This is an old revision of the document!
În acest laborator vom îmbunătăți implementarea noastră a modulului de GPIO adăugând posibilitatea pinilor de a funcționa și ca intrări.
În laboratorul trecut am învățat că dacă un pin are funcția de GPIO, atunci vom putea să îi controlăm direcția și valoarea în mod programatic prin scrieri și citiri în/din anumite registre.
Registrele care controlează comportamentul unui port sunt:
Aceste registre sunt toate pe 8 biți iar fiecare bit controlează comportamentul unui pin al portului respectiv. Ca și în laboratorul trecut, ne vom limita la portul A al microcontroller-ului.
= PORTA (recapitulare) =
În laboratorul trecut am învățat ce efect avea schimbarea unui bit din registrul PORTA:
Registrul DDRA controleaza direcția pinilor din portul A astfel:
Din registrul PINA putem citi valoarea tensiunii de pe pinii portului A astfel:
Până acum am învațat că dacă schimbăm un bit din DDRA sau PORTA putem să influențăm comportamentul unui pin. Însă instrucțiunile in și out nu pot scrie decât valori pe 8 biți. Spre exemplu, dacă dorim să schimbăm doar bitul 5 din DDRA în 1 atunci pașii pe care trebuie sa îi urmăm sunt:
ldi R17, 0b00100000 ; încărcăm în R17 o mască ce are 1 pe bitul 5 in R16, DDRA ; încărcăm în R16 valoarea din DDRA or R16, R17 ; în urma operației sau între R16 și R17 în R16 bitul 5 va fi pus pe 1 out DDRA, R16 ; stocăm valoarea din R16 înapoi în DDRA
Fiindcă acțiunea de a schimba un bit în 1 (set) sau în 0 (clear) este una întâlnită des în programele ce rulează pe arhitectura AVR aceasta include două instrucțiuni ce permit schimbarea unui bit dintr-un registru ce se află în primele 32 de adrese din I/O Space în 0 sau în 1: cbi (Clear Bit in Register) și sbi (Set Bit in Register). Ele primesc ca și argumente adresa registrului (în intervalul [0:31]) și numărul bitului (în intervalul [0:7]). Dacă rescriem codul folosind aceste înstrucțiuni el devine:
sbi DDRA, 5
cbi și sbi primesc ca și argument numărul bitului pe care dorim să-l schimbăm, nu o mască de biți.
Pentru a modifica valoarea unui registru I/O putem sa folosim:
LDI R16, 7 OUT 0x01, R16 ; DDRA = 00001111
LDI R16 0 OUT 0x01, R16 ; DDRA = 00000000 SBI 0x01, 5 ; DDRA = 00100000 SBI 0x01, 4 ; DDRA = 00110000 CBI 0x01, 5 ; DDRA = 00010000
TODO 1 din gpio.v și cpu.v.sbi și cbi și completați logica necesară execuției lor. Urmăriți comentariile marcate cu TODO 2 din signal_generation_unit.v, decode_unit.v și control_unit.v.t0 *------* t1 -*----*- t2 --*--*-- t3 ---**--- t4 ---**--- t5 --*--*-- t6 -*----*- t7 *------*
sbi și cbi pentru a scrie valoarea pinului PB0 pe pinul PA0. Încărcați-l pe placa de dezvoltare.