Professional Documents
Culture Documents
L2. CPAB - ATmega328
L2. CPAB - ATmega328
1. Microcontrolerul ATmega-328
1.1. Caracteristici generale
ATmega-328 este un microcontroller de tip RISC (Reduced Instruction Set) pe 8 biți din familia AVR
(Advanced Virtual RISC) a firmei Atmel (din 2016 Microchip). Este un microcontroller cu performanțe
bune ajungând sa execute instrucțiuni într-un singur ciclu de clock, atingând randamente de 1MIPS
(Millions of instructions per second) per MHz. Este optimizat pentru consum redus de putere raportat
la viteza de procesare și poate fi folosit în general în sisteme de tip “embedded”.
În Tabelul I sunt extrase cele mai importante resurse ale microcontrolerului ATmega328:
Tabelul I. Principalele resurse ale microcontrolerului ATmega328
Caracteristici ATmega328
Număr Pini 28/32
Încapsulări (4) 28-pin PDIP
32-lead TQFP
28-pad QFN/MLF
32-pad QFN/MLF
CPU RISC 8-Bit AVR
Frecvență maximă de operare (oscilator) 20 MHz
Performanță 20 MIPS la 20 MHz
Tensiune de operare De la 1.8 V la 5.5 V
Memorie de Program 32KB de tip Flash
Memorie SRAM 2048 Bytes (2KB)
Memorie EEPROM 1024 Bytes (1KB)
Rezoluție ADC 10-Bit
Număr de canale ADC 6/8
Pini PWM 6
Întreruperi externe 2
Timere (3) 8-Bit x 2 & 16-Bit x 1
Watchdog Timer Da
Comparator 1
USI (Universal Serial Interface) Da
SPI (Serial Peripheral Interface) Da
I2C Da
Reset Da
Temperatură de operare De la -40 C până la +85 C
3. Portul B este format din pinii de la PB0 la PB7. Port B este un port bidirecțional (I/O) pe 8 biți cu
rezistențe interne de agățare (rezistențe de tip pull-up).
4. Portul C este un port bidirecțional (I/O) pe 7 biți cu rezistențe interne de agățare (rezistențe de tip
pull-up). Doar ca I/O sunt folosiți pinii de la PC0 la PC6.
5. PC6/RESET este un pin de I/O daca siguranța RSTDISBL este programată și este transformat în pinul
de RESET dacă siguranța RSTDISBL nu este programată.
6. Portul D este format din pinii de la PD0 la PD7. Port D este un port bidirecțional (I/O) pe 8 biți cu
rezistențe interne de agățare (rezistențe de tip pull-up).
7. AVCC este pinul unde se conectează sursa de tensiune pentru convertorul analog digital (ADC).
Trebuie conectat extern la VCC chiar daca ADC-ul nu este folosit.
9. ADC[6:7] reprezintă intrările 6 și 7 pentru ADC în cazul încapsulărilor TQFP și VFQFN. Acești pini sunt
alimentați de sursa de tensiune pentru partea analogică. Pinii PC[0:5] pot fi configurați ca celelalte 6
intrări pentru ADC.
În tabelul III este prezentată numerotarea pinilor microcontrolerului ATmega328 în ordine crescătoare
conform Figurii 3.
Tabelul III. Numerotarea pinilor microcontrolerului ATmega328
Tabela de regiștrii cu acces rapid conține 32 regiștri de lucru de uz general pe 8 biți cu timp de acces
unic de un ciclu de ceas. Aceasta permite funcționarea unității de logică aritmetică (ALU) pe un ciclu
de ceas. Într-o operație tipică ALU, doi operanzi sunt extrași din tabela de regiștri, operația este
executată, iar rezultatul este stocat din nou în tabela de regiștri într-un ciclu de ceas.
ALU acceptă operații aritmetice și logice între registre sau între o constantă și un registru. Operațiunile
cu un singur registru pot fi, de asemenea, executate în ALU. După o operație aritmetică, Registrul de
Stare (STATUS Register) este actualizat pentru a reflecta informațiile despre rezultatul operației.
Stiva este utilizată în principal pentru stocarea datelor temporare, pentru stocarea variabilelor locale
și pentru stocarea adreselor de retur după întreruperi și apeluri de subrutină. Stiva este implementată
crescând de la locații de memorie mai mari la locații de memorie mai mici. Registrul indicator de Stivă
(Stack Pointer Register ) indică întotdeauna partea de sus a Stivei. Stiva este alocată efectiv în SRAM-
ul de date generale și, în consecință, dimensiunea acesteia este limitată doar de dimensiunea totală a
SRAM-ului și de modul de utilizare al acestuia.
Registrele R26:R31 au unele funcții adăugate pentru utilizarea lor în scop general. Aceste registre sunt
indicatoare de adresă pe 16 biți pentru adresarea indirectă a spațiului de date.
1.3.3. Memoria microcontrolerului ATmega328
Arhitectura AVR are două spații de memorie principale (arhitectură Harvard):
ATmega328 conține 32 Kbytes memorie de tip Flash reprogramabilă pentru stocarea programului.
Întrucât toate instrucțiunile AVR au o lungime de 16 sau 32 de biți, memoria Flash este organizată în
16K x 16. Pentru securitate software, memoria de program de tip Flash este împărțit în două secțiuni,
secțiunea de program de aplicații și secțiunea de program de Boot. Ambele secțiuni au biți de blocare
dedicați pentru protecția la scriere și citire / scriere.
Memoria Flash rezistă la cel puțin 10.000 de cicluri de scriere / ștergere. Este o memorie de citire
programabilă (Programmable Read Only Memory - ROM) non volatilă. Contorul de program al
microcontrolerului ATmega328 (PC) are o lungime de 14 biți, adresându-se astfel locațiile de memorie
ale programului 16K.
În memoria SRAM, cele 2304 locații de memorie de date adresează tabela de regiștri cu uz general
(primele 32 de locații), memoria de I/O standard (următoarele 64 de locații), memoria de I/O extinsă
(următoarele 64 de locații ) și datele interne din SRAM (ultimele 2K locații). Memoria SRAM este
volatilă și se șterge după întreruperea sursei de tensiune. Harta memoriei este prezentată în Fig. 9.
void setup() {
//codul scris aici rulează o singura data
}
void loop() {
//codul scris aici rulează tot timpul
}
Astfel, în rutina "setup" se va scrie de obicei cod de inițializare, iar in rutina "loop" se va scrie
partea principală a programului.
1.4.4. Exemplu: Arduino Blink
Ca exemplu de implementare de cod, vom folosi un led montat din fabricație pe placa. Placa
Arduino are din construcție un led conectat la pinul digital 13. Acest led se aprinde atunci când pinul
13 digital este pus în HIGH (din programul scris pe Arduino) se stinge atunci când pinul 13 este pus in
LOW (HIGH = VCC: 5V, LOW = GND). Codul se poate încarcă și din exemplele pe care le pune la dispoziție
interfața Arduino (File -> Examples -> Basics -> Blink).
void setup() {
pinMode(13, OUTPUT);
}
void loop() {
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);
}
Dacă se încarcă acest program pe placa Arduino și se urmărește led-ul conectat la pinul 13, se
va observa ca el clipește o dată pe secundă.
În secțiunea "setup" avem o singură instrucțiune, care declară că pinul 13 digital va fi folosit în
continuare pentru a controla un dispozitiv (OUTPUT) (daca am fi vrut să citim informație din mediu –
sa atașăm un senzor la el – am fi scris "pinMode(13, INPUT)"). Aceasta instrucțiune se execută o singură
dată.
Urmează secțiunea "loop", care aprinde led-ul conectat la pinul 13 ("digitalWrite(13, HIGH)"),
așteaptă o secunda, îl stinge și iarăși așteaptă o secundă. Instrucțiunile din secțiunea "loop" se execută
ciclic, astfel ca imediat după ce s-a terminat un ciclu, led-ul iarăși se aprinde, apoi iarăși se stinge și tot
așa până când tăiem alimentarea plăcii.
Pentru aprinderea Led-ului atașat din fabricație la placa de dezvoltare Arduino la pinul 13, va
trebui programat pinul corespunzător microcontrolerului (PB5) ca sursă de tensiune (1 logic). Astfel,
trebuie setați 2 regiștri ai microcontrolerului pentru programarea pinului PB5 ca pin de ieșire cu
valoarea logică 1.
Tabelul IV. Tabela cu regiștrii de configurare a porturilor
Pentru setarea direcției unui pin ce aparține portului B se folosește registrul DDRB:
DDRB = 0bB7B6B5B4B3B2B1B0
unde B0-B7 sunt valorile asignate pinilor microcontrolerului în registrul DDRB.
DDRB = 0b00100000.
Pentru setarea stării unui pin ce aparține portului B se folosește registrul PORTB:
PORTB = 0bB7B6B5B4B3B2B1B0
unde B0-B7 sunt valorile asignate pinilor microcontrolerului în registrul PORTB.
#include <avr/io.h> // se include biblioteca ce conține definiția termenilor utilizați (de ex. DDRD)
#include <util/delay.h> // conține definiția funcției de așteptare
void setup() {
DDRB = 0b00100000; // Setare Pin PB5 ca pin de ieșire
PORTB = 0b00000000; // Stinge LED-ul
}
void loop() {
PORTB = 0b00100000; //Aprinde LED-ul
_delay_ms(1000); // Întârziere de 1000ms
PORTB = 0b00000000; //Stinge LED-ul
_delay_ms(1000); // Întârziere de 1000ms
}
Exerciții:
1. Realizați un circuit prin care să modificați starea unui led conectat la pinul 7 al plăcii de dezvoltare
Arduino la un interval de 2s. Valorile se vor implementa cu numere în baza 16.
2. Să se realizeze un program care să simuleze funcționarea unui semafor în mod continuu după
secvența: verde (aprins 3s), portocaliu (aprins 0,5s), roșu (aprins 2s). Ledul verde se va conecta la
pinul 2, ledul portocaliu la pinul 4 iar ledul roșu la pinul 8.