Capitole utile din Datasheet ATmega328P
Un microcontroller(µC) este o componentă electronică care integrează un microprocesor şi dispozitive periferice, punându-se accent pe un cost de producție mic și un consum energetic redus, altfel spus pe optimizarea aplicației. Principala diferenţă dintre un microcontroller (µC) şi un microprocesor (µP) o constituie faptul că un µC integrează atât unitatea de procesare cât și memorie de program, memorie de date, interfeţe de intrare-ieşire și periferice.
Un µC operează la frecvenţe reduse, în general la zeci sau sute de MHz. Cu toate acestea, microcontroller-ele sunt utilizate într-o gamă largă de aplicaţii în diverse domenii. Dispozitivele unde µC sunt utilizate pot fi produse de uz general (mașini de spălat, frigidere, automate de cafea), sisteme industriale dedicate (relee de protecție, controllere industriale, sisteme de tip interfață om-mașină - HMI ), sisteme din industria aerospaţială și multe altele.
În funcție de tipul aplicațiilor pentru care sunt dedicate acestea, majoritatea µC nu au o magistrală externă de adrese sau date deoarece toate memoriile utilizate (volatile și nevolatile) sunt interne, ducând la integrarea acestora în capsule cu un număr mic de pini şi reduse ca dimensiuni, ceea ce reduce costurile de producţie și consumul energetic. Există desigur și microcontrollere care furnizează magistrale externe pentru date și adrese (multiplexate în timp sau magistrale dedicate) în scopul interfațării memoriilor externe (RAM, FLASH, ROM).
Cele mai întâlnite structuri din circuitul integrat al unui µC sunt următoarele:
Costul unui µC depinde în mare măsură de numărul de periferice integrate, frecvența de lucru a procesorului, cantitatea de memorie și alți parametri amintiți mai sus. Cu cât caracteristicile acestuia sunt mai avansate, cu atât crește prețul de producție. Arhitecturile de µC pe piaţă la ora actuală variază în limite largi, de la chip-uri cu doar 2 pini de I/O până la procesoare digitale de semnal (DSP) sau procesoare cu arhitecturi avansate pe 32 sau chiar 64 de biţi (ex: ARM, PIC32, STM32 sau AVR32).
Pentru alte exemple, puteți începe căutarea de aici: https://www.hackster.io/projects/tags/microcontroller
Famila AVR de la Microchip este formată din microcontrollere cu arhitectură Harvard pe 8 biţi şi set redus de instrucţiuni (RISC).
Memoriile Flash, EEPROM, şi SRAM sunt integrate în acelaşi chip, înlăturând nevoia de memorie externă. Programul este format din instrucţiuni de 16 biţi lungime care sunt stocate în memoria Flash non-volatilă. Mărimea memoriei de program este indicată de numele componentei respective. De exemplu, ATmega128 are 128kB de memorie Flash. Spaţiul de adresa este format din registrele generale, registrele de I/O şi memoria SRAM. Sunt în total 32 de registre generale a câte 8 biţi.
AVR au o unitate de execuţie în bandă de asamblare cu două niveluri, acest lucru permiţând că următoarea instrucţiune să fie adusă din memorie (fetch) în timp ce instrucţiunea curentă este în execuţie. Majoritatea instrucţiunilor se execută într-un singur ciclu de instrucţiune, acest lucru permiţând atingerea unui throughput de 1MIPS pe MHz.
În cadrul laboratoarelor și a proiectului de PM, veți utiliza ATmega328P, un microcontroller pe 8 biți din familia megaAVR. Registrele şi magistrala internă de date sunt pe 8 biţi.
Perifericele interne chip-ului pot fi accesate din exterior prin intermediul pinilor. Capsula microcontroller-ului are 28 de pini (prezentați mai jos), dintre care 5 sunt pentru alimentare sau funcții auxiliare, iar 23 sunt pentru I/O. GPIO-urile sunt împărțite în patru porturi (B, C și D) avand câte 8 pini PORTB si PORTD, iar PORTC 7.
Pentru mai multe detalii, consultați datasheet-ul (documentația tehnică sumarizată) a microcontrollerului.
Arduino este o companie open-source care produce atât plăcuțe de dezvoltare bazate pe microcontrolere, cât și partea de software destinată funcționării și programării acestora. Pe lângă acestea include și o comunitate uriașă care se ocupă cu creația și distribuirea de proiecte care au ca scop crearea de dispozitive care pot sesiza și controla diverse activități sau procese în lumea reală.
O plăcuță Arduino este compusă dintr-un microcontroler Atmel AVR de 8-, 16- sau 32-biți (deși începând cu 2015 s-au folosit microcontrolere de la alți producători) cu componente complementare care facilitează programarea și încorporarea în alte circuite
Multe plăcuțe includ un regulator liniar de 5 V și un oscilator cu cuarț de 16 MHz (sau un rezonator ceramic în unele variante), deși anumite plăcuțe, cum ar fi LilyPad, funcționează la 8 MHz și nu necesită regulator, datorită restricțiilor de formă. Un microcontroler instalat pe Arduino vine preprogramat cu un bootloader care simplifică încărcarea programelor pe memoria flash a cipului, în comparație cu alte dispozitive care necesită programatoare externe. Acest aspect face Arduino o soluție simplă, permițând programarea de pe orice computer ordinar. În prezent, bootloader-ul optiboot este bootloader-ul implicit instalat pe Arduino UNO.
Plăcuța Arduino are expuși mulți dintre pinii de intrare/ieșire ai microcontrolerului, pentru ca aceștia să fie folosiți de alte circuite.
Programele Arduino pot fi scrise în orice limbaj de programare cu un compilator capabil să producă un cod mașină binar. Atmel oferă un mediu de dezvoltare pentru microcontrolerele sale, AVR Studio și mai nou, Atmel Studio.
Proiectul Arduino oferă un mediu integrat de dezvoltare (IDE), care este o aplicație cross-platform, scrisă în Java. Acesta își are originile în mediul de dezvoltare pentru limbajul de programare Processing și în proiectul Wiring. Este proiectat pentru a introduce programarea în lumea artiștilor și a celor nefamiliarizați cu dezvoltarea software. Include un editor de cod cu funcții ca evidențierea sintaxelor, potrivirea acoladelor și spațierea automată și oferă mecanisme simple cu un singur click, pentru a compila și a încărca programele în plăcuța Arduino. Un program scris în IDE pentru Arduino se numește sketch.
Arduino IDE suportă limbajele de programare C și C++ folosind reguli speciale de organizare a codului. Arduino IDE oferă o librărie software numită Wiring, din proiectul Wiring, care oferă multe proceduri comune de intrare și ieșire. Un sketch tipic Arduino scris în C/C++ este compus din două funcții care sunt compilate și legate cu un stub de program main(), într-un program executabil cu o execuție ciclică:
După compilarea și legarea cu GNU toolchain inclus, de asemenea, în IDE, mediul de dezvoltare Arduino trimite comandă către programul avrdude pentru a converti codul executabil într-un fișier text codat hexazecimal, care poate fi încărcat în placa Arduino de un program de încărcare.
Pentru a putea intefața cu mediul exterior, sunt utilizate diferite componente electronice care au rol fie de actuator (modifică starea mediului exterior) sau de traductor/senzor (sunt influențate de mediul exterior și oferă informații microcontroller-ului despre diverși parametri).
Actuatorii sunt acele elemente care influențează mediul exterior. Putem spune că actuatorii sunt elementele ce pot fi comandate și care pot interacționadirect cu mediul pentru a influența diferiți parametri (ventilatoare, indicatoare sonore - buzzere , indicatoare luminoase, rezistențe de încălzire, etc). Uneori pentru a putea activa un actuator, este nevoie de un element de acționare. De exemplu, pentru a putea porni un motor(actuator) prin comanda dată de microcontroller, trebuie să folosim un element de acționare (care pornește ventilatorul) intermediar care să poată comanda curenți mari (prin ventilator) folosind curenți foarte mici de comandă (ieșirea microcontrollerului). În acest exemplu, soluția ar fi utilizarea unui tranzistor.
Traductoarele (sau traductorii) sunt acele elemente care iși modifică proprietățile electrice în funcție de parametrii mediului exterior și oferă microcontroller-ului informații despre mediul exterior. De exemplu: un fotorezistor va avea rezistența electrică mult mai mare în lipsa luminii, iar când aceasta este iluminată va avea o rezistență electrică de zeci sau chiar sute de ori mai mică. Un alt exemplu de traductor este butonul simplu normal deschis: când este apăsat el închide un contact, când nu este apăsat, contactul din interior este deschis. În funcție de tipul traductoarelor, acestea pot avea nevoie de prelucrarea semnalului înainte ca acesta să fie preluat de microcontroller (signal conditioning) - de exemplu fotorezistorul trebuie folosit într-un montaj cu divizor de tensiune sau cu sursă de curent -, sau pot fi conectate direct la microcontroller - de exemplu butonul.
În cadrul acestui laborator veți utiliza LED-uri pe post de indicator luminos de semnalizare a stării unui pin și butoane pentru a transmite informație către microcontroller.
LED-urile - Light Emitting Diode - numite și diode electroluminesciente emit lumină când ele sunt polarizate direct. În funcție de semiconductorii care sunt utilizați în construcție, și de plasticul ce are rol de lentilă de dispersie și filtru optic, LED-urile pot emite lumină în diferite culori. Nu confundați LED-urile cu becurile! În timp ce becurile emit lumina prin încalzirea unui filament de tungsten la temperaturi foarte mari, LED-urile emit lumina trecând un curent printr-un material semiconductor (joncțiune p-n). Spre deosebire de becuri, al căror randament este de sub 5% - majoritatea energiei primite de ele se pierde prin efect caloric -, LED-urile au un randament de transformare a energiei electrice în energie luminoasă mult mai mare.
LED-urile pot fi utilizate pe post de indicator luminos (adesea utilizate în diferite aparate pentru a semnaliza faptul că aparatul este pornit și realizează un anumit lucru), sau pentru iluminare, caz în care sunt utilizate LED-uri de putere.
În cadrul laboratorului LED-urile sunt utilizate pentru a indica starea unui pin.
Calculul rezistenței de limitare a curentului:
Un LED este proiectat să opereze la un curent nominal (ex: 10mA). Căderea de tensiune pe LED urile indicatoare, de mică putere, la acest curent, este dată de culoarea LED-ului, puterea acestuia și de temperatură. Ea poate varia de la 1.7V în cazul LED-urilor roșii, 2-2.3V pentru cele Orange, galbene și verzi și ajunge la 3.2-3.5V în cazul LED-urilor albastre și albe.
Schema utilizată este următoarea:
Întrucât microcontroller-ul are ieșirile comandate folosind stâlp Push-Pull CMOS, tensiunea Upin în starea de 1 logic va fi apropiată de tensiunea de alimentare a microcontroller-ului.
Exemplu:Dacă alimentarea microcontroller-ului este de 5V pentru un LED roșu ce dorim să îl folosim la 10mA, specificat de producător cu o cădere de tensiune de 1.7V, trebuie să folosim o rezistență de 330 de ohmi.
Cel mai simplu mod de interacțiune al utilizatorului cu un microcontroller îl constituie folosirea butoanelor. Modul de conectare al unui push-button este dat în figura de mai jos:
a) arată un buton conectat la pinul PD0 al µC. La apăsarea butonului, intrarea PD0 va fi legată la GND, deci va fi în starea logică “0”. Acest mod de legare este incorect deoarece atunci când butonul nu este apăsat intrarea se află într-o stare nedefinită (ca și cum ar fi lăsată în aer), ea nefiind conectată nici la GND, nici la Vcc. Această stare se numește stare de impedanță mărită și nu poate fi citită de către circuitele interne ale µC deoarece un bit dintr-un registru poate să ia doar valorile 0 sau 1. În practică, citirea unei intrări în stare de impedanță mărită va produce un rezultat de 1 sau 0 în funcție de condițiile de mediu. Spre exemplu, dacă apropiem degetul de acea intrare, citirea va fi 1, iar, daca îndepărtăm degetul, citirea va fi 0.
b) arată modul corect de conectare al butonului, folosind o rezistență de pull-up între pinul de intrare și Vcc. Această rezistență are rolul de a aduce intrarea în starea “1” logic atunci când butonul este liber prin “ridicarea” potențialului liniei la Vcc. Alternativ, se poate folosi o rezistență de pull-down (conectată la GND), caz în care intrarea este ținută in starea logică “0” cât timpul butonul nu este apăsat.
Pentru a economisi spațiu exterior, în µC ATmega324, aceste rezistențe au fost incluse în interiorul circuitului integrat. Inițial ele sunt dezactivate iar activarea acestora se poate face prin software scriind o valoare în registrul de ieșire (PORTn
) al unui port care a fost configurat drept intrare. Bitul PUD
din registrul SFIOR
este setat inițial pe 0, adică atunci când se scrie în PORTn
se activează rezistențele de pull-up.
Microntroller-ul ATmega324 oferă 4 porturi I/O a câte 8 pini, iar intern, fiecare port are asociat trei registre a câte 8 biți prin care utilizatorul poate controla la nivel de pin fluxul datelor: poate scrie/citi date în/din portul respectiv. Aceste trei registre sunt:
DDRn
- Data Direction RegisterPORTn
- Data RegisterPINn
- Input Pins Addressn poate să fie A, B, C sau D în funcţie de portul selectat. x poate să fie între 0 și 7.
Descrierea detaliată a porturilor şi registrelor corespunzătoare acestora se găseşte în datasheet-ul ATmega324, în capitolul I/O Ports.
Registrele DDRn
, PORTn
, PINn
, precum şi registrele perifericelor nu fac parte din cele 32 de registre de uz general. Ele nu sunt folosite pentru stocarea datelor, ci au ca rol comunicarea cu perifericul corespunzător. Pentru a face accesul la acestea mai simplu, ele sunt mapate în memorie. Astfel, pentru a scrie o valoare într-un registru este necesar să se scrie valoarea la adresa de memorie corespunzătoare registrului. Adresele lor se pot vedea în datasheet, în capitolul Register Summary, iar în avr-libc sunt definite macro-uri pentru fiecare dintre aceste adrese.
(1 << x)
) sau macro-ul _BV(x)
. De asemenea recomandăm folosirea numelui pinului în loc de indexul acestuia, pentru că numele acestora sunt sugestive pentru funcția pe care o îndeplinesc (spre exemplu, în registrul ADCSRA
al convertorului analog-digital, bitul ADEN
este bitul de enable). Numele pinilor, ca și în cazul registrelor, sunt deja definite în avr-libc.
Operație | Formă |
---|---|
Scriere bit pe 1 | register |= (1 << bit_index) |
Scriere bit pe 0 | register &= ~(1 << bit_index) |
Toggle bit | register ^= (1 << bit_index) |
Citire bit | register & (1 << bit_index) |
DDRB = 8; // AȘA NU. DDRB = (1 << 3); // Nici așa, este hardcodat indexul pinului. DDRB |= (1 << PB3); // AȘA DA. DDRB |= _BV(PB3); // AȘA DA.
Detalii despre lucru cu biții din registre puteți citi și la secțiunea tutoriale de pe wiki.
Să presupunem că avem un LED legat la pinul 1 al portului B (numit PORTB1
sau PB1
). Pentru a aprinde sau stinge LED-ul trebuie să urmăm următorii pași:
PB1
trebuie configurat ca ieșirePB1
) din registrul DDRB
va fi 1PB1
sa ia valoarea HIGHPB1
) din registrul PORTB
va fi 1PB1
sa ia valoarea LOWPB1
) din registrul PORTB
va fi 0
Să presupunem ca avem un buton legat la pinul 4 al portului D (numit PORTD4
sau PD4
), din cazul b) prezentat anterior. Pentru a determina starea butonului (apăsat sau liber) trebuie să urmăm următorii pași:
PD4
trebuie configurat ca intrarePD4
) din registrul DDRD
va fi 0PD4
) din registrul PIND
Vom scrie un program care stinge și aprinde un LED la intervale de 500 ms. Acest lucru se face modificând tensiunea unuia dintre pinii microcontroller-ului, în cazul nostru pinul 5 din portul B (PB5
), pe placa Arduino UNO, pinul didital 13.
Exemplu folosind biblioteca Arduino.
#define LED 13 void setup() { pinMode(LED, OUTPUT); } void loop() { digitalWrite(LED, HIGH); delay(500); digitalWrite(LED, LOW); delay(500); }
Exemplu folosind scrieri in registrii procesorului.
void setup() { DDRB |= (1 << PB5); } void loop() { PORTB |= (1 << PB5); delay(500); PORTB &= ~(1 << PB5); delay(500); }
Tinkercad este un program online, gratis de modelare 3D recunoscut pentru simplitatea in utilizare. Acesta ofera suport de simulare pentru placa Arduino UNO.
Task 0 Rulați exemplul Hello Word folosind simulatorul Tinkercad. LED-ul este marcat cu L pe placa Arduino si este conectat la pinul digital 13. Puteti adauga inca un LED ca in exemplul de montaj.
Task 1 Adaugati un buton la pinul digital 2 (PD2) si faceti LED-ul sa se aprind cand butonul este apasat.
Task 2 Adaugati inca un buton la pinul digital 3 (PD3). Folsoiti butoanele pentru a creste/micsora durata delay-ului folosit la exemplul Hello Word.
Task 3 Incarcati programul Hello Word pe placa Arduino UNO folosind Arduino IDE.
Task 4 Realizati montajul de la Task 2 folosind un breadboard si rulati programul.