La programmation des ATMEL AVR

Transcription

La programmation des ATMEL AVR
La programmation des ATMEL AVR
JUILLOT Guillaume
2 septembre 2003
Table des matières
Introduction
I
Les
I.1
I.2
I.3
I.4
I.5
I.6
I.7
I.8
I.9
3
microcontrôleurs AVR pour les nuls
Qu’est-ce qu’un microcontrôleur ? . . . .
Les entrées/sorties d’un microcontrôleur
Timers/Counters et génération de PWM
Convertisseurs analogique/numérique . .
Communication série USART . . . . . .
Comparateur analogique . . . . . . . . .
Watchdog Timer . . . . . . . . . . . . .
Modes d’économie d’énergie . . . . . . .
Interruptions internes et externes . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
5
5
6
7
7
8
8
8
9
II La programmation des microcontrôleurs en C
II.1 Débuter avec Imagecraft . . . . . . . . . . . . . . . . . . . . . .
II.2 La séparation de code en plusieurs fichiers et quelques fonctions
II.2.1 La définition de fonctions utiles à l’aide de #define . . .
II.2.2 Rajouter un fichier à un projet . . . . . . . . . . . . . .
II.3 Les interruptions avec ImageCraft AVR . . . . . . . . . . . . .
II.4 L’assembleur dans un programme en C . . . . . . . . . . . . . .
II.5 Quelques compléments sur le compilateur ICC AVR . . . . . .
. . . .
utiles
. . . .
. . . .
. . . .
. . . .
. . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
11
11
13
14
14
15
16
16
III La simulation des progammes
III.1 Premiers pas avec AVR Studio 4
III.2 Workspace . . . . . . . . . . . . .
III.3 Programme en cours . . . . . . .
III.4 Contrôle du déroulement . . . . .
III.5 Choix de la vue . . . . . . . . . .
III.6 Output view . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
19
19
20
21
21
22
22
IV L’implémentation réelle sur le microcontrôleur
IV.1 L’alimentation . . . . . . . . . . . . . . . . . . . . . . . . . . . .
IV.2 L’horloge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
IV.3 Le port de programmation . . . . . . . . . . . . . . . . . . . . . .
IV.4 Comment implémenter notre programme dans le microcontrôleur
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
23
23
23
24
26
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Le mot de la fin
29
A Schéma de l’ATmega128
31
B Conversion hexadécimal/binaire/décimal
B.0.1 Convention d’écriture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33
33
1
2
TABLE DES MATIÈRES
C Aide à la programmation
C.1 Type de données . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
C.2 Gestion des entrées/sorties . . . . . . . . . . . . . . . . . . . . . . . . . . .
C.3 Interruptions externes . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
C.4 Timer/Counter0 (8 bits) . . . . . . . . . . . . . . . . . . . . . . . . . . . .
C.5 Timer/Counter2 (8 bits) . . . . . . . . . . . . . . . . . . . . . . . . . . . .
C.6 Timer/Counter1 et 3 (16 bits) . . . . . . . . . . . . . . . . . . . . . . . . .
C.7 Interruptions pour Timers/Counters . . . . . . . . . . . . . . . . . . . . .
C.8 Génération de PWM sur OC0 (8 bits) . . . . . . . . . . . . . . . . . . . .
C.9 Génération de PWM sur OC2 (8 bits) . . . . . . . . . . . . . . . . . . . .
C.10 PWM sur OC1A, OC1B, OC1C, OC3A, OC3B et OC3C (de 8 à 10 bits)
C.11 USART . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
35
35
35
35
36
36
37
37
37
38
38
39
Adresses Internet utiles
41
Index
43
Introduction
Ce document a été écrit dans le cadre de la coupe 2003 de robotique e=M6. Il a pour but
de vous présenter toutes les phases de développement d’un projet sur les microcontrôleurs de la
famille AVR de chez ATMEL.
Cette présentation est décomposée en quatre parties. La première sera une description aussi
complète que possible des possibilités qu’offrent les microcontrôleurs choisis. Suivront les rudiments de la programmation en C et en assembleur, à l’aide du compilateur Imagecraft. Un aspect
important est la simulation du programme, qui se fera à l’aide de AVR Studio 4 dans la troisième
partie du présent document. Je terminerai en présentant la mise en pratique du programme en
l’implémentant sur le microcontrôleur.
Les exemples donnés seront valables pour un ATmega128. Il est possible qu’ils ne soient plus
valables pour un autre microcontrôleur. Dans tous les cas il est vivement recommandé
d’avoir une datasheet complète de l’ATmega128 sous les yeux pour mieux pouvoir
suivre les exemples. Utilisez également la datasheet d’un autre microcontrôleur si vous souhaitez
adapté les exemples au microcontrôleur de votre choix.
3
4
INTRODUCTION
Chapitre I
Les microcontrôleurs AVR pour
les nuls
Les microcontrôleurs de la famille AVR d’ATMEL possèdent de nombreuses caractéristiques
différentes, aussi bien en termes de vitesse, mémoire, nombre d’entrés/sorties mais aussi au niveau
des fonctions particulières qui sont disponibles. Il conviendra donc de choisir le microcontrôleur
en fonction de l’utilisation qui est à faire - par exemple, il est conseillé d’éviter d’utiliser un
ATmega128 si l’on ne cherche qu’à générer un PWM1 .
I.1
Qu’est-ce qu’un microcontrôleur ?
Un microcontrôleur est composé d’un microprocesseur, de mémoire ROM pour stocker le
programme et d’une mémoire RAM volatile pour conserver les résultats intermédiaires lors de
l’exécution du programme.
Mais les microcontrôleurs possèdent des avantages incomparables pour l’informatique embarquée par rapport aux microprocesseurs. Ce sont d’abord les broches qui peuvent servirent
d’entrées/sorties mais surtout toutes les fonctions périphériques. En effet, selon le microcontrôleur
considéré, on peut trouver :
– plusieurs Timers/Counters
– Génération de signaux PWM
– Nombreux convertisseurs analogiques/numériques
– Communication série USART
– Comparateur analogique
– Watchdog Timer
– Oscillateur RC interne
– Modes d’économies d’énergie
– Interruptions internes et externes
I.2
Les entrées/sorties d’un microcontrôleur
La plupart des pattes d’un microcontrôleur peuvent servir soit d’entrées, soit de sorties, et ce
choix peut changer à tout instant comme le veut le développeur.
Les entrées/sorties sont regroupées par huit et le groupement de huit pattes ainsi formé est
appelé port et se voit attribué une lettre. Par exemple, les broches 44 à 51 forment le port A.
1 PWM = Pulse Width Modulation, c’est un signal rectangulaire caractérisé par le rapport cyclique
(tempshaut /tempsbas ), c’est-à-dire avec un temps à 1 différent du temps à 0.
5
6
CHAPITRE I. LES MICROCONTRÔLEURS AVR POUR LES NULS
Chaque patte est ensuite numérotée selon sa position au sein de ce port. Par exemple, la broche
46 est appelée PA52 . Trois registres3 servent à gérer les entrées/sorties :
– DDRx4 : indique quelles sont les pattes considérées comme des entrées et celles considérées
comme des sorties. Si le nième bit de DDRx (noté DDxn) est à 1, alors la nième patte du
port x (notée Pxn) est considéré comme une sortie. Si DDxn est à 0, alors Pxn est considérée
comme une entrée.
– PORTx : la valeur du nième bit de PORTx (noté PORTxn) définit la valeur de sortie de
Pxn. Si PORTxn=1, alors Pxn=+Vcc, si PORTxn=0, alors Pxn=Gnd.
– PINx : la valeur du nième bit de PINx (noté PINxn) est la valeur qui est appliquée à l’entrée
du microcontrôleur. Par exemple, si on applique +Vcc à Pxn, alors PINxn=1.
La plupart des pattes possèdent des fonctions périphériques qui inhibent l’utilisation en tant
qu’entrées/sorties. Si l’on utilise les fonctions périphériques, il ne faut en aucun cas modifier les
bits DDRxn, PORTxn et PINxn correspondants.
I.3
Timers/Counters et génération de PWM
Les Timers/Counters, notés TCNTn où n est le numéro Timer/Counter, sont des compteurs
cadencés selon une certaine fréquence définie. Lorsqu’il atteint son maximum (MAX5 ), il passe à 0
et recommence à compter. Ce passage de MAX à 0 peut s’accompagner d’une interruption interne
(cf. Interruptions internes et externes en page 9).
À ces Timers/Counters se rajoutent un comparateur dont on peut définir le seuil à l’aide du
registre OCRn. Lorsque le TCNTn atteint la valeur de OCRn, alors la patte OCn change de valeur, passant de 0 à 1 ou de 1 à 0 selon la configuration puis retournant à la valeur initiale lorsque
TCNTn passe de MAX à 0.
Ces Timers/Counters peuvent donc avoir plusieurs utilisations. D’abord, le programmeur peut
savoir le temps écoulé depuis qu’il a lancé le Timer/Counter. Ou encore, l’interruption de passage
de MAX à 0 peut être utilisée pour temporisation, et commencer ou arrêter un programme au
bout d’un certain temps. La dernière utilisation, très utile en robotique pour la commande de servomoteurs, est la génération de signaux PWM. En effet, si la patte OCn change de valeur lorsque
le TCNTn atteint la valeur du comparateur OCRn, on obtient sur OCn un signal alternativement
à 1 puis à 0 avec des durée à 0 et à 1 réglables. On a bien OCn qui est un signal PWM dont on
peut définir le rapport cyclique en mettant la bonne valeur dans OCRn.
Plusieurs registres sont utilisés pour configurer les Timers/Counters :
TCCRn, OCRn, ASSR, TIMSK et TIFR. Leurs configurations sont compliquées, il convient de
se reporter aux chapitres correspondants de la datasheet. La valeur du Timer/Counter, accessible
via le registre TCNTn, peut être modifiée à tout instant afin de réinitialiser ma séquence à partir
d’une certaine valeur, après avoir atteint MAX, le compteur recommencera à 0. À noter que la
fréquence de comptage peut être un sous-multiple de la fréquence du microcontrôleur ou encore
être imposée par une horloge externe connectée à une patte du microcontrôleur.
Certains compteurs fonctionnent sur 16 bits. Ils présentent plusieurs avantages : ils peuvent
compter plus loin donc plus longtemps ; lors d’une utilisation pour générer du PWM, la résolution
est plus élevée ; et surtout ils possèdent deux comparateurs dont les seuils peuvent être réglés
différement, ce qui permet d’obtenir sur les pattes OCnA et OCnB deux signaux PWM de
même fréquence mais de rapport cyclique différent à l’aide d’un seul Timer/Counter. Dans le
2 Les plus perspicaces auront remarqué que l’ordre des numéros sur le port A est inversé par rapport aux numéros
des pattes. En réalité, cela dépend du port, certains sont dans le bon sens, d’autres non. Voir dans la datasheet.
3 Un registre est une variable interne de huit bits, utilisée pour définir le comportement du microcontrôleur ou
pour savoir dans quel état il se trouve.
4 x représente la lettre du port, par exemple DDRA ou DDRB ...
5 pour un compteur sur m bits, alors MAX = 2m − 1
I.4. CONVERTISSEURS ANALOGIQUE/NUMÉRIQUE
7
cas de Timer/Counter sur 16 bits, le registre TCNTn se décompose en deux registres TCNTnL et
TCNTnH tandis que OCRn se décompose en OCRnAL et OCRnAH pour le premier comparateur
et OCRnBL, OCRnBH pour le deuxième comparateur.
I.4
Convertisseurs analogique/numérique
Le monde réel étant continu, c’est-à-dire analogique, tandis que les microcontrôleurs fonctionnent en numérique, il faut bien avoir une interface entre les deux : le convertisseur analogique/numérique6 . Son fonctionnement est simple à comprendre : à intervalles de temps réguliers,
la tension analogique est mesurée puis arrondie afin de pouvoir être convertie en numérique. La
conversion est donc d’autant plus fidèle que le nombre de bits du codage est élevé et est inversement
proportionnelle à la plage de tension analogique en entrée. Les microcontrôleurs de la famille AVR
possèdent des convertisseurs embarqués donc il n’est pas nécessaire d’en concevoir ou d’en acheter.
Par exemple, l’ATmega128 possède un CAN fonctionnant sur 10 bits. Ce CAN peut convertir
jusqu’à 8 signaux analogiques par intermittence. Le temps maximum de conversion est de 260µs
mais peut être diminué en réduisant la résolution (nombre de bits du codage). L’échelle de tension
en entrée est par défaut [0, V cc] mais peut être passée à [0, Vref ] où Vref ≤ V cc est une tension
appliquée à la patte Aref (no 62). A noter que les CAN peuvent être configurés pour ne faire
qu’une conversion ou pour convertir en continu la tension analogique, la conversion étant alors
réguilèrement mise à jour selon la durée de conversion.
I.5
Communication série USART
USART est l’abrévation pour Universal Synchronous and Asynchronous serial Receiver and
Transmitter, c’est un système de communication point-à-point très flexible.
Les données sont transmises par trames de 7 à 13 bits. La trame a le format suivant :
D
D
D
D
D
D
D
D
D
D
D
(IDLE) D St 0 D 1 D 2 D 3 D 4 D [5] D [6] D [7] D [8] D [P] Sp1 [Sp2] D (St/IDLE)
D
D
D
D
D
D
D
D
D
D
D
St : bit de départ, toujours à 0
n : bits de données
P : bit de parité
Sp : bit(s) de fin, toujours à 1
IDLE : pas de transfert, la ligne doit être à 1
Fig. I.1 – Trame USART
Les éléments entre crochets sont facultatifs, leur présence est définie par le développeur. Le bit
de parité permet de vérifier rapidement s’il y a eu une erreur de transmission mais n’est pas fiable
à 100%.
L’USART se décompose en trois parties :
L’émetteur : se charge d’émettre sur la patte TXDn, à la fréquence configurée, la trame selon la
valeur stockée dans le registre UDR ; il s’occupe donc automatiquement de la génération des
bits Start, Stop et éventuellement Parity. Des interruptions peuvent être déclenchées lorsque
la transmission est terminée.
6 en
abrégé, CAN ou ADC en anglais pour Analog to Digital Converter
8
CHAPITRE I. LES MICROCONTRÔLEURS AVR POUR LES NULS
Le récepteur : dès détection sur la patte RXDn d’un bit Start valide (c’est-à-dire à 0), chaque
bit de la trame est alors échantilloné selon la fréquence configurée ou selon l’horloge sur XCK,
et stocké dans un registre temporaire jusqu’à réception de la trame complète. Ensuite, la
valeur reçue est déplacée dans le registre UDR accessible par le programme. Une interruption
peut être déclenchée lors de la fin de réception pour prévenir qu’une trame est arrivée. Si le
programme n’a pas lu une trame lorsqu’une deuxième trame arrive, la première trame est
perdue. Si la transmission s’est mal déroulée, par exemple si la trame est non conforme, si le
bit de parité n’est pas correct ou si des données reçues n’ont pas été lues, divers drapeaux7
passent à 1 et les données erronées sont effacées.
Le générateur d’horloge : lors d’une utilisation en mode synchrone, un générateur est déclaré
maı̂tre et l’autre esclave. Le maı̂tre génère le signal d’horloge selon le débit souhaité et l’envoit sur la patte XCK du microcontrôleur. L’horloge esclave reçoit ce signal d’horloge sur
sa patte XCK et l’utilise pour échantilloner les trames ou les émettre au bon rythme. En
mode asynchrone, l’USART en reception se charge de synchroniser son horloge sur la trame
arrivante.
La configuration doit être faite avant toute tentative d’envoi de données et ne devra pas être
changée tant que des données restent à émettre/recevoir. Il faut bien veiller à ce que la configuration
soit toujours identique sur les deux microcontrôleurs pour le format de la trame, le débit et qu’en
mode synchrone les deux pattes SCK soient reliées et qu’un USART soit en maı̂tre et l’autre en
esclave.
I.6
Comparateur analogique
Outre les convertisseurs analogiques/numériques, les microcontrôleurs AVR possèdent un comparateur analogique. Celui-ci compare les deux tensions appliquées aux pattes AIN0 et AIN1. Si
AIN 0 < AIN 1 alors le bit ACO (5ème bit du registre ACSR) passe à 1. Sinon, ACO reste à 0.
De plus, une interruption peut être déclenchée lors du passage à 1 de ACO.
I.7
Watchdog Timer
Le Watchdog Timer se charge de faire des RESET à intervalle de temps régulier. Il utilise un
oscillateur RC interne en tant qu’horloge cadencée à 1MHz. Ce système permet de recommencer le
même programme à intervalles de temps réguliers ou encore de se réveiller d’un mode d’économie
d’énergie après un certain lapse de temps (voir paragraphe suivant). A noter que la mémoire RAM
n’est pas perdu au cours de ce RESET, ce qui permet d’augmenter le temps entre deux réexécution
du programme en tenant à jour un compteur qui est décrémenté à chaque Watchdog Reset jusqu’à
ce qu’il atteigne 0 et alors on commence réellement le programme.
I.8
Modes d’économie d’énergie
Certaines applications ne nécessitent pas que le microcontrôleur tourne continuellement. Il
serait donc souhaitable de le désactiver, de ”l’endormir”, pour qu’il consomme aussi peu d’énergie
que possible. Ceci est possible grâce aux Sleep Mode. Plusieurs modes sont disponibles, afin de
pouvoir ”endormir” ce dont on n’a pas besoin et de conserver ce qui doit l’être.
Une fois configuré, il suffit pour entrer dans le mode d’énregie d’exécuter l’instruction SLEEP.
La sortie du mode se fait via une interruption externe ou interne, selon le mode utilisé.
7 Un
drapeau est un bit indiquant qu’un évènement s’est produit.
I.9. INTERRUPTIONS INTERNES ET EXTERNES
I.9
9
Interruptions internes et externes
Certains évènements peuvent intervenir à n’importe quel instant et doivent être gérés sans
attendre. Il est évident que de faire constament une batterie de tests pour voir si tel ou tel
évènement s’est produit n’est pas performant du tout. Les interruptions sont LA solution à ce
problème. En effet, dès qu’un évènement se produit, si l’interruption est correctement configurée,
le microcontrôleur arrête immédiatement son exécution pour exécuter une autre portion de code
gérant cet évènement. Dès que cette portion de code a fini d’être exécutée, le microcontrôleur
retourne à son programme principal, à l’endroit où il l’avait quitté.
Les interruptions possibles sont de deux types :
externe : lorsqu’une des pattes passe dans un certain état ou tant que la patte est dans un état
défini
interne : par exemple lorsque qu’un compteur dépasse sa valeur maximale8 , lorsqu’un transfert
via USART est terminé...
Plusieurs choses sont à faire pour configurer et utiliser les interruptions :
1. Pour les interruptions internes, configurer le registre correspondant pour déclencher l’interruption ; par exemple pour déclencher une interruption sur un Overflow du Timer/Counter0,
on configure le registre TIMSK en mettant le bit no 0, TOIE0, à 1.
2. Pour les interruptions externes, ce sont les registres EICRA, EICRB, EIMSK et EIFR qu’il
faut configurer pour qu’un certain état sur une ou plusieurs des pattes INT0 à INT7 déclenche
une interruption.
3. Il faut ensuite dire au microcontrôleur ce qu’il doit exécuter. Pour cela, les premiers blocs
de mémoire sont alloués à un Reset and Interrupt Vector. À chaque type d’interruption est
associé une adresse dans ce Vector où le développeur met une instruction ”jmp LABEL”,
LABEL étant l’adresse de la mémoire où se trouve le code à exécuter.
4. Ensuite, on programme le code qui doit être exécuté en le mettant à l’adresse LABEL définie
ci-dessus. Nous verrons dans le chapitre sur la programmation en C en page 15 comment ces
deux étapes peuvent être réalisé facilement.
5. Il reste à activer la gestion des interruptions à l’aide de la commande assembleur sei. La
gestion des interruptions peut être desactivée à l’aide de la commande assembleur cli.
A noter que le retour au programme principal se fait via la commande assembleur reti et non
via ret comme pour un retour depuis une sous-fonction classique.
8 on
appele cela Overflow
10
CHAPITRE I. LES MICROCONTRÔLEURS AVR POUR LES NULS
Chapitre II
La programmation des
microcontrôleurs en C
Normalement, à ce niveau, vous vous dı̂tes : ”Que ça a l’air bien les microcontrôleurs, ce
doit être trop dur à programmer.” Et bien, vous vous trompez ! Evidement si l’on était obligé de
programmer en assembleur, ce serait galère. Mais heureusement, les microcontrôleurs AVR ont
l’avantage de disposer de moultes compilateurs, ce qui permet de programmer en C, ce qui est,
vous l’avouerez, tout de même plus facile.
Parmis ces compilateurs, il y a entre autres1 : GCC AVR - compilateur sous license GNU
c’est-à-dire libre d’utilisation ; Imagecraft - alias ICC AVR ; et CodeVision AVR. Si GCC AVR est
gratuit, il a le gros désavantage de fonctionner sans interface graphique mais à l’aide de MakeFile.
Les aficionados de la programmation en C sous Linux ne seront guère gênés mais moi si. C’est
pourquoi j’ai choisi d’utiliser une version de démonstration d’Imagecraft, les limitations de cette
démo n’étant guère gênant pour de petits projets.
Pour les adeptes de Linux, reportez-vous aux rapports de mes prédecesseurs à cette adresse :
http://resel.enst-bretagne.fr/club/em6/site_2002/index.php3?corps=doc.
II.1
Débuter avec Imagecraft
Après un détour sur http://www.imagecraft.com pour télécharger la démo d’Imagecraft et
après l’avoir installé, on le lance et les choses sérieuses vont commencer.
Si vous êtes prêts, nous allons pouvoir commencer. Un projet est souvent composé de plusieurs
fichiers qu’il faut regroupé. Pour cela, on crée un ... Project ! Dans le menu Project, choisissez
New. Créez un répertoire où vous voulez que le projet soit stocké puis donnez-lui son nom2 . Pour
l’exemple qui suit, vous prendrez comme répertoire debut et comme nom de projet debut. Ouvrez
le projet ainsi créé via Project/Open. Ensuite faites File/New et vous pouvez commencer à écrire
du code.
Maintenant que tout est prêt pour commencer à programmer, je vous propose de faire un
programme qui consiste à faire clignoter une LED3 . D’abord, choisissons où sera connecté cette
1 Voir
sur http://www.avrfreaks.net pour plus de détails
AVR ne gère pas les noms de fichiers longs. Pour créer un projet dans un répertoire donc le chemin
d’accès contient des caractères illicites pour des noms de fichiers courts, il faut donner dans la case Nom du fichier
l’arborescence complète en format nom de fichier court. Par exemple C:\mesdoc~1\codeav~1\debut.prj
3 LED est le sigle anglais pour Diode Electro-Luminescente, c’est une petite ampoule.
2 ICC
11
12 CHAPITRE II. LA PROGRAMMATION DES MICROCONTRÔLEURS EN C
DEL. Si personne ne s’y oppose, je propose la patte PA04 .
Ensuite, il faut que le microcontrôleur sache quelle portion de code exécuter au démarrage.
Pour cela, on inclue ce code dans la fonction main. Voici donc le début de notre code :
void main(void){
Explications : main est l’entrée du programme, c’est vers là que se dirigera le microcontrôleur dès sa
mise sous tension. void est un mot anglais signifiant ”rien”. Placé avant le nom de la fonction - ici
main -, void indique que le programme ne renvoie pas de résultat comme par exemple pourrait le
faire une fonction somme. Ensuite, entre paranthèses se trouve les paramètres de la fonction, c’està-dire ce que la fonction a besoin de connaitre. Ici void soit ”rien” mais une fonction somme aura
besoin des deux nombres à additionner donc la fonction deviendrait : int somme(int n, int m)5 .
Le symbole { sert à indiquer le début de la fonction. A la fin de la fonction, il faut mettre }.
Nous avons vu dans le paragraphe sur les entrées/sorties, en page 5, que les pattes pouvaient
servir à la fois d’entrée ou de sortie. Ici il faut dire au microcontrôleur que la patte PA0 est une
sortie. Il faut donc mettre le bit 0 de DDRA à 1. La première instruction de notre programme est
donc :
DDRA=0x01;
En effet 0x indique que le nombre est en héxadécimal. Donc 0x01=00000001 en binaire6 . On
voit bien7 que le bit 0 de DDRA est mis à 1. PA0 est désormais une sortie pour le microcontrôleur.
Le point-virgule ” ;” sert à indiquer que l’instruction est finie.
Certains doivent se dire que c’est génial, que le compilateur comprend tout de suite ce que
DDRA signifie. Et bien non. En réalité le registre DRRA, comme tous les registres, est un endroit
de la mémoire dont l’emplacement change selon le microcontrôleur sur lequel on travaille. Il faut
donc préciser au compilateur quel microcontrôleur est utilisé afin qu’il puisse remplacer DDRA par
son adresse mémoire. Heureusement pour nous, pas besoin de redéfinir à chaque fois les adresses de
tous les registres utilisés, il suffit de mettre au tout début du programme, avant mêma la fonction
main, la déclaration suivante :
#include <iom128v.h>
La commande #include permet d’insérer dans le programme sur lequel on travaille des portions
de code définis dans un autre fichier, en l’occurence iom182v.h
Maintenant il faut allumer la LED. Pour cela, il faut mettre à 1 le bit 0 de PORTA. Ce qui se
fait via :
PORTA=0x01;
Etant donnée la vitesse d’éxecution8 , il faut patienter un peu avant d’éteindre la LED. On
utilise pour cela une boucle qui ne fait rien :
for(i=0;i<10000;i++);
La boucle for compte depuis i=0 tant que i<10000 en faisant i++ , c’est-à-dire en augmentant i
de 1 à chaque boucle. i ne tombe pas du ciel et doit être déclaré au début de la fonction afin que
le compilateur sache ce qu’est i. On mettra donc la déclaration suivante avant DDRA=0x01 ; :
int i ;
4 Souvenez-vous,
PA0 est la patte no 0 du port A, numéroté 51
= entier en anglais
6 Voir en annexe, page 33 pour la conversion héxadédimal/binaire/décimal
7 Les bits sont numérotés de droite à gauche. En effet, le bit 0 est le bit le moins important et est donc mis le
plus à droite, tout comme les unités sont placés à droite des dizaines, eux-mêmes à droite des centaines...
8 A 16 MHz, il faut 62.5ns pour faire l’instruction précédente.
5 int
II.2. LA SÉPARATION DE CODE EN PLUSIEURS FICHIERS ET QUELQUES
FONCTIONS UTILES
13
Ainsi le compilateur sait que i est un entier.
On peut désormais éteindre la LED et attendre à nouveau. On rajoute donc à la suite du
programme les instructions :
PORTA=0x00 ;
f o r ( i =0; i <10000; i ++);
Il faut maintenant recommencer à allumer, attendre, éteindre, attendre... Pour cela, on englobe
les 4 dernières instructions dans un bloc :
while ( 1 ) {
les 4 instructions
}
Ainsi les 4 dernières instructions seront répétées éternellement.
Il reste à finir la fonction main par } et le programme est terminé. Voici le programme au
complet :
#include <iom128v . h>
void main ( void )
{
int i ;
DDRA=0x01 ;
while ( 1 )
{
PORTA=0x01 ;
fo r ( i =0; i <10000; i ++);
PORTA=0x00 ;
for ( i =0; i <10000; i ++);
}
}
Sauvegardez le code (File/Save) dans le fichier code.c par exemple. Ensuite, indiquez quel
microcontrôleur est utilisé via le menu Project/Option/Target/Device Configuration. Indiquez maintenant que le fichier code.c fait partie du projet en cliquant doit sur Files dans la partie
droite de votre écran et en sélectionnant Add Files... Il ne reste plus qu’à compilé à l’aide de
la touche F9 ou via le menu Project/Make Project. Si aucune erreur n’apparait dans le bas de
votre écran, vous avez programmé votre premier projet sur microcontrôleur AVR. Félicitations !
Vous pouvez passer à la simulation, en page 19, ou alors en apprendre plus sur la programmation
C en continuant ci-dessous.
II.2
La séparation de code en plusieurs fichiers et quelques
fonctions utiles
Vous avez peut-être remarqué que dans le programme précédent les registres DDRA et PORTA
sont entièrement modifiés. Il y a des cas où cela n’est pas souhaité et où on souhaite passer le bit
0 à 1 sans modifier les autres bits. Nous allons donc pour cela créer des fonctions supplémentaires.
Mais ces fonctions ont de grandes chances d’être nécessaires dans un autre projet, et on a pas trop
envie de les réécrire le moment venu. Nous allons donc les mettre dans un fichier séparé qui sera
inclus dans les projets qui en ont besoin.
14 CHAPITRE II. LA PROGRAMMATION DES MICROCONTRÔLEURS EN C
II.2.1
La définition de fonctions utiles à l’aide de #define
Comment faire pour passer le nème bit du registre x à 1 sans modifier les autres bits ? Le
registre x est de la forme ( y , y , y , nème bit , y , y , y , y ) où y=0 ou 1. Il suffit de savoir9 que
(y OU 0)=y et que (y OU 1)=1. Il suffit donc de faire x OU ( 0 , 0 , 0 , 1 au nème bit , 0 , 0 , 0
, 0 ) pour obtenir le registre x identique sauf le nème bit qui est passé à 1. Ceci se fait en C par
l’instruction :
x|=(1<<n);
En effet, l’instruction x|=y réalise l’instruction x=(x OU y), car | est la traduction de OU en C.
On peut de même écrire x+=3 pour augmenter x de 3. Ensuite (x<<m) rajoute m zéros à la fin
de x et enlève les m premiers bits au début de x. Ainsi par exemple par exemple (6<<3) devient
00110000 car 6 en binaire est 00000110.
Présentons maintenant la déclaration #define. Par exemple, #define x 3 placée au début
du programme, entre les #include et la première fonction, indique au compilateur qu’il doit
remplacer tout les x qu’il trouve par un 3. Ce remplacement ne doit se faire que si x n’est pas
définit, on met donc cette déclaration dans un bloc :
#ifndef nom du bloc de définition
#define nom du bloc de définition
liste des définitions
#endif
Une macro10 ne se termine pas par un point-virgule car celui-ci sera mis par le développeur
dans son programme lors de l’appel de cet macro. Il est possible de faire une macro sur plusieurs
lignes selon le format suivant :
#define nom de la macro \
instruction1 ; \
instrution2 ; \
...
dernière instruction
Cette fois des ; sont mis car, je le rappele, le compilateur ne fait que remplacer le nom de la macro
par sa définition.
II.2.2
Rajouter un fichier à un projet
Nous allons donc maintenant définir 4 fonctions très utiles pour tout projet. Pour cela, après
avoir relancé et ouvert le projet debut si vous l’aviez quitté depuis, faites File/New. Entrez ensuite
les déclarations suivantes :
#i f n d e f
#define
#define
#define
#define
#define
FONCTIONS UTILES
FONCTIONS UTILES
SET BIT ( o c t e t , b i t ) ( o c t e t |= (1<< b i t ) )
CLEAR BIT( o c t e t , b i t ) ( o c t e t &= ˜(1<< b i t ) )
IS SET ( o c t e t , b i t ) ( ( o c t e t & (1<< b i t ) ) ! = 0 )
IS CLEAR ( o c t e t , b i t ) ( ( o c t e t & (1<< b i t ) ) = = 0 )
#endif
9 L’opération
10 Une
OU se fait bit à bit avec les règles suivantes : (0 OU 0)=0 ; (0 OU 1)=1 ; (1 OU 0)=1 ; (1 OU 1)=1
macro est une fonction écrite à l’aide d’un #define
II.3. LES INTERRUPTIONS AVEC IMAGECRAFT AVR
15
Enregistrez ce fichier sous le nom fonctions utiles.h dans le répertoire debut. Pourquoi .h
alors qu’avant c’était debut.c ? Et bien parce que la règle veut que les fichiers secondaires soient
dans un ”header”. Mais dans un header, on ne peut écrire que des #define et non du code. Dans
ce cas, on sépare les #define qu’on met dans un .h et les portions de code qu’on met dans un .c
qui porte le même nom que le .h.
Ensuite clic droit sur Header dans la partie droite de votre écran puis Add Files... pour
ajouter les fonctions utiles au projet. Puis il faut dire au programme principal qu’il a le droit
d’utiliser ce fichier. Cela se fait en mettant :
#include ”fonctions utiles.h”
juste après les autres #include. Les plus observateurs auront remarqué que l’ont a mis des guillemets au lieu de <> comme à la page 12. Les <> signifient que le fichier se trouve dans le répertoire
où est installé le compilateur alors que les guillemets indiquent que le fichier est dans le même
répertoire que le projet.
On peut maintenant utiliser les macros SET BIT et CLEAR BIT dans la fonction main. Par
exemple :
SET BIT(DDRA,0);
pour mettre à 1 le bit 0 de DDRA.
II.3
Les interruptions avec ImageCraft AVR
Nous avons vu, en page 9 que la gestion des interruptions est lourde à faire en assembleur.
Heureusement, le C et Imagecraft sont là pour nous aider. Si les étapes 1,2 et 5 restent inchangées,
voilà comment faire pour s’occuper des étapes 3 et 4. Pour l’exemple, nous allons allumer une LED
sur PA0 dès que la patte PD0 passe à 1, PD0 étant la patte correspondant à INT0, l’interruption
externe no 0.
Lors du déclenchement d’une interruption, le programme principal est interrompu et une certaine fonction s’exécute. Dans notre cas, cette fonction va allumer la LED, appelons-la allume si
vous le voulez bien. Si tous les #include ont été correctement fait, la fonction s’écrit facilement
par :
void a l l u m e ( )
{ SET BIT (PORTA, 0 ) ; }
Il faut maintenant dire au compilateur que c’est cette fonction qui doit être appelées lors de
l’interruption externe. Pour cela, Imagecraft possède la déclaration :
#pragma interrupt handler nom de la fonction:iv nom de l’interruption.
Dans notre exemple, on aura donc :
#pragma i n t e r r u p t h a n d l e r a l l u m e : iv INT0 ;
Ainsi, l’interruption INT0 exécutera la fonction allume quand elle se déclenche.
16 CHAPITRE II. LA PROGRAMMATION DES MICROCONTRÔLEURS EN C
Reste à écrire le reste et on obtient in fine :
#include <iom128v . h>
#include ” f o n c t i o n s u t i l e s . h”
#pragma i n t e r r u p t h a n d l e r a l l u m e : iv INT0
void a l l u m e ( )
{
SET BIT (PORTA, 0 ) ;
}
void main ( void )
{
SET BIT (DDRA, 0 ) ;
// l a p a t t e 0 du p o r t A e s t une s o r t i e
CLEAR BIT(DDRD, 0 ) ; // l a p a t t e 0 du p o r t D e s t une e n t r e e
EICRA = 0 x03 ;
EICRB = 0 x00 ;
EIMSK = 0 x01 ;
TIMSK = 0 x00 ;
ETIMSK = 0 x00 ;
asm ( ” s e i ” ) ;
while ( 1 ) ;
}
Les valeurs attribuées à EICRA, EICRB, EIMSK, TIMSK et ETIMSK sont trouvées d’après
la datasheet. asm(”sei”) est expliqué dans le paragraphe suivant. Le compilateur se charge de
terminer la fonction traitant une interruption par l’instruction reti au lieu d’un ret habituel,
le développeur n’a rien à se soucié. Dans l’exemple donné, le microcontrôleur exécute sans cesse
l’instruction while(1), c’est-à-dire ne fait rien. Dès que la patte PD0 passe à 1, la fonction allume()
est appelée. Lorsqu’elle se termine, le microcontrôleur retourne où il s’était arrêté, c’est-à-dire à
l’instruction while(1).
II.4
L’assembleur dans un programme en C
Il est parfois nécessaire d’insérer des commandes assembleur directement dans le code C. Cela se
fait via l’instruction asm("instruction en assembleur") ; qui insère l’instruction en assembleur
dans le code compilé. Voici quelques exemples les plus fréquents :
asm ( ”nop” ) ; // i n s t r u c t i o n ne f a i s a n t r i e n pendant un c y c l e d ’ h o r l o g e
asm ( ” s e i ” ) ; // l e s i n t e r r u p t i o n s s o n t p r i s e s en compte
asm ( ” c l i ” ) ; // l e s i n t e r r u p t i o n s ne s o n t p l u s p r i s e s en compte
Un autre cas où le recours à l’assembleur est nécessaire est lorsque l’on cherche à mettre
une temporisation d’une durée précise. Dans ce cas, on n’a d’autres choix que de regarder le
code compilé en assembleur pour voir combien de temps nos instructions durent afin d’adapter la
longueur de la boucle de temporisation.
II.5
Quelques compléments sur le compilateur ICC AVR
Ce compilateur fournit un outil très utile pour tous développeurs : l’Application Builder qui
se trouve dans le menu Tools. Cet outil écrit automatiquement les lignes de configurations du
microcontrôleur selon les besoins que vous aurez spécifiés. Ainsi, il devient facile de démarrer
un projet nécessitant la gestion de plusieurs Timers/Counters, d’interruptions multiples ou de
II.5. QUELQUES COMPLÉMENTS SUR LE COMPILATEUR ICC AVR
17
communication USART sans avoir à ouvrir la datasheet du microcontrôleur pour trouver quels
registres doivent être initialisés et avec quelles valeurs.
J’ai remarqué quelques problèmes avec le compilateur au sujet de la gestion des entiers longs.
En effet, si les opérations sur les int et les float ne posent aucuns problèmes, il n’en est pas de même
pour les long. Si vous souhaitez faire des calculs sur de grands entiers, préférez donc l’utilisation
de float partout. Ce problème est facilement repérable grâce à la simulation des programmes, ce
que je vais vous présenter dans le chapitre suivant.
18 CHAPITRE II. LA PROGRAMMATION DES MICROCONTRÔLEURS EN C
Chapitre III
La simulation des progammes
Après avoir écrit son code, on aimerait bien voir comment les instructions s’enchaı̂nent pour
voir si tout fonctionne comme prévu. Cela se fait grâce à AVR Studio 4, logiciel gratuit développé
par ATMEL. Courrez le télćharger sur http://www.atmel.com/atmel/products/prod203.htm
puis installez-le.
La simulation est conforme au comportement réel du microcontrôleur dans la mesure où le
simulateur est correctement programmé. A l’heure où j’écris ces lignes, des bugs subsistent. Par
exemple, la gestion des Timer/Counter, et particulièrement de la génération de signaux PWM, ne
marche absolument pas. Il ne faut donc pas s’y fier dans ces domaines. De même, l’implémentation
des programmes dans le microcontrôleur via le câble AVR ISP (voir en page 23) présente parfois
certaines difficultés incompréhensibles. Ce dernier point peut être résolu en utilisant conjointement
les version 3 et 4 de AVR Studio, la version 3 ne présentant aucun problème avec AVR ISP.
Peut-être ces problèmes seront-ils résolus dans les futurs versions de AVR Studio 4 lorsque vous
souhaiterez l’utiliser, alors essayez donc si la version 4 vous convient.
III.1
Premiers pas avec AVR Studio 4
Après l’avoir lancé, faites File/Open et ouvrez le fichier debut.cof. Vous avez ensuite le menu
suivant qui s’affiche1 :
où vous choisissez AVR Simulator et ATmega128.
1 Si ce n’est pas la première fois que vous ouvrez le fichier, AVR Studio 4 vous signale que ce fichier est déjà
associé à un projet et vous demande si vous voulez ouvrir ce projet. Répondez oui à moins que vous ne vouliez
retomber sur la fenêtre affichée ci-dessus.
19
20
CHAPITRE III. LA SIMULATION DES PROGAMMES
Après avoir cliquez sur Finish, l’écran suivant devrait apparaitre :
Voyons à quoi servent les différentes parties de cet écran.
III.2
Workspace
C’est là que vous pouvez voir l’état de votre microcontrôleur. Vous pouvez ainsi voir les valeurs
de tous les registres du microcontrôleur mais aussi les modifier en temps réel. A côté de chaque
registre se trouvent des cases symbolisant les bits du registre. La première case est le bit 7 du
registre2 et ainsi de suite. Si la case est coloriée, le bit est à 1, il est à 0 sinon. Dans l’exemple
donné, PORTA=0x21, soit le bit 0 et 5 à 1.
2 Rappelez-vous
que les bits sont représentés dans l’ordre inverse : page 12
III.3. PROGRAMME EN COURS
21
Un autre outil important de cette fenêtre est la Stop Watch. C’est un chronomètre qu’on remet
à zéro en cliquant droit dessus et en choisissant Reset StopWatch. Cela permet de savoir le temps
écoulé entre deux instructions quelconques. Attention, le calcul est fait à une certaine fréquence
d’horloge, visible juste au-dessus de la Stop Watch. La fréquence de l’horloge peut être modifiée
via le menu Debug/AVR Simulation Options.
III.3
Programme en cours
C’est là qu’on peut suivre où en est le programme dans son déroulement. La prochaine instruction à être exécutée est indiquée par la flèche jaune. C’est ici qu’on peut placer des Breakpoints3 .
Pour mettre un Breakpoint ou en enlever un, il suffit de faire un clic droit sur l’instruction où l’on
souhaite installer/enlever un Breakpoint puis de choisir Toggle Breakpoint.
Un autre outil très utile accessible depuis cette fenêtre est de pouvoir suivre en temps réel la
valeur des variables du programme. Pour cela, on selectionne cette variable, on clique droit et on
choisit Add To Watch. C’est ce qui a été fait dans l’exemple pour la variable i.
III.4
Contrôle du déroulement
Cette barre contrôle le déroulement du programme. Les principaux boutons sont :
Start et Stop Debugging : Comme vous devez vous en doutez, ces deux boutons permettent
de commencer et d’arrêter le déroulement du programme.
3 Points
d’arrêt, voir Contrôle du déroulement en page 21
22
CHAPITRE III. LA SIMULATION DES PROGAMMES
Run : Permet d’exécuter le programme. Dans ce mode, le Workspace et la fenêtre Watch sont
inacessibles. Ce mode se termine soit en cliquant sur Break, soit lorsque le logiciel rencontre
un Breakpoint. Ce mode est très utile pour sortir de boucles d’attente de longue durée en
mettant un Breakpoint sur la première instruction après la boucle. Associé à la Stop Watch,
on peut savoir la durée de la boule (cf. page 21).
Break : Permet d’interrompre l’exécution du programme lors qu’on est en mode Run ou AutoStep.
Reset : Comme son nom l’indique, recommence le programme depuis le début.
Step Into : Mode pas-à-pas. Exécute la seule instruction indiquée par la flèche jaune. Si cette
instruction fait appel à une sous-fonction, la fenêtre du programme en cours s’ouvre sur cette
sous-fonction et le développeur peut exécuter les instructions de cette sous-fonction en mode
pas-à-pas.
Step Over : Mode pas-à-pas également, mais à la différence de Step Into s’il y a appel d’une
sous-fonction, celle-ci est exécutée entièrement sans que le développeur ne puisse suivre son
déroulement.
Step Out : Termine la fonction en cours d’exécution puis retourne au programme qui l’a appelée
en redonnant la main au développeur.
Run To Cursor : Exécute le programme jusqu’au curseur4 .
AutoStep : Equivalent à Run mais ici le développeur voit le Workspace et la fenêtre Watch.
Le déroulement est plus lent qu’en mode Run mais on peut voir ce qui se passe dans le
microcontrôleur ou les variables du programme.
III.5
Choix de la vue
Register et Memory Window : Affichent la vue sélectionnée dans la fenêtre Workspace.
Watch : Affiche la fenêtre Watch qui permet d’afficher la valeur de variables choisies, voir page
21.
Toggle Disassembler Window : Permet d’afficher le code assembleur dans la fenêtre du programme en cours et dès lors d’exécuter les instructions en assembleur au pas-à-pas. Très utile
pour voir comment le programme a été compilé notamment pour connaitre les instructions
utilisées dans une boucle afin de pouvoir adapté le nombre d’occurences pour obtenir une
durée précise.
III.6
Output view
Cette fenêtre permet de voir si la simulation se déroule bien, par exemple s’il n’y a pas eu
d’erreurs de chargement du projet. En résumé, c’est là que seront affichés les messages provenant
du simulateur.
4 La
barre verticale qui clignote à l’endroit où le texte tapé est inséré
Chapitre IV
L’implémentation réelle sur le
microcontrôleur
Si tout marche comme il faut sur le papier et sur la simulation, passons aux choses sérieuses et
voyons ce que ça donne dans la réalité. Et bien c’est là que les choses se gâtent et je dois avouer
que le chemin jusqu’au microcontrôleur fonctionnel est long et semé d’embûches. Mais avec ce
document, tout devrait aller (enfin, j’espère). Construisons donc une carte pour programmer cet
ATmega128. Cette programmation ce fera via un câble AVR ISP, disponible chez de nombreux
fournisseurs de matériel électronique.
IV.1
L’alimentation
Le microcontrôleur est alimenté en 0V - 5V, aussi stable que possible. Evidement, on relie les
masses ensemble sur le 0V d’une part, et les Vcc ensemble sur le 5V d’autre part. De plus, doivent
être aussi reliées à Vcc deux pattes : AV cc - l’alimentation du convertisseur analogique-numérique
- et P EN - inutilisé pour la programmation via AVR ISP.
IV.2
L’horloge
Plusieurs solutions s’offrent à vous pour cadencer le microcontrôleur. On verra plus loin comment indiquer au microcontrôleur la solution choisie, en page 27
L’ocillateur interne : Certains microcontrôleurs de la famille AVR possèdent un oscillateur interne, par exemple l’ATmega128 en possède quatre fonctionnant à 1, 2, 4 ou 8 MHz. Cette
solution offre l’avantage d’être facile à mettre en oeuvre (rien à faire) mais a l’inconvénient
d’avoir une fréquence instable selon la tension d’alimentation, la température, etc... et surtout de ne pas pouvoir fonctionner jusqu’au 16 MHz maximum de l’ATmega128.
L’horloge externe : Il suffit de fournir un signal carré sur la patte XTAL1, mais encore faut-il
pouvoir le générer ce signal.
L’oscillateur RC externe : Cette solution présente l’avantage de pouvoir aller plus haut en
fréquence (jusque 12 MHz sur l’ATmega128) et de choisir des fréquences autres que celles de
l’oscillateur interne mais présente encore le gros inconvénient d’être instable en température
et tension d’alimentation.
Le quartz ou le résonnateur : C’est la solution pour être précis, stable et atteindre les 16 MHz
mais peut présenter des difficultés de mise en oeuvre. Les quartz à deux pattes se branche sur
XTAL1 et XTAL2 avec deux condensateurs entre chaque pattes et la masse, comme indiqué
sur le schéma ci-dessous.
23
CHAPITRE IV. L’IMPLÉMENTATION RÉELLE SUR LE
MICROCONTRÔLEUR
24
Fig. IV.1 – Utilisation d’un quartz
Et c’est ces capacités qui posent problèmes. Selon leur valeur, le quartz peut fonctionner
ou non. Et leur valeur, identique pour les deux condensateurs, dépend du quartz, du microcontrôleur et des pistes qui rejoignent le tout. Et pour vérifier si le quartz fonctionne, l’oscilloscope n’est d’aucune utilité puisqu’il rajoute des capacités parasites, il est donc nécessaire
d’utiliser un analyseur logique. En pratique, 22pF semble être une valeur qui marche bien,
mais si ce n’est le cas, il va falloir tester plusieurs valeurs jusqu’à ce que ça fonctionne.
En tous cas, limitez au maximum la longueur des pistes entre les condensateurs, le quartz
et le microcontrôleur. Certains quartz à 4 pattes ainsi que les résonnateurs possèdent déjà
des capacités intégrées mais fonctionneront à des fréquences moins précises et seront plus
instables. Pour plus de renseignements, se reporter à http://www.avrfreaks.com/Freaks/
Articles/ColinOFlynn/intro.php.
IV.3
Le port de programmation
Les choses se compliquent encore plus maintenant car il faut déchiffrer la datasheet de l’ATmega128 et de l’AVR ISP, et ce ne sont pas des modèles de clarté. Le câble AVR ISP se branche
sur la carte de votre microcontrôleur via un connecteur 6 ou 10 broches. Vu que la version 10
Fig. IV.2 – Connecteur du câble AVR ISP, à brancher sur la carte de microcontrôleur, vue 2D
broches n’apporte rien, on utilisera le connecteur 6 broches. Et vu que ce dessin n’est pas très
clair, en voilà un plus beau :
IV.3. LE PORT DE PROGRAMMATION
25
Fig. IV.3 – Connecteur du câble AVR ISP, à brancher sur la carte de microcontrôleur, vue 3D
Voyons comment connecter ce câble au microcontrôleur.
Vtg et Gnd : se connectent à l’alimentation, Vtg étant bien entendu Vcc
Reset : Comme la barre l’indique, cette patte du microcontrôleur doit être reliée en temps normal
à Vcc mais doit pouvoir être forçée à 0 par AVR ISP. On utilise donc le montage suivant :
Fig. IV.4 – Connection de la patte RESET au connecteur AVR ISP
SCK : Se connecte à la broche nommée SCK du microcontrôleur soit PB1.
MOSI et MISO : C’est là que les choses sont bizarres. On se dit qu’il suffit de connecter le
MOSI du microcontrôleur sur le MISO du câble et inversement. Et bien non ! Allez savoir
pourquoi, ATMEL a décidé et écrit au fin fond de la datasheet que pour l’ATmega128, MISO
du câble se connecte à PDO soit PE1 et que le MOSI du câble se connecte à PDI soit PE0.
Pour les autres microcontrôleurs le problème ne se pose pas.
CHAPITRE IV. L’IMPLÉMENTATION RÉELLE SUR LE
MICROCONTRÔLEUR
26
Si vous comptez utiliser les broches SCK, PDI et PDO du microcontrôleur pour les brancher à
quelquechose d’autre, une petite précaution s’impose. Soit déconnecter ce quelquechose au moment
de la programmation, soit faire le montage suivant pour chaque broche :
Fig. IV.5 – Connection des pattes PDI et PDO au connecteur AVR ISP
IV.4
Comment implémenter notre programme dans le microcontrôleur
Vous allez devoir quitter ce tutorial quelques jours le temps de réaliser la carte et de souder
les composants. Voici un site très utile sur la soudure de composants CMS :
http://home.nordnet.fr/~fthobois/les_cms.htm
Pour vérifier la bonne soudure des pattes, utilisez un multimètre en testeur de continuité mais
attention, il faut éviter d’appuyer sur les pattes du microcontrôleur au risque de prendre un faux
contact pour une bonne soudure.
Ca y est, la carte est prête, tout est soudé, alors allons-y. Nous allons implémenter le programme
debut fait dans la partie sur la programmation en C, en page 11. Pour cela, il faut bien sûr brancher
le câble AVR ISP sur l’ordinateur, l’autre côté sur la carte électronique, puis lancer AVR Studio
4 1 et charger le projet debut comme indiqué à la page 19. Enfin, mettez sous alimentation votre
montage. ATTENTION : il faut impérativement brancher le câble AVR ISP avant d’alimenter
le circuit, sous peine de voir la câble griller. Maintenant, sous AVR Studio 4, cliquez sur le bouton
suivant :
et un menu composé de 6 onglets apparait. Voici les onglets, que nous allons regarder maintenant :
Program : Choisissez dans Device le microcontrôleur que vous utilisez. Indiquez ensuite que
vous programmez le microcontrôleur via ISP. Les menus Flash et EEPROM permettent de
1 ou
AVR Studio 3, d’après ma remarque au début du chapitre 3, page 19, l’interface étant sensiblement la même
IV.4. COMMENT IMPLÉMENTER NOTRE PROGRAMME DANS LE
MICROCONTRÔLEUR
27
programmer les mémoires correspondantes, soit le programme chargé dans le simulateur,
soit un programme désigné en chargeant le fichier .hex créé par le compilateur. La mémoire
Flash est sauf exception, celle qui contient le programme.
Fuses : Ce menu permet de configurer le microcontrôleur. Décochez d’abord la compatibilité
ATmega103. Puis tout ce que vous avez à changer désormais est le type d’horloge que vous
souhaitez utiliser. A noter que si vous souhaitez utiliser un quartz à plus de 8 MHz, il faut
décocher ”CKOPT fuse”.
LockBits : Attention, les changements ici peuvent être irréversibles. C’est ici qu’on peut bloquer
définitivement la modification de certains paramètres, voire bloquer toute programmation
ultérieure. Bref, on ne touche à rien.
Advanced : Ici vous pouvez éventuellement spécifier le port série utilisé par AVR ISP, mais en
Auto, ça semble marcher très bien. Sinon, un bon moyen de voir si le microcontrôleur répond
est de lire sa signature et ainsi de s’assurer que le microcontrôleur est celui qu’on pensait.
Board : Je n’ai pas vraiment compris l’utilité de cet onglet alors passons.
Auto : Permet d’automatiser certaines tâches afin, d’un seul clic, de pouvoir exécuter plusieurs
opérations à la suite. On peut ainsi automatiser des tâches répétitives.
28
CHAPITRE IV. L’IMPLÉMENTATION RÉELLE SUR LE
MICROCONTRÔLEUR
Le mot de la fin
Voilà, vous savez tout ce que vous avez besoin de savoir pour faire un projet sur les microcontrôleurs AVR d’ATMEL. Je tiens à remercier tout ceux qui m’ont aidé et soutenu lors de la
découverte de ces microcontrôleurs. Parmi eux, les membres de mon équipe : François BARRE,
Vincent BORREL, Guillaume DUPUY, Thomas LEFÈVRE, Arnaud LESUEUR, Jean-Baptiste
RICHARD et Benjamin SARDA ainsi que les anciens de la robotique à l’ENST Bretagne : Pascal
LEGRAND, Samuel MESCOFF, Sébastien ROY, Luc SORGUE et Nicolas TORNERI.
Si vous avez des commentaires, suggestions ou si vous avez un texte à rajouter à ce document,
je me ferai un plaisir d’en tenir compte. Envoyez-moi un simple mail à
[email protected]
29
30
LE MOT DE LA FIN
Annexe A
Schéma de l’ATmega128
31
32
ANNEXE A. SCHÉMA DE L’ATMEGA128
Annexe B
Conversion
hexadécimal/binaire/décimal
B.0.1
Convention d’écriture
En décimal, notre base habituel, le nombre est écrit comme d’habitude : 21
En héxadécimal, on le fait précéder d’un ”0x” : 0x15
En binaire, on le termine par un ”b” : 00010101b
Conversion binaire/hexadécimal
Pour convertir un octet binaire en une valeur hexadécimal, procédez ainsi :
1. Découper votre octet en deux parties de 4 bits
2. Convertir les deux morceaux obtenus selon le tableau suivant :
binaire
hexadecimal
0000
0
0001
1
0010
2
0011
3
0100
4
0101
5
0110
6
0111
7
binaire
hexadecimal
1000
8
1001
9
1010
A
1011
B
1100
C
1101
D
1110
E
1111
F
3. Et pour finir on colle ensemble les deux symboles hexadécimal pour trouver la conversion.
Par exemple : 01111101b
étape1
y 0111 et 1101
étape2
y 7 et D
étape3
y d’où 01111101b = 0x7D
Suivez les étapes en sens inverse pour convertir un nombre hexadécimal en binaire.
33
ANNEXE B. CONVERSION HEXADÉCIMAL/BINAIRE/DÉCIMAL
34
Conversion hexadécimal/décimal
0x0.
0x1.
0x2.
0x3.
0x4.
0x5.
0x6.
0x7.
0x8.
0x9.
0xA.
0xB.
0xC.
0xD.
0xE.
0xF.
0x.0
0
16
32
48
64
80
96
112
128
144
160
176
192
208
224
240
0x.1
1
17
33
49
65
81
97
113
129
145
161
177
193
209
225
241
0x.2
2
18
34
50
66
82
98
114
130
146
162
178
194
210
226
242
0x.3
3
19
35
51
67
83
99
115
131
147
163
179
195
211
227
243
0x.4
4
20
36
52
68
84
100
116
132
148
164
180
196
212
228
244
0x.5
5
21
37
53
69
85
101
117
133
149
165
181
197
213
229
245
0x.6
6
22
38
54
70
86
102
118
134
150
166
182
198
214
230
246
0x.7
7
23
39
55
71
87
103
119
135
151
167
183
199
215
231
247
0x.8
8
24
40
56
72
88
104
120
136
152
168
184
200
216
232
248
0x.9
9
25
41
57
73
89
105
121
137
153
169
185
201
217
233
249
0x.A
10
26
42
58
74
90
106
122
138
154
170
186
202
218
234
250
0x.B
11
27
43
59
75
91
107
123
139
155
171
187
203
219
235
251
0x.C
12
28
44
60
76
92
108
124
140
156
172
188
204
220
236
252
0x.D
13
29
45
61
77
93
109
125
141
157
173
189
205
221
237
253
0x.E
14
30
46
62
78
94
110
126
142
158
174
190
206
222
238
254
0x.F
15
31
47
63
79
95
111
127
143
159
175
191
207
223
239
255
Annexe C
Aide à la programmation
C.1
Type de données
Type
Taille (octects)
Domaine
unsigned char
1
0...255
signed char
1
-128...127
char (*)
1
0...255
unsigned short
2
0...65535
(signed) short
2
-32768...32767
unsigned int
2
0...65535
(signed) int
2
-32768...32767
pointer
2
unsigned long
4
0...4294967295
(signed) long
4
-2147483648...2147483647
float
4
+/-1.175e-38...3.40e+38
double
4
+/-1.175e-38...3.40e+38
(*) ”char” est équivalent à ”unsigned char”
C.2
Gestion des entrées/sorties
DDRx : Data Direction Register, bit à 0 pour que la patte correspondante soit une entrée, à 1
pour une sortie
PORTx : pour changer la valeur des pattes en sortie
PINx : pour obtenir la valeur des pattes en entrée
x est une lettre entre A et G indiquant le port considéré.
C.3
Interruptions externes
EICRA, External Interrupt Control Register A
bit
EIRCA
7 6
ISC3
5 4
ISC2
3 2
ISC1
ISCn
00
01
10
11
1 0
ISC0
35
Interruption de INTn sur
niveau bas
non disponible
front descendant
front montant
36
ANNEXE C. AIDE À LA PROGRAMMATION
EICRB, External Interrupt Control Register B
bit
EIRCB
7 6
ISC7
5 4
ISC6
3 2
ISC5
1 0
ISC4
ISCn
00
01
10
11
Interruption de INTn sur
niveau bas
front montant et front descendant
front descendant
front montant
EIMSK, External Interrupt Mask
bit
7
6
5
4
3
2
1
0
EIMSK INT7 INT6 INT5 INT4 INT3 INT2 INT1 INT0
INTn à 1 pour que l’interruption externe correspondante soit prise en compte.
C.4
Timer/Counter0 (8 bits)
TCNT0, Timer Counter Register : indique la valeur courante du Timer/Counter0
OCR0, Output Compare Register : peut être utilisé pour générer une interruption en cours de
comptage (voir C.7)
TCCR0, Timer Counter Control Register
TCCR0 Fréquence de comptage Durée totale (*)
0x00
Timer/Counter0 arrêté
0x01
clkI/0
16µs
0x02
clkI/0 / 8
128µs
0x03
clkI/0 / 32
512µs
0x04
clkI/0 / 64
1, 024ms
0x05
clkI/0 / 128
2, 048ms
0x06
clkI/0 / 256
4, 096ms
0x07
clkI/0 / 1024
16, 384ms
(*) Durée entre deux retours à 0 pour un microcontrôleur cadencé à 16MHz
C.5
Timer/Counter2 (8 bits)
TCNT2, Timer Counter Register : indique la valeur courante du Timer/Counter2
OCR2, Output Compare Register : peut être utilisé pour générer une interruption en cours de
comptage (voir C.7)
TCCR2, Timer Counter Control Register
TCCR2
Fréquence de comptage
Durée totale (*)
0x00
Timer/Counter2 arrêté
0x01
clkI/0
16µs
0x02
clkI/0 / 8
128µs
0x03
clkI/0 / 64
1, 024ms
0x04
clkI/0 / 256
4, 096ms
0x05
clkI/0 / 1024
16, 384ms
0x06
Horloge externe sur T2 (front descendant)
0x07
Horloge externe sur T2 (front montant)
(*) Durée entre deux retours à 0 pour un microcontrôleur cadencé à 16MHz
C.6. TIMER/COUNTER1 ET 3 (16 BITS)
C.6
37
Timer/Counter1 et 3 (16 bits)
TCNTnH et TCNTnL, Timer Counter Register High et Low : indique la valeur courante
du Timer/Counter

