Scopul:
1. Initiere in programare ASM
2. Studiul instrumentelor de proiectare a
aplicatiilor cu MCU (AVR Studio, Proteus)
3. Lucrul cu modulul periferic GPIO
Expunerea problemei:
Să se proiecteze un sistem care ar permite schimbarea stării unui
led, din aprins în stinns si invers, la apăsarea unui buton. Starea inițială se
va considera led aprins.
Consideraţii teoretice:
Modulul periferic GPIO - Port Generic de
Intrare/Ieşire.
Orice Microcontroller are un set de pini, majoritatea dintre care care pot fi configuraţi ca pini generici de intrare sau ieşire (GPIO), astfel încît sa i se poată atribui o valoare logica către terminalul pinului sau sa fie citita aceasta valoare logica de pe el, in cazul cand pinul este configurat către intrare.
Pinii de intrare/ieşire sunt grupaţi in porturi a cate opt. Lucrul cu portul se executa ca cu un tot intreg, respectiv, dintro singura operatie de transfer catre port putem modifica configuratia la toti opt pini deodata. Deci operatiile de transfer catre port va afecta toti pinii ce il constitiue.
Deoarece modulul GPIO este un modul periferic al microcontrollerului, respectiv are rezervati un set de registri in spatiul de adrese a registrilor periferici.
Fiecare modul GPIO a microcontrollerului cu arhitectura AVR va avea la dispozitie trei registri periferici PINx, DDRx si PORTx.
Figura 1
Modul de
functionare a modulului GPIO
·
PINx - serveste pentru
citirea valorii logice de pe terminalul fizic, acest registru este
accesibil doar pentru citire. Operatia de scriere catre acest
registru nu va afecta valoarea fizica a terminalului fizic.
·
PORTx - registru de setare a valorii portului pentru
cazul cand este setat catre iesire si activarea rezistentei de pull-up in cazul
cand este setat catre intrare.
·
DDRx - Registrul de setare a directiei
portului, intrare sau iesire
In cazul cand o locatie a DDRx va
contine "1", pinul respectiv va fi setat catre iesire, iar valoarea
logica din PORTx de la aceiasi locatie va fi tranferata catre terminalul fizic.
In cazul in care o locatie a DDRx va contine "0" , terminalul fizic respectiv va fi setat catre intrare. In acest caz valoarea din registrul PORTx va conecta rezistenta de pull-up cu valoarea logica "1", valoarea logica "0" va seta pinul in starea de impedanta inalta - "HiZ". se recomanda de a evita starea de HiZ pe terminal, fapt ce are loc cand terminalul nu este conectat la o sursa de semnal, pentru a evita introducerea de zgomote in interiorul cipului microcontrollerului, ce ar putea in cazurile critice duce pana la defectarea crcuitului.
In cazul in care o locatie a DDRx va contine "0" , terminalul fizic respectiv va fi setat catre intrare. In acest caz valoarea din registrul PORTx va conecta rezistenta de pull-up cu valoarea logica "1", valoarea logica "0" va seta pinul in starea de impedanta inalta - "HiZ". se recomanda de a evita starea de HiZ pe terminal, fapt ce are loc cand terminalul nu este conectat la o sursa de semnal, pentru a evita introducerea de zgomote in interiorul cipului microcontrollerului, ce ar putea in cazurile critice duce pana la defectarea crcuitului.
In asa mod recomandarea pentru pinii neutilizati este de a
seta configuratia lor ca intrare cu rezistenta de pull-up activata, ceia ce va
evita scurtcircuituri intamplatoare atunci cand este setat spre iesire, si
pentru cazul cand este pe intrare , evitarea zgomotelor pe intrare nedorite.
Mersul lucrării:
1) Pentru
început se familiarizează cu scopurile propuse, formulând principiul de
funcţionarea ledului şi a butonului la apăsare. Ca urmare creem schema bloc.
2) Următorul pas este crearea ciruitului în programul de
simulare PROTEUS, unde se demonstrează cum funţionează porturile de I/O şi
respectiv programul microcontrollerului.
Principiul de lucru a controlerului (programei) va fi
următorul: programul va cicla şi va controla mereu dacă tasta este sau nu
apăsată, după care va verifica dacă este sau nu aprins LED-ul şi îl va
deconecta sau conecta respectiv, după care va intra în bucla de verificare şi aşteptare
ca tasta să nu mai fie apăsată şi iarăşi de la început.
3)
Listingul programului
Descrierea instrucţiunilor
utilizate:
SBIC – această instrucţiune testează un singur bit din
registrul de intrare/ieşire şi sare peste o comandă dacă bitul nu este setat.
Această instrucţiune operează cu primii 32 regiştri din porturile de
intrare/ieşire – adresele 0-31. Nu modifică nici un
flag.
Sitaxa
|
Operanzii
|
Program counter
|
SBIC A,b
|
0≤A≤31, 0≤b≤7
|
PC←PC+1, condiţia e falsă
PC←PC+2, sare o instr. de 1 cuv
PC←PC+3, sare o instr. de 2 cuv
|
CPI – această instrucţiune efectuează comparaţia între un registru şi o
constantă. Registrul nu suferă modificări. Toate instrucţiunile de ramificări
pot fi utilizate după această instrucţiune.
Modifică flagurile: Z, C, N, V, H.
Sitaxa
|
Operanzii
|
Program counter
|
CPI Rd, K
|
16≤A≤31, 0≤K≤255
|
PC←PC+1
|
BRNE – Ramificare condiţională relativă. Testează flagul Z
(flagul zero) şi dacă nu este setat programul se remifică relativ lui PC în
orice direcţie (PC-64≤destinaţia≤PC+63).
Nu modifică nici un flag.
Sitaxa
|
Operanzii
|
Program counter
|
BRNE
k
|
-64≤k≤+63
|
PC←PC+k+1
PC←PC+1, dacă condiţia e falsă
|
Concluzii:
Programarea assembler se realzează
la cel mai jos nivel. In assembler progamatorul dirijează explicit cu fiecare
instrucţiune de executie a controllerului. Deaceea un program scrin în
assembler este mult mai mic, mult mai rapid comparativ cu un program scris
într-un limbaj de nivel înalt. Sintaxa în assembler este foarte simpla, însă
organizarea şi comportametul programului ramâne pe competenţa şi răspunderea
programatorului.