Cours:TPS 2103 tp3
Vous allez développer un système de digicode architecturé autour d'un atmega328p (le µcontrôleur présent sur les cartes arduino).
Pour ce TP, nous utilisons une carte arduino sans le shieldinfo
Sommaire
Matériel
Nous utiliserons :
- 1 carte arduino UNO
- 1 plaque à essais
- 2 leds Rouge
- 2 leds verte
- 4 résistances 330Ω
- 1 clavier matriciel
- 1 buzzer (à insérer directement sur les connecteurs arduino)
- 5 fils M-M
- 7 fils M-F
Informations lumineuses
Le digicode sera équipé de 2 voyants lumineux (rouge et vert).
On utilisera des résistances de 330Ω, et vous êtes libre de choisir un montage à anodes ou cathodes communes.
Câbler sur une plaque à essais les leds sur les pin PC0 (Rouge) et PC1 (Verte)
Vérifier le fonctionnement des leds :
#include <avr/io.h>
#include <util/delay.h>
int main()
{
// config des sorties
while(1)
{
//allumer R + attendre
//allumer V + attendre
//eteindre V + attendre
//eteindre R + attendre
}
}
int main()
{
DDRB |= 1 << PB5;
while(1)
{
PORTB |= 1 << PB5;
_delay_ms(100);
PORTB &= ~(1 << PB5);
_delay_ms(100);
}
}
|
Decodage d'un clavier
Câblage
Le tableau suivant résume la disposition physique du clavier avec la position physique sur le connecteur des lignes (L1 à L4) et colonnes (C1 à C3) en vue de dessus :
|
|
Câbler sur une plaque à essais le clavier 12 touches que l'on vous donne. Les colonnes seront reliées sur le port D et les lignes sur le port B (cf indications ci dessus)
Remarque : On ne câblera aucune résistance de tirage, on utilisera les résistances internes au µcontrôleur.
|
Principe de décodage
En utilisant un clavier matriciel, chaque touche n'est pas associé à une broche du µcontrôleur. Dans le cas présent, on passe de :
- 12 entrées nécessaires si chaque touche était connectée directement
- 7 broches nécessaires avec le clavier matriciel
L'intérêt évident est donc une réduction du nombre de broches nécessaires à l'utilisation du clavier.
L'inconvénient qui en résulte est la complexité relative du code pour trouver quelle touche est appuyée.
Le principe de décodage est symétrique entre lignes et colonnes. Détaillons donc le fonctionnement pour trouver sur quelle ligne une touche est appuyée :
- On configure les broches colonnes en sortie.
- On configure ces sorties à l'état 0
- Les broches lignes sont en entrée
- l'état des lignes dépend de l'appui sur un bouton :
- si aucun bouton appuyé, les résistances de tirage donnent un état 1 sur les lignes
- si on appui sur un bouton de la ligne1 (key 1/2/3), alors l'entrée ligne PB0 passe à l'état 0.
- la valeur change suivant la ligne sur laquelle un bouton est appuyé
- il suffit donc d'observer les 4 bits PB3..PB0 (que l'on note ici etat), et ainsi :
- si etat = 1111 , pas de touche
- si etat = 1110 , au moins une touche parmi 1/2/3
- si etat = 1101 , au moins une touche parmi 4/5/6
- ...
Indice de ligne
Ecrire et tester le programme lecture_ligne() qui renvoie le numéro de ligne sur laquelle un bouton est appuyé
- La validation se fera en utilisant des leds connectées sur le port C :
- On mettra 4 leds sur les broches PC3 à PC0
- On visualisera un nombre n sur 4 bits en écrivant PORTC = n;
int8_t lecture_ligne()
{
int8_t ch;
DDRD ?= .... ; // commençons par lister les sorties sur le port D
DDRB ?= .... ; // puis les entrées sur le port B
PORTD?=..... ; // on place les sortie à l'état 0
PORTB?= .... ; // on active les résistances de pull-up sur les entrées
_delay_ms(1); // un délais est nécessaire pour l'activation des pull-ups
ch = PINB & ??; // on récupère ensuite l'état des entrées
switch (ch)
{
case : return 0; // aucune touche
case : return 1; // L1
case : return 2; // L2
case : return 3; // L3
case : return 4; // L4
// si autre cas, deux touches ou autre
default : return -1;
}
}
Indice de colonne
De la même façon, écrire et tester la fonction lecture_colonne() qui permettra d'obtenir le numéro de colonne sur laquelle un bouton est appuyé.
Touche appuyée
Nous souhaitons maintenant écrire une fonction qui renverra une valeur tel que décrit ci dessous :
int8_t touches[4][3] = { // tableau de char à 2 dimensions
{1,,},
{...},
{...},
{,,11}
};
int8_t getTouche();
|
La valeur retournée sera :
|
Écrire cette fonction en vous servant bien évidemment des 2 fonctions précédentes et pourquoi pas du tableau "touches" complété.
int8_t getTouche()
{
....
}
Assemblons le tout
Nous allons utiliser la fonction getTouche() pour réaliser un programme de digicode.
Cahier des charges
Commençons pour définir les contraintes :
- On appuie sur la touche '*' pour démarrer la saisie du code => la led rouge s'allume
- L'utilisateur doit alors saisir le code sur 4 chiffres
- On valide le code par la touche '#'
- Si le code est bon la led verte s'allume pendant 10s, sinon la led rouge clignote pendant 10s