OCRnAH, OCRnAL 
utilisés pour générer des interruptions en cours de comptage
OCRnBH, OCRnBL
 (voir C.7)
OCRnCH, OCRnCL
TCCRnA, Timer Counter Control Register A = 0x00
TCCRnB, Timer Counter Control Register B
TCCRnB
Fréquence de comptage
Durée totale (*)
0x00
Timer/Counter2 arrêté
0x01
clkI/0
4, 096ms
0x02
clkI/0 / 8
32, 768ms
0x03
clkI/0 / 64
262, 144ms
0x04
clkI/0 / 256
1, 048576s
0x05
clkI/0 / 1024
4, 194304s
0x06
Horloge externe sur Tn (front descendant)
0x07
Horloge externe sur Tn (front montant)
(*) Durée entre deux retours à 0 pour un microcontrôleur cadencé à 16MHz
C.7
Interruptions pour Timers/Counters
TIMSK, Timer Counter Interrupt Mask
bit
7
6
5
4
TIMSK
Comp2
Over2
0 Comp1A
3
Comp1B
2
Over1
1
Comp0
0
Over0
ETIMSK, Extended Timer Counter Interrupt Mask
bit
7
6
5
4
3
ETIMSK
0
0
0 Comp3A Comp3B
2
Over3
1
Comp3C
0
Comp1C
Overn à 1 active l’interruption d’Overflow du Timer/Counter n, c’est-à-dire qu’une interruption est déclenché quand le Timer/Counter revient à la valeur 0
Compnx à 1 active l’interruption de comparaison lorsque le Timer/Counter n atteint la valeur
du registre OCRnx
C.8
Génération de PWM sur OC0 (8 bits)
OCR0
haut
OCR0, Output Compare Register : permet de définir le rapport cyclique η = temps
tempsbas = 256
TCCR0, Timer Counter Control Register
TCCR0 Fréquence du signal PWM Période (*) Commentaire
0x68
Timer/Counter0 arrêté
A éviter
0x69
clkI/0 / 256
16µs
0x6A
clkI/0 / 2048
128µs
0x6B
clkI/0 / 8192
512µs
0x6C
clkI/0 / 16384
1, 024ms
0x6D
clkI/0 / 32768
2, 048ms
0x6E
clkI/0 / 65536
4, 096ms
0x6F
clkI/0 / 262144
16, 384ms
Recommandé pour les servomoteurs
(*) Période du signal PWM pour un microcontrôleur cadencé à 16MHz
38
ANNEXE C. AIDE À LA PROGRAMMATION
C.9
Génération de PWM sur OC2 (8 bits)
Attention, OC2 est commun avec une autre sortie PWM, OC1C
haut
OCR2, Output Compare Register : permet de définir le rapport cyclique η = temps
tempsbas =
TCCR2, Timer Counter Control Register
TCCR2
Fréquence du signal PWM
Période (*) Commentaire
0x68
Timer/Counter0 arrêté
A éviter
0x69
clkI/0 / 256
16µs
0x6A
clkI/0 / 2048
128µs
0x6B
clkI/0 / 16384
1, 024ms
0x6C
clkI/0 / 65536
4, 096ms
0x6D
clkI/0 / 262144
16, 384ms
Servomoteurs
0x6E
Horloge externe sur T2 (front descendant)
0x6F
Horloge externe sur T2 (front montant)
(*) Période du signal PWM pour un microcontrôleur cadencé à 16MHz
C.10
OCR2
256
PWM sur OC1A, OC1B, OC1C, OC3A, OC3B et
OC3C (de 8 à 10 bits)
Dans ce qui suit, n vaut 1 ou 3 et x vaut A, B ou C
OCRnxH
OCRnxL
⇒ forment par concaténation OCRnx=65536*OCRnxH+OCRnxL
rapport cyclique ηnx =
OCRnx
où resolution ∈ {8, 9, 10} selon la configuration choisie
2resolution
TCCRnA, Timer Counter Control Register A
bit
7
6
5
4
3
2
1
0
TCCRnA
COMnA COMnB COMnC WGMn
COMnx
00
10
WGMn
01
10
11
Description
OCnx non utilisé
OCnx utilisé
Résolution
8 bits
9 bits
10 bits
TCCRnB, Timer Counter Control Register B
TCCRnB
8 bits
Fréquence PWM
9 bits
10 bits
Fréquence
à 16MHz
Fréquence
à 16MHz
Fréquence
à 16MHz
0x09
clkI/O
resolution
2
clkI/O
256
16µs
clkI/O
512
32µs
clkI/O
1024
64µs
0x0A
clkI/O
8 ∗ 2resolution
clkI/O
2048
128µs
clkI/O
4096
256µs
clkI/O
8192
512µs
0x0B
clkI/O
64 ∗ 2resolution
clkI/O
16384
1, 024ms
clkI/O
32768
2, 048ms
clkI/O
65536
4, 096ms
C.11. USART
TCCRnB
39
8 bits
Fréquence PWM
9 bits
10 bits
Fréquence
à 16MHz
Fréquence
à 16MHz
Fréquence
à 16MHz
0x0C
clkI/O
256 ∗ 2resolution
clkI/O
65536
4, 096ms
clkI/O
131072
8, 192ms
clkI/O
262144
16,384ms
0x0D
clkI/O
1024 ∗ 2resolution
clkI/O
262144
16,384ms
clkI/O
524288
32, 768ms
clkI/O
1048576
65, 536ms
C.11
USART
Dans ce qui suit, n vaut 0 ou 1 selon l’USART considéré. Format de la trame : voir page 7
UDRn, USARTn Data Register : destination des données reçues ou origine des données à
envoyer
UCSRnA, USARTn Control and Status Register A : non utilisé pour la configuration
UCSRnB, USARTn Control and Status Register B
bit
7
6
5
4
3
2
1
0
UCSRnB RXCIEn TXCIEn UDRIEn RXENn TXENn UCSZn2 RXB8n TXB8n
➫ RXCIEn : à 1 pour permettre le déclenchement d’une interruption lors d’une réception
terminée
➫ TCCIEn : à 1 pour permettre le déclenchement d’une interruption lors d’une émission terminée
➫ UDRIEn : à 1 pour permettre le déclenchement d’une interruption lorsque l’émetteur est
prêt à émettre
➫ RXENn : à 1 pour autoriser la réception
➫ TXENn : à 1 pour autoriser l’émission
➫ UCSZn2 : à 1 pour indiquer une trame de 9 bits, à 0 si 8 bits ou moins
➫ RXB8n : 9eme à la réception si utilisation d’une trame de 9 bits. A lire avant UDRn
➫ TXB8n : 9eme à l’émission si utilisation d’une trame de 9 bits. A écrire avant UDRn
UCSRnC, USARTn Control and Status Register C
bit
7
6
5
4
3
2
1
UCSRnC 0 UMSELn UPMn USBSn UCSZn
0
UCPOLn
➬ UMSELn : à 0 pour communication asynchrone, à 1 pour synchrone
UPMn Bit de parité
00
désactivé
➬ UPMn :
10
pair
11
impair
➬ USBSn : à 0 pour une trame à 1 bit Stop, à 1 pour 2 bits Stop
UCSZn
Taille des données
00
5
➬ UCSZn :
01
6
10
7
11
8 ou 9 selon UCSZn2 du registre USCRnB
➬ UCPOLn : inutile en mode asynchrone, peu utile en mode synchrone, à mettre à 0
40
ANNEXE C. AIDE À LA PROGRAMMATION
UBRRnH
UBRRnL
⇒ forment par concaténation UBRRn=65536*UBRRnH+UBRRnL
UBRRn, USARTn Baud Rate Register : valeur maximale = 0x0FFF
Calcul du débit
Calcul de
Mode
en bits/s (bps)
UBRRn
Asynchrone
U BRRn =
f
16(U BRRn + 1)
BAU D =
f
−1
16 ∗ BAU D
Synchrone
U BRRn =
f
2(U BRRn + 1)
BAU D =
f
−1
2 ∗ BAU D
Exemples de configuration Communication asynchrone, trame de 8 bits avec un bit de
parité pair, 9600 bps pour un microcontrôleur cadencé à 16MHz :
UCSRnC = 0x26 ; UBRRnL = 0x67 ; UBRRnH = 0x00 ;
– Emetteur, sans interruption : UCSRnB = 0x08 ;
– Emetteur, avec interruption : UCSRnB = 0x48 ;
– Récepteur, sans interruption : UCSRnB = 0x10 ;
– Récepteur, avec interruption : UCSRnB = 0x90 ;
Code C pour une trame de 8 bits ou moins, sans gestion d’interruptions
– Emission :
while ( ! ( UCSRnA & (1<<UDREn ) ) ) ;
/∗ a t t e n t e de l i b e r a t i o n de l ’ e m e t t e u r ∗/
UDRn = d o n n e e a e n v o y e e r ;
– Reception :
while ( ! ( UCSRnA & (1<<RXCn ) ) ) ;
/∗ a t t e n t e de r e c e p t i o n de donnees ∗/
d o n n e e r e c u e = UDRn;
Adresses Internet utiles
resel.enst-bretagne.fr/club/em6 Pour suivre l’évolution du robot de l’ENST Bretagne et
obtenir une verion plus récente de ce tutorial.
resel.enst-bretagne.fr/club/em6/site 2002/index.php3?corps=doc Pour les linuxiens, un
tutorial sur la programmation des AVR avec AVR GCC.
www.atmel.com Le fabricant des microcontrôleurs AVR.
www.avrfreaks.com Simplement le meilleur site dédié aux microcontrôleurs AVR, si vous avez
des questions, allez-y sans tarder.
www.atmel.com/dyn/resources/prod documents/doc2467.pdf C’est ici que se trouve la datasheet de l’ATmega128.
www.atmel.com/dyn/products/tools card.asp?tool id=2726 La datasheet du câble de programmation AVR ISP.
www.imagecraft.com Pour obtenir une version de démonstration du compilateur utilisé dans ce
tutorial.
www.atmel.com/dyn/products/tools card.asp?tool id=2725
AVR Studio 4.
Le programmateur/simulateur
home.nordnet.fr/∼fthobois/les cms.htm Un site pour vous aider à souder des composants
CMS.
41
42
ADRESSES INTERNET UTILES
Index
C (programmation en)
.c et .h, 15
#define, 14
#include, 12
#pragma, 15
asm("..."), 16
et assembleur, 16
for, 12
guillemets, 12
i++, 12
int, 13
interruption, 15
macro, 14
main, 12
paramètres d’une fonction, 12
point-virgule, 12
void, 12
while, 13
Comparateur analogique, 8
Compilateurs, 11
Convertion analogique/numérique, 7
Reexécution de programme, 8
Registre, 6
DDRx, 6
OCRn, 6
PINx, 6
PORTx, 6
TCNTn, 6
Reset
pour la programmation, 25
Watchdog Timer, 8
Simulation, 19
assembleur, 22
breakpoint, 21
configuration, 19
déroulement du programme, 21
StopWatch, 21
Workspace, 20
Sleep Mode, 8
sortie, 8
Timer/Counter, 6
16 bits, 6
Economie d’énergie, voir Sleep Mode
Entrée/sortie, 5
USART, 7
Interruption
en assembleur, 9
en C, 15
généralités, 9
Timer/Counter, 6
Watchdog Timer, 8
Mise en pratique, 23
alimentation, 23
configurer le microcontrôleur, 27
horloge, 23
implémentation du programme dans le
microcontrôleur, 27
port de programmation, 24
quartz, 23
SCK, MISO, MOSI, PDI, PDO, 25
soudure des composants, 26
Mode d’économie d’énergie, voir Sleep Mode
Port, 5
PWM, 6
43