S`ouvrir au monde

Transcription

S`ouvrir au monde
S'ouvrir au monde
Extrait du PoBot
http://www.pobot.org
S'ouvrir au monde
- Programmation - Apprendre - Les micro-contrôleurs - Les micro-contrôleurs sans ta mère -
Date de mise en ligne : dimanche 27 novembre 2005
PoBot
Copyright © PoBot
Page 1/9
S'ouvrir au monde
Sommaire
• La solution du jour
• ATMega8 et communications (...)
• Communications série et (...)
• Max à la rescousse
• Le schéma complet
• Le montage
• L'application
• Le programme
• L'initialisation de l'USART
• Réception de données
• Transmission de caractères
• Quelques remarques
• Conclusion
• Liste des composants
Après avoir fait clignoter les LEDs à s'en faire péter les rétines, il est maintenant temps de franchir un échelon. C'est
bien de faire réaliser des actions avec notre micro-contrôleur, mais c'est encore mieux s'il était possible de le piloter
de l'extérieur, de lui faire envoyer des infos,... En 3 mots : communiquer avec l'extérieur.
La solution du jour
Il existe plusieurs moyens pour faire communiquer l'ATmega8 avec l'extérieur (un PC par exemple) :
•
•
•
le SPI : on s'en sert déjà pour le programmer depuis le PC
l'I2C, dénommé TWI pour Two Wires Interface
la liaison série
Le SPI étant occupé (ce qui n'empêcherait de l'utiliser quand même, mais c'est plus complexe), nous allons l'écarter
pour l'instant. Faire de l'I2C avec un PC est possible, mais il faudrait développer un petit programme pour cela. On
verra cela plus tard. Reste donc pour aujourd'hui notre bonne vieille interface série, que nous allons pouvoir tester
côté PC avec l'aide d'Hyperterminal ou de tout autre émulateur de terminal de votre choix.
ATMega8 et communications série
L'ATmega8 dispose de manière interne d'un circuit dénommé USART pour Universal Synchronous and
Asynchronous serial Receiver and Transmitter. A noter qu'on entend couramment parler d'UART, mais qu'ATMEL
a ajouté ici un S pour Synchronous. Ce qui veut dire que cette interface peut servir à faire aussi bien de la
communication série asynchrone courante, c'est à dire avec les bits de start et de stop, mais aussi synchrone dans
laquelle les bits de données sont envoyés de manière cadencée par un signal de clock, piloté par un maître de
cérémonie. Mais ce sera aussi pour une autre fois, car le PC ne sait pas faire cela de manière simple.
Pour tout savoir sur l'USART, ses fonctionnalités, sa mise en oeuvre,... rendez-vous à la page 130 du datasheet.
Copyright © PoBot
Page 2/9
S'ouvrir au monde
Communications série et RS232
Il s'agit là de deux choses différentes, mais que l'on a tendance à amalgamer dans le monde des PC.
Communication série désigne un mode de transmission dans lequel on envoie les bits des données en séquence
(en série) sur un même fil, par opposition à communication parallèle où les différents bits sont envoyés en même
temps sur des lignes parallèles (d'où le nom).
RS232 désigne une norme électrique pour les communications série, qui spécifie les tensions représentant les états
logiques sur les fils véhiculant les signaux et données. En simplifié, sur une ligne RS232, les tensions sont de -12V et
+12V. La raison est tout simplement d'avoir des tensions suffisamment différentiables pour être capables de distinguer
les états logiques même en cas d'affaiblissement ou de dégradation des signaux électriques (sur une liaison de
grande longueur par exemple).
Oui, et alors ?
Et bien, le problème c'est qu'un micro-contrôleur, comme la plupart des puces logiques TTL, ne connait que 0 et 5V
pour ce qui est des signaux qu'il gère. Ce qui veut dire que les signaux présents sur les pins RxD et TxD ne prendront
que ces deux valeurs. Conclusion : ce n'est pas du RS232, et ça ne pourra pas causer avec un PC via sa prise COM1
par exemple.
Max à la rescousse
Non, ce n'est pas un pote costaud. Juste un petit boitier fait par la société MAXIM (entre autres) et qui permet
d'assurer la conversion des signaux entre le monde RS232 et le monde TTL. plusieurs modèles existent dans la
gamme, avec des fonctionnalités diverses, et celui qui va nous servir ici les le MAX232. Je ne vais pas le détailler ici,
car il suffit de parcourir son datasheet [/IMG/pdf/MAX220-MAX249.pdf] pour tout comprendre, et voir comment il se
met en oeuvre.
Le schéma complet
Et bien le voici.
Copyright © PoBot
Page 3/9
S'ouvrir au monde
Schéma électronique
On y retrouve plus ou moins le même schéma que celui de l'article précédent. Nous avons cependant été obligés de
déplacer deux des LEDs sur un autre port, car les lignes Rx et Tx sont sur les mêmes pins que les bits 0 et 1 du port
D. Les deux LEDs correspondantes sont maintenant connectées aux bits 0 et 1 du port C.
La nouveauté réside dans la présence du MAX232 et sa connexion à l'ATmega. Comme vous pouvez le constater, il
n'y a pas de quoi s'affoler.
Le montage
Après quelques transformations de notre montage précédent, on arrive à ce résultat :
Le montage expérimental
On y retrouve en partie droite l'ATmega8 avec la liaison avec les LEDs ainsi qu'avec le câble ISP (la nappe
multicolore du dessus).
En partie gauche, on y voit le MAX232 flanqué des ses 5 capas, l'arrivée des lignes RS232 en provenance du PC en
bas à gauche, et la liaison des lignes série TTL avec l'ATmega8 réalisée par les straps agencés en Z.
Une remarque au passage : j'ai réalisé que le fabriquant du set de straps avait eu la bonne idée d'utiliser les codes de
couleurs des résistances pour indiquer la longueur des straps, exprimé en nombre de pas 2,54mm. Hyper pratique
quand on utilise une plaquette d'expérimentation. Je sais, il y en a qui vont me dire : "et tu ne l'avais pas compris
avant ?". Ben non, mais à ma décharge, jusqu'à présent j'utilisais des fils de récup pour ce genre de travaux, mais j'ai
décidé d'utiliser des straps pour ces articles, afin de faire plus propre pour le bien-être du lecteur.
Copyright © PoBot
Page 4/9
S'ouvrir au monde
L'application
Cette application fait toujours défiler les LEDs, mais nous permet de le contrôler au moyen de caractères de
commande envoyés par un PC sur un de ses port COM. Les commandes disponibles sont :
espace
suspend/redémarre le défilement
*
enchaîne automatiquement les differentes séquences, et reboucle sur la première en fin de liste. C'est le mode de fonctionnement lors de la mise sous tension
+
passe à la séquence suivante de celle en cours, et boucle sur elle-même
-
fait la même chose, mais en passant à la séquence précédente
En plus de cela, le programme affiche un message de bienvenue et la liste des commandes au démarrage, et rend
compte de l'exécution de chacune d'entre elles.
Un exemple de session Hyperterminal est illustrée ci-dessous :
Un exemple de session
Pour ceux qui se demandent pourquoi les messages sont en Anglais : non, je n'ai pas pompé ces programmes sur le
Net, mais c'est juste parce que mes activités professionnelles me conduisent à travailler sur des projets
internationaux. Du coup je ne fais plus gaffe, et rédige mes programmes en Anglais par habitude...
Le programme
Voici le source complet et le Makefile pour avr_gcc.
Copyright © PoBot
Page 5/9
S'ouvrir au monde
Source de l'application
Makefile
Comme pour le cadencement du défilement des LEDs vu précédemment, deux stratégies existent :
•
le polling, ou scrutation active, consistant dans le cas de la réception par exemple, à boucler (à vide) tant que le
bit indicateur de la réception d'un caractère (RXC) du registre UCSRA reste à 0
• les interruptions, qui signalent de manière totalement asynchrone les différents événements de la
communication (réception d'un octet, buffer de transmission vide, transmission effectuée,...)
Puisque nous sommes déjà au niveau Anakin Adolescent, nous allons directement nous intéresser à la deuxième
approche. Des exemples de sources concernant la première sont disponibles dans le datasheet, page 140 par
exemple.
L'initialisation de l'USART
Avant de pouvoir l'utiliser, il est nécessaire d'initialiser l'USART, notamment pour définir vitesse et format de
communication.
La vitesse se définit dans le registre UBRR, qui se compose des deux registres UBRRH et UBRRL (pour High et Low).
la valeur à y placer dépend de la vitesse souhaitée bien entendu, mais aussi de la fréquence du quartz utilisé. Divers
tableaux en page 156 du datasheet détaillent tout cela. Faites bien attention à ce propos de n'utiliser que les valeurs
pour lesquelles l'erreur de vitesse est inférieure à 0.8 (les valeurs correspondantes sont en gras dans les tableaux).
A noter que l'accès au registre UBRRH est un peu spécial, car son adresse est partagée avec le registre UCSRC.
Pour indiquer dans lequel des deux on écrit, il faut position er le bit 7 (commun aux deux) selon (0 pour accéder à
UBRRH, 1 pour UCSRC).
L'activation des interruptions USART est contrôlée par le registre UCSRB (USART Control and Status Register B), au
moyen des bits RXCIE, TXCIE et UDRIE (voir page 152 du datasheet).
Pour activer la réception, il faut positionner le bit RXEN (Receive Enabled) du registre de contrôle UCSRB. A partir de
ce moment, le bit PD0 du port D n'est plus accessible en tant qu'I/O. Puisqu'on veut recevoir une interruption lorsqu'un
caractère a été reçue, il faut aussi positionner le bit RXCIE (Receive Complete Interrupt Enabled) de ce même
registre.
La partie transmission de l'USART est activée en positionnant le bit TREN (Transmit Enabled) du registre de contrôle
UCSRB. A partir de ce moment, le bit PD1 du port D n'est plus accessible en tant qu'I/O. Nous allons également
utiliser l'interruption UDRE (USART Data Register Empty), en positionnant le bit UDRIE du registre UCSRB.
Copyright © PoBot
Page 6/9
S'ouvrir au monde
C'est à peu près tout. Il faut savoir maintenant que les données reçues ou à envoyer transitent par le registre UDR
(USART Data Register).
Mais, allez-vous dire, si on veut envoyer un caractère et qu'un autre arrive pendant ce temps, on va perdre la donnée
à transmettre. Et bien non. Car même si ce registre de donnée apparait à une seule adresse, il correspond en réalité à
deux registres internes distincts pour la réception et la transmission. Les gars d'ATMEL sont tout sauf des idiots :-)
Réception de données
Lorsqu'un caractère est complètement reçu par l'USART, celui-ci le transfère dans le registre UDR (USART Data
register), positionne le bit RXC du registre UCSRA (USART Control and Status Register A) et lève l'interruption
Receive Complete Interrupt.
Il nous suffit d'écrire un handler pour cette interruption afin de traiter le caractère dès qu'il est disponible. A noter que
traiter le caractère ne veut pas dire traiter la commande. En effet, le code s'exécutant dans un handler d'interruption
doit être le plus court possible, étant donné qu'on a plus ou moins tout arrêté ailleurs pour l'exécuter. Nous nous
contenterons donc d'ajouter ce caractère dans une file d'attente dans laquelle l'application ira puiser pour traiter les
commandes correspondantes.
Plutôt que de tartiner des pages ici, je vous invite à analyser le code et les commentaires du source (histoire que je ne
me sois pas em..dé à le faire pour rien ;-). Vous noterez qu'après les initialisations, le main de l'application se contente
de boucler sur deux actions :
•
•
attendre que des caractères soit présents dans la file d'attente de réception
exécuter la commande correspondante
Transmission de caractères
Le procédé est assez similaire à la réception. Une petite différence cependant au niveau de la philosophie de
l'interruption UDRE, qui est levée dès que le registre de données est vide, et tant qu'il est vide (et non pas lorsque
son état change).
A la différence de la réception, nous n'allons donc activer cette interruption que lorsqu'on place le premier caractère à
transmettre dans la file d'attente, et la désactiver dès qu'il n'y aura plus rien en attente. Cette interruption fait donc
office de pompe à données.
La file d'attente de transmission est gérée de la même manière que celle de réception. Pour envoyer des caractères
depuis le corps de l'application, il suffira de les y ajouter, en activant l'interruption pour le premier de la file.
Quelques remarques
Sections critiques
Copyright © PoBot
Page 7/9
S'ouvrir au monde
Vous remarquerez en lisant le source, que les instructions d'ajout ou de retrait de données dans ou depuis les files
d'attente sont encadrées par des instruction CLI et SEI, qui respectivement masquent et autorisent les interruptions.
Pourquoi cela ? Tout simplement pour implémenter une section critique, qui ne doit être interrompue sous aucun
prétexte. Sans cette précaution, la file concernée pourrait être laissée dans un état incohérent si au milieu du retrait
d'un caractère par exemple, un autre arrive, provoquant l'exécution du code de l'interrupt handler du receive, et donc
modifiant les informations d'état de la file. En masquant les interruptions, cet événement est mémorisé puis notifié dès
que le SEI sera exécuté. Inutile de dire que ces sections critiques doivent être les plus courtes possibles.
volatile
Un certain nombre de variables sont déclarées avec l'attribut volatile. Qu'est-ce que cela signifie ?
Rien en rapport avec la grippe aviaire en tout cas !! C'est une indication au compilateur de ne pas chercher à optimiser
l'assembleur généré en cachant la valeur dans un registre de travail, car cette valeur peut changer à tout moment.
Chaque accès à la variable doit donc relire la valeur depuis la mémoire.
Pourquoi demander cela ? Tout simplement parce que les variables concernées sont partagées entre du code normal
et du code d'interrupt handler, et qu'elles sont de surcroit modifiées dans ces handlers. Etant donné le côté hautement
asynchrone des interruptions, cela veut dire que ces variables peuvent changer de valeur à tout moment. Donc, il faut
systématiquement les relire.
Soyez bien attentifs à ce genre de détail : on a vu des robots faire n'importe quoi pour une variable qui aurait dû être
déclarée volatile et qui ne l'a pas été. Et bonjour pour détecter la cause du problème quand on n'a pas l'habitude...
Conclusion
A noter que l'USART permet de faire des choses encore plus sophistiquées, comme par exemple de communiquer
entre plusieurs ATmega en mode maître/esclave. Tous sont connectés en parallèle sur la mème ligne série, un peu
comme sur un bus. Un mécanisme d'adressage est alors disponible pour que le maître désigne le destinataire des
données. Attention cependant, il ne s'agit pas d'un bus à part entière, car on ne peut pas librement changer les rôles
en cours de session. Pour en savoir plus, consultez la section Multi-processor Communication Mode page 148 du
datasheet.
Liste des composants
Les mêmes que pour le montage précédent, plus ceux-ci :
- Etiquette - Valeur -
Copyright © PoBot
C7
1µF polarisée
C8
1µF polarisée
C9
1µF polarisée
Page 8/9
S'ouvrir au monde
C10
1µF polarisée
C11
1µF polarisée
IC2
MAX232
Les capas polarisés utilisées ici sont des tantales : c'est plus petit. Ca doit marcher également avec des
électrochimiques (qui seront peut-être moins chers).
Si votre MAX232 porte le suffixe "A" (MAX232A), les capas C7 à C11 peuvent (doivent ?) être remplacées par des
100nF polarisées également.
Post-scriptum :
Suite à une question qui m'a été posée, voici quelques compléments concernant la connexion physique au PC. Plusieurs solutions existent comme
toujours : on peut faire un câble équipé d'une prise DB9 femelle pour se brancher directement sur le PC.
Personnellement je préfère une autre approche, qui parait plus complexe, mais qui s'avère beaucoup plus versatile (à mon sens) :
équiper mon montage d'une prise DB9 mâle, câblée à l'identique de celle du PC. Dans le cas de nos montages d'expérimentation, on équipera
la DB9 mâle de fils d'une dizaine de centimètres environ, préparés à l'autre extrémité de manière à pouvoir s'enficher facilement dans les contacts
de la plaquette.
réaliser un câble dit "croisé" ou "null modem", reliant les deux. Ce câble est équipé de 2 prises DB9 femelles, et fait office de canal de
communication entre 2 ordinateurs au sens large en connectant le signal transmit de l'un sur l'entrée receive de l'autre et vice-versa.
Reste à savoir quelles sont les broches à utiliser. Sur une prise DB9 mâle, nous allons nous intéresser aux signaux suivants :
receive, sur la broche 2
transmit, sur la broche 3
masse, sur la broche 5 On peut ignorer le reste, car soit ce n'est pas connecté, soit cela correspond aux signaux de handshake hardware, qui
sont rarement utilisés (en tout cas pas par les µcontrôleurs.
Pour ce qui est du câble croisé, c'est simple : on connecte entre elles les broches 5, et on relie la broche 2 de l'une à la broche 3 de l'autre et Lycée
de Versailles.
Et comment on sait quelle est la broche n sur la prise ? Très simple : on prend une loupe et on cherche le numéro. Il est souvent gravé côté
soudures, ou parfois côté broches. Ca dépend du fabricant.
Autre solution : Google étant ton ami comme toujours, taper "RS232 DB9 pinout", et servez-vous. Cette page-là est par exemple très claire et
complète :
http://www.zytrax.com/tech/layer_1/cables/tech_rs232.htm
Et en plus, c'est la première.
Copyright © PoBot
Page 9/9

Documents pareils