AVR MCU Programming
AVR MCU Programming
AVR MCU Programming
(Cas de ATmega328)
Introduction
• ATmega328 est un microcontrôleur AVR 8 bits et 28 broches, fabriqué par Microchip, suit
une Architecture RISC et possède:
une mémoire programme de type flash de 32 Ko.
une mémoire données EEPROM de 1 Ko et sa mémoire SRAM de 2 Ko.
un port C (PC0 – PC5) pour les opérations ADC et 2 autres ports B et D, comme ports
d’entrée-sortie numériques
32 registres de travail d'accès rapide pour l'ALU
Fréquence d'horloge : 16 Mhz (20 Mhz maxi tolérée)
Périphériques internes
6 convertisseur Analogique/Numérique 10 bits, comparateur analogique
1 timer 16 bits (T1), 2 timers 8 bits(T0,T2)
6 canaux PWM, 1 chien de garde (watchdog)
SPI, USART, TWI (=I2C)
• Il fonctionne entre 3,3V et 5,5V.
• Il est le cœur de l’Arduino Uno et utilisé dans les applications de systèmes intégrés.
Brochages: PDIP
Brochages: TQFP
Architecture interne (voir doc ATmega328P)
Architecture interne du CPU (voir doc ATmega328P)
Schéma Arduino Uno
Atmega328 et Arduino Uno
Atmega328 et mémoire
Langage C AVR
Langage C AVR: Types de données
• Les types du C AVR sont:
unsigned char a; //8 bits
signed char b; //8 bits
unsigned int c; //16 bits
signed int d; //16 bits
long e; //32 bits
float f; //32 bits
• Mais il est recommandé d’utiliser les types prédéfinis du compilateur C (du GNU):
uint8_t a; //8 bits et int8_t b; //8 bits
uint16_t c; //16 bits et int16_t d; //16 bits
int32_t e; //32 bits et uint32_t e;
float f;
Langage C AVR: Opérateurs logiques
• OR: | • AND: &
1010 1010
| 1100 & 1100
------- --------
1110 1000
Langage C AVR: Opérateurs logiques
• XOR: ^ • NOT: ~
1010 ~ 1100
^ 1100 --------
------- 0011
0110
Langage C AVR: Opérateurs logiques
• Décalage à gauche (<<): des zéros sont ajoutés à droite
0b00001110 << 2 = 0b00111000
2. Activer ADC dans le registre ADCSRA, sélectionner la vitesse de conversion avec ADPS2
3. Choisir la tension de référence ADC avec REFS1: REFS0 dans le registre ADMUX
6. Quand le bit ADIF=1, lire les registres ADCL et ADCH pour obtenir la sortie numérique.
(NB: lire ADCL puis ADCH)
CAN: Etapes de programmation
CAN: Mesure de la temperature avec LM35D
CAN: Mesure de la temperature avec LM35D (Vref =5V)
Temp (°C) Vin (mV) Vout ADC
0 0 0 00 0000 0000
1 10 2 00 0000 0010
2 20 4 00 0000 0100
3 30 6 00 0000 0110
10 100 20 00 0001 0100
20 200 40 00 0010 1000
30 300 61 00 0011 1101
40 400 82 00 0101 0010
50 500 102 00 0110 0110
60 600 122 00 0111 1010
70 700 143 00 1000 1111
100 1000 205 00 1100 1101
CAN: Mesure de la temperature avec LM35D
CAN: Mesure de la temperature avec LM35D (Vref =5V)
CAN: Mesure de la temperature avec LM35D (Vref =5V)
Interruption
Présentation
Un seul MCU peut servir plusieurs périphériques
Quand un périphérique a besoin d’un service auprès du MCU, il va le notifier par l’envoi
d’un signal. A son tour le MCU arrête ce qu’il a traité et rend service au périphérique qu’il
l’a notifié.
Le programme associé à cette interruption s’appelle ISR ou Interrupt Service Routine
dont la syntaxe est la suivante:
ISR (interruptSource_vect){
//code
}
A chaque interruption, il y a un emplacement mémoire fixe qui contient l’adresse de ISR
Présentation
Les causes d'interruptions sont liées à des niveaux ou à des changements d'états des
broches PD2 (INT0) ou PD3 (INT1) du microcontrôleur et ces broches doivent être
configurées en entrée .
Ces broches sont configurables pour déclencher les interruptions (n° 2 et 3 dans
les vecteurs INT0_vect/INT1_vect).
Les causes possibles (registre EICRA ) sont:
Détection d'un niveau 0 sur l'entrée (low level),
Front négatif ou positif (falling/rising edge).
Changement d'état quelconque (any logical change)
Registres concernés
Choix de la cause d'interruption - écrire dans le registre EICRA:
les bits EICRA.1 - EICRA.0 pour INT0 (ISC01 - ISC00)
les bits EICRA.3 - EICRA.2 pour INT1 (ISC11 - ISC10)
Registres concernés
Activation des interruptions INT0/INT1: bit SREG.7 à 1 et mise à 1 de EIMSK.0 et EIMSK.1
Registres concernés
Flags internes: lorsqu'une cause d'IT est détectée, un flag interne de EIFR est positionné.
Mettre à 0 flag dans registre EIFR : les bits du registre EIFR indiquent (flags) qu'une
demande d'interruption INT0/INT1 est en attente
un flag à 1 dans ce registre signifie que la cause d'IT a été détectée mais que la routine
ISR n'est pas encore exécutée.
Si l'on souhaite annuler une demande d'IT (avant son exécution), on doit remettre ces
flags à 0.
Pour annuler une demande (clear flag), il faut écrire 1 (et pas 0) dans le registre EIFR pour
le flag concerné
Vecteurs d’interruption
Vecteurs d’interruption
Exemple
Exemple
Exemple
Communication série
Communications série:
AVR Atmega possède l’interface USART (Universal Synchronous and
Asyncronous Receiver and Transmitter ) pour la communication série avec d’autres
périphériques comme Ordinateurs, modules GSM et GPS, etc
Les données envoyées ou reçues ont la structure suivante: 1 bit START (logique 0) +
données de 8 bits + 1 bit STOP (logique 1)
Communications série:
Exemple: Envoi de 2 nombres 9 et 10
La vitesse de transmission connue sous le nom Baud rate est la vitesse de la ligne série.
dont les standards sont: 9600, 1200, 2400, 4800, 19200, 115200 bps.
Communications série:
Dans USART, nous n'avons besoin que des fils Tx (transmission), Rx (réception) et GND.
Avec un nouveau PC et des ordinateurs portables, on doit utiliser le port série vers le
connecteur USB. Il existe de différents connecteurs série vers USB disponibles, par
exemple CP2102, FT232RL, CH340, etc.
Communications série: Vitesse de transmission
Communications série:
Communications série:
Pour la programmation, on aura besoin de comprendre les registres de base utilisés en
USART. (voir page 176 de la datasheet)
Communications série:
Initialisation
Communications série:
Recevoir un caractère
Communications série:
Transmettre un caractère
Communications série:
Transmettre une chaîne de caractères
Communications série:
Communications série: SPI
AVR Atmega possède l’interface SPI (Serial Peripheral Interface) pour la communication
série avec d’autres périphériques.
Le protocole SPI est synchrone : une horloge synchronise l'échange de données.
Dans tout échange on définit un Maître(Master) qui réalise l'horloge et un ou plusieurs
Esclaves (Slaves).
L'esclave est choisi avec une entrée spéciale appelée SS (Slave Select).
Communications série: SPI
Initialisation du Master
Communications série: SPI
Transmettre un octet à partir du Master
Communications série: SPI
Recevoir un octet à partir du Master
Timers/Compteurs
Introduction
C'est un périphérique matériel destiné à compter :
soit des évènements extérieurs, potentiellement non-périodiques : c'est sa fonction
de compteur ;
soit des évènements internes périodiques (tops d'horloge) : c'est sa fonction
de temporisateur, de mesure le temps.
Tant qu'il est « activé », un timer compte (c'est sa fonction) : il s'incrémente chaque fois
qu'il détecte un nouvel évènement.
En cas de débordement, il reprend à 0 (sauf mode de fonctionnement particulier).
Un timer sert généralement à :
mesurer des durées
déclencher périodiquement des routines d'interruptions
générer des signaux MLI (Modulation à Largeur d’Impultion)
Introduction
Composition
• Des broches :
• d'entrée : pour compter ses changements d'états ( ce sont les « évènements externes
» que le timer peut compter)
• de sortie : pour signaler que le compteur a atteint une valeur particulière ;
• Un sélecteur : sélectionne l'entrée dont les changements d'états (évènements) seront
comptés, en général, l'horloge interne ou une broche externe
• Un prédiviseur :
• dans le cas où le compteur est connecté à l'horloge, il est possible de ralentir le
comptage en ne comptant qu‘un top d'horloge sur n (prédiviseur). Il est choisi parmi
un ensemble de puissances de 2, par exemple : {1, 16, 64, 256} ;
Composition
• Un registre de comptage : c'est lui qui stocke la valeur de comptage
• Des unités de comparaison, chacune munie d'un registre de comparaison : ces registres
contiennent une valeur destinée à être comparée à celle du compteur ; dans le but de
changer l'état d'une broche de sortie de l'unité de comparaison, ou de déclencher une
interruption ;
• Des registres de contrôle : pour configurer son mode de fonctionnement.
Composition: Timer 0
Mode de fonctionnement
Mode de fonctionnement: Normal
Le timer compte tout le temps, c'est-à-dire qu'il s'incrémente à chaque évènement
détecté, qui peuvent être au choix :
les tops d'horloge prédivisés, en mode temporisateur,
les changements d'état de sa broche d'entrée, en mode compteur ;
il revient à 0 après un débordement (overflow).
il peut déclencher une interruption de débordement
Lorsque le timer compte les tops d'horloge prédivisés (fonction temporisateur), la
durée (période) de ses cycles est définie par : T_cycle_normal = prédiviseur/fcpu * 256
Mode de fonctionnement: CTC
C'est le mode « Remise à zéro sur comparaison ou CTC (Clear Timer on Compare match) »
Le domaine de comptage est raccourci : le timer évolue de 0 à la valeur du registre de
comparaison A, puis revient à 0
Le test de comparaison peut aussi déclencher (outre le reset du compteur) :
une interruption de comparaison A (différente de celle de débordement et de celle
de comparaison B)
un changement d'état de la broche de sortie OC0A (Timer 0)
Dans ce mode ( + fonction temporisateur), la durée du cycle est :
T_cycle_CTC = préd./fcpu * (OCR0A+1)
Mode CTC: Génération d’un signal carré
La broche de sortie OC0A (resp. OCOB) (= broche du timer 0 associée à la comparaison A)
peut s'inverser à chaque comparaison.
La période du signal carré est le double de celle du cycle de comptage :
T_signal_sortie_CTC = 2*préd./fcpu * (OCR0A+1)
Registre du timer0
• TCCR0A: Registre de contrôle A.
Registre du timer0
• TCCR0A: Registre de contrôle A.
Registre du timer0
• TCCR0B: Registre de contrôle B.
Registre du timer0
• TCNT0: Registre de comptage (8 bits). on veillera à l'initialiser à 0 si l'on souhaite que son
premier cycle soit complet.
Registre du timer0
• OCR0A/OCR0B: Registres de sortie de comparaison
Registre du timer0
• TIMSK0 : Registre d’interruption
Registre du timer2
• TCCR2A : Registre de contrôle A
Registre du timer2
• TCCR2B : Registre de contrôle B
Mode normal
Chaque débordement du Timer conduise à une interruption.
Exemple: si l'horloge est à 16MHz, 16/1024=15625 Hz soit 15625 cycles d’horloge par
seconde. Donc, il faut compter 15625 cycles pour faire une seconde.
Nombre de débordement avec Timer à 8 bits: 15625/256 = 61 pour faire une seconde.
OCR0A=250
Prescaler TCNT0
CPU Clock Timer/Counter
(16 MHz/64 =250 ==
16 MHz (TCNT0)
KHz) OCR0A?
𝑇𝑜𝑛 𝑇𝑜𝑛
Duty cycle (%) = ∗ 100 = 𝑃𝑒𝑟𝑖𝑜𝑑 ∗ 100
𝑇𝑜𝑛+𝑇𝑜𝑓𝑓
Introduction
Exemple: une tension de 5 V en PWM de rapport de cycle de 50% donne en sortie une
tension de 5*0,50 = 2,5 V.
Sorties PWM
Sortie PWM sur une broche quelconque
Sortie PWM sur une broche quelconque
Sorties PWM avec Timer: OCnx
Choix du mode de fonctionnement (ex: Timer 2)
Mode Fast PWM
Mode Fast PWM: inversé
Pour définir le rapport de cycle, il faut charger une valeur entre 0 (0%) et 255 (100%)
pour un Timer 8 bits dans le registre OCRnx.
Mode Fast PWM: non inversé
Mode PWM: Fast PWM
Exemple: Contrôler la luminosité des LED attachée au port PD6 à l'aide de Fast
PWM.
Mode PWM: Fast PWM
Mode PWM: Fast PWM
Mode Phase Correct PWM
Mode Phase Correct PWM: non inversé
• Pour définir Phase Correct PWM, il suffit de définir les registres TCCRnx et OCRnx. On
peut également définir la forme d'onde de sortie comme inversée ou non inversée.
Mode Phase Correct PWM: inversé
Mode Phase Correct PWM: non inversé
Mode Phase Correct PWM: non inversé
Mode Phase Correct PWM avec interruption
Mode Phase Correct PWM avec interruption
TPs: interfaçages avec les périphériques
Références
https://www.tala-informatique.fr/wiki/index.php/Atmega328_registers
https://www-lisic.univ-littoral.fr/~hebert/microcontroleur
https://www.silicium628.fr/article_i.php?id=5
https://microcontrollerslab.com/avr-microcontroller-tutorials/
https://docs.arduino.cc/tutorials/generic/secrets-of-arduino-pwm
https://www.tinkercad.com
Atmega328P datasheet