Folosind GPIO (General-Purpose Input/Output) putem controla un pin al unui circuit integrat. De exemplu, putem aprinde un led folosind instrucțiuni AVR sau putem citi starea unui pin - LOW sau HIGH. Pinii ce suportă GPIO sunt grupați în porturi (grupuri de 8 pini logici numite A
sau B
) controlate de registre speciale (pe câte 8 biți):
În memoria microcontrollerului de la 0x00 la 0x3F gasim I/O Space. Aici se află toate registrele de lucru cu periferice și, desigur, DDRx, PORTx și PINx. De exemplu registrul PORTA are adresa 0x02.
Pentru a scrie citi date din I/O Space putem folosi instrucțiunile LDS/STS, însă recomandat este să folosim instrucțiunile speciale pentru lucru de memoria I/O Space ce se execută mai rapid:
OUT A, Rr
: Scrie (Store) în I/O Space la adresa A valoarea din registrul Rr IN Rd, A
: Citește (Load) din I/O Space de la adresa A și pune în registrul Rd
Pentru a modifica un singur bit dintr-un registru de configurare putem folosi instrucțiunile SBI
/CBI
.
I
din SREG
este 1)
Task 01 (2p) Scrieți un program care setează portul A ca ieșire, portul B ca intrare, apoi, într-o buclă, citește valoarea de pe portul B și o scrie pe portul A. Folosiți tool-ul avrasm pentru a-l scrie în fișierul rom.v
.
Task 02 (2p) Scrieți un program care scrie pe portul A următoarea secvență, folosind instrucțiunle SBI si CBI. Vom verifica secvența folosind simularea.
t0 *------* t1 -*----*- t2 --*--*-- t3 ---**--- t4 ---**--- t5 --*--*-- t6 -*----*- t7 *------* - `-` înseamnă led stins - `*` înseamnă led aprins - (dacă am lega la pinii PAx leduri :-) )
Task 03 (3p) Scrieți și simulați un program în avrasm care:
fast PWM, TOP == 0xFF
clkI/O (No prescaling)
Clear OC0A on Compare Match, set OC0A at BOTTOM (non-inverting mode)
Task 04 (3p) Plecând de la următorul schelet de cod, creați un program care schimbă starea pinului PA0 folosindu-se de o întrerupere, cât timp bucla principală este într-o buclă infinită. Simulați programul.
DDRA equ 0x01 PORTA equ 0x02 TCCR0A equ 0x19 TCCR0B equ 0x18 TIMSK equ 0x26 OCR0A equ 0x16 rjmp main ; Adresa 0x0000 reti ; Adresa 0x0001 reti ; Adresa 0x0002 reti ; Adresa 0x0003 reti ; Adresa 0x0004 reti ; Adresa 0x0005 reti ; Adresa 0x0006 reti ; Adresa 0x0007 reti ; Adresa 0x0008 rjmp TIM0_COMPA_ISR ; Adresa 0x0009 reti ; Adresa 0x000A reti ; Adresa 0x000B reti ; Adresa 0x000C reti ; Adresa 0x000D reti ; Adresa 0x000E reti ; Adresa 0x000F reti ; Adresa 0x0010 TIM0_COMPA_ISR: ; TODO 4: Schimbați (toggle) starea pinului PA0. main: ; TODO 4: Configurați pinul PA0 ca și ieșire. ; TODO 4: Porniți un timer care să genereze o întrerupere de comparație pe canalul A. Puneți ; valoarea 42 ca valoare de comparație pentru canalul A. ; TODO 4: Activați întreruperile global. ; Deși programul pare să stea într-o buclă infinită, ar trebui să vedem că totuși starea ; pinului PA0 se schimbă. loop: rjmp loop