Vous êtes sur la page 1sur 121

Microcontrôleur AVR

(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

• Décalage à droite (>>): des zéros sont ajoutés à gauche


0b00001110 >> 3 = 0b00000001
Langage C AVR: Opérations sur les bits
• Pour positionner un bit particulier en C, on utilise une valeur définie qui va servir à l'aide
d'un « opérateur ou » ou un « opérateur et » à positionner des bits individuels. Cette
valeur s’appelle masque.
• Les opérations logiques effectuées sont des opérations bit à bit :
& (et) logique bit à bit en C: pour positionner un ou plusieurs 0
| (ou) logique bit à bit en C: pour positionner un ou plusieurs 1
• Les masques seront exprimés en hexadécimal.
Langage C AVR: Opérations sur les bits
• Pour positionner un ou plusieurs bits à 1, on écrit un ou plusieurs des 1 aux places
concernées et on complète par des 0. Ceci formera le masque binaire qu’il faudra
transformer en hexadécimal et utiliser avec un opérateur OU.
• Pour positionner un ou plusieurs bits à 0, on écrit un ou plusieurs des 0 aux places
concernées et on complète par des 1. Ceci formera le masque binaire qu’il faudra
transformer en hexadécimal et utiliser avec un opérateur ET.
• Un schéma de principe est le suivant
Langage C AVR: Opérations sur les bits (macros)
• Pour modifier un ou plusieurs bits à 1, sans modifier l'état des autres registres, on
utiliser l’opérateur OU (|)
Modifier un bit à 1
#define bit_set(var,bitno) var |= (1 << bitno)
#unsigned char x=0b0001;
bit_set(x,3); //x=0b1001;
bit_set(PORTB,3); //PORTB |= (1<<PB3);
Modifier plusieurs bits à 1
#define bits_set(var,mask) var |= mask
unsigned char x=0b1010;
bits_set(x,0b0101); //x=0b1111
bits_set(PORTB,0b00000101); // PORTB |= 0b00000101;
Langage C AVR: Opérations sur les bits (macros)
• Pour modifier un ou plusieurs bits à 0, sans modifier l'état des autres registres, on
utilise l’opérateur ET (&)
Modifier un bit à 0
#define bit_clear(var,bitno) var &= ~(1 << bitno)
#unsigned char x=0b1001;
bit_clear(x,0); //x=0b1000;
bit_clear(PORTB,0); // PORTB &= ~(1 << PB0);
Modifier plusieurs bits à 0
#define bits_clear(var,mask) var &= ~mask
unsigned char x=0b1010;
bits_clear(x,0b0011); //x=0b0010
NB: On pourra affecter directement une valeur Hexadécimale ou binaire, si on veut
modifier l’état des autres registres.
Langage C AVR: Opérations sur les bits
• Pour tester si un bit est 1 ou 0, on utilise un masque en face du bit que l’on veut tester.
On construit ensuite une expression booléenne pour tester le résultat en le comparant à
une valeur prédéfinie
Exemple
if ((Reg & 0x40) == 0x40) {
//vraie si bit B6 à 1 ...
}

if ((Reg & 0x08) == 0x00) {


//vraie si bit B3 à 0 ...
}
Langage C AVR: Opérations sur les bits
• Pour lire l’état d’une broche, on pourra tester si un bit est 1 ou 0, ou retirer l’état des
autres broches sans modifier son état.
• Exemple: Lire l’état de la broche 6 du port B
Langage C AVR: Opérations sur les bits
• Pour basculer l'état d'un registre de 0 à 1 ou inversement, sans modifier l'état des
autres registres, nous allons utiliser l'opérateur XOR.
• Pour basculer seulement la broche 5 du port B, on pourra utiliser l’une des 3 instructions
suivantes:
PORTB ^= 0b00100000;
PORTB ^= (1<<5);
PORTB ^= 0x20;
Ports d’E/S
• Le nombre de PORTs disponibles sur les AVR dépend de la série.
• A chaque port, on associe 3 registres: PORTx, DDRx et PINx:
DDRx(Data Direction Register): sert à configurer la direction de chaque broche du port:
Entrée (Input) /Sortie( Output) (ou 0/1)
PORTx (Port Output Register Thing): sert à écrire des données (sortie)
PINx (Port INput): sert à lire des données (entrée)
Ports d’E/S
• Extrait de la documentation pour le port B
Ports d’E/S
• Exemple 1: Configuration des ports B (sortie) et D (entrée)

• Exemple 2: Ecriture de la valeur 0 sur la broche 6 du port B


Les ports d’E/S
• Exemple 3: Lecture d’une valeur de la broche 3 du port D
Programmation AVR
Outils et environnement de développement
• Pour programmer AVR MCU, il faut:
Un programmateur: exemple, USB ASP
Un IDE et un compilateur: Microchip Studio
Outils de simulation: Proteus, SimulIDE, etc
Mesure de performances
• Le code utilisant les registres (à droite) est non seulement plus léger mais également
plus rapide que celui utilisant les bibliothèques Arduino.
Structure d’un programme AVR
E/S numérique:
Exemple 1 : Allumer toutes les LEDs (D1, D2, D3) du port D puis les éteindre.
E/S numérique:
.
E/S numérique:
Exemple 2 : Allumer quelques LED lors d’un appui sur un bouton.
E/S numérique
Conversion Analogique
Numérique
Conversion Analogique-Numérique:
• Un CAN, ou convertisseur analogique-numérique, permet de convertir une tension
analogique en une valeur numérique qui peut être utilisée par un microcontrôleur.
• Il existe de nombreuses sources de signaux analogiques que l'on pourrait souhaiter
mesurer, comme ceux des capteurs analogiques qui mesurent:
la température,
l'intensité lumineuse,
la distance,
la position et la force,
etc
Conversion analogique-numérique:
• ATmega328 dispose d'une approximation successive de
10 bits ADC (une sortie numérique de 0 à 1023).
• Il possède 6 canaux ADC au Port C.
• Une tension de référence est nécessaire pour réaliser
une conversion car celle-ci est essentiellement basée
sur une comparaison:
En interne, elle est de 1,1 V dans les versions
ATMagaX8/XX8 mais de 2,56 V dans les
ATMega8/16/32.
En externe, elle peut utiliser les broches AREF ou VREF.
VREF permet d’utiliser Vcc comme référence.
• ADC peut également être configuré pour fonctionner en
continu (mode de fonctionnement libre) ou pour
effectuer une seule conversion.
Conversion analogique-numérique:
• La formule permettant de calculer la conversion est selon la doc(page 261):
𝑉𝑖𝑛∗1024 𝑉𝑖𝑛 𝑉𝑟𝑒𝑓
𝐴𝐷𝐶 = = où 𝑠𝑡𝑒𝑝 =
𝑉𝑟𝑒𝑓 𝑠𝑡𝑒𝑝 1024
• ADC est un nombre entier sur 10 bits, Vin est la tension d'entrée présente sur le
convertisseur, Vref est la tension de référence.
Conversion analogique-numérique:
• Les principaux registres concernés sont:
ADCH: contient les octets les plus significatifs de données numériques

ADCL: contient les octets les moins significatifs de données numériques

ADMUX: Registre de sélection ADC Multiplexer


ADCSRA: Registre de contrôle et d’état ADC
Conversion analogique-numérique:
Configuration: Registre ADMUX
• Registre ADMUX (Voir page 262 de la documentation ATmega328P)

Bit 7: 6 – REFS1 : 0 (Reference Selection Bits): Sélection de la tension de référence pour


ADC
Configuration: Registre ADMUX
Bit 5 – ADLAR: 10 bits de sortie
Configuration: Registre ADCSRA
• Registre ADCSRA: registre de contrôle et d’état

Bit 7 – ADEN: ADC Enable

• ADEN = 1: ADC activé

• ADEN = 0: ADC désactivé


CAN: Etapes de programmation
1. Configurer le canal ADC broche comme entrée

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

4. Commencer la conversion en configurant le bit ADSC dans ADCSRA.

5. Attendre la fin de conversion en surveillant le bit ADIF dans le registre ADCSRA.

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.

CPU Clock Prescaler Timer/Counter


16 MHz (16 MHz/1024 =15625 Hz) (TCNT0)

Sa valeur est incrémentée à


15625 Hz c-à-d chaque incr
prend 1/15625 s = 64 us
Mode normal
 On souhaite que chaque débordement du Timer 0 conduise à une interruption.
Mode CTC
 A chaque fois que TCNTn==OCRnA, TCNTn est remis à 0 et l'égalité déclenche une
interruption.

OCR0A=250

Prescaler TCNT0
CPU Clock Timer/Counter
(16 MHz/64 =250 ==
16 MHz (TCNT0)
KHz) OCR0A?

Sa valeur est incrémentée à Débordement si TCNT0 == OCR0A


250 KHz c-à-d chaque incr. Donc interruption à chaque
prend 1/250000 s = 0,004 s 250 x 0,004 = 1 ms
Mode CTC
 On souhaite que chaque débordement du Timer 2 conduise à une interruption.
Modulation à Largeur d’Impulsion
(MLI)
Introduction
 La MLI ou PWM(Pulse Width Modulation) est une technique utilisée en électronique
pour générer un signal de sortie entre 0 et 5 V. Le signal bascule rapidement entre les
niveaux HIGH et LOW, et la tension résultante se situe entre ces deux valeurs.
 La fréquence et période de ce signal sont constantes, mais la longueur des demi-
périodes change
 Le rapport entre la durée pendant laquelle la sortie est au niveau HIGH et la
période du signal détermine la brillance apparente d’une LED par exemple. Ce rapport est
appelé: rapport cyclique (ou duty cycle).
 En PWM, plus le rapport cyclique est élevé, plus la tension de sortie est élevée.

𝑇𝑜𝑛 𝑇𝑜𝑛
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

Vous aimerez peut-être aussi