laborator 3 - utclujusers.utcluj.ro/~rdanescu/pmp-lab3.pdfcablul 12pini la 2x6 pini. capatul cu 12...
TRANSCRIPT
Laborator 3
1. Intreruperi externe.
2. Tastatura PMod KYPD. Conectarea si utilizarea acestei tastaturi
1. Intreruperile externe
Intreruperile externe sunt un alt mod de a percepe activitatea unor pini externi. Exista opt
intreruperi externe disponibile, comune cu pinii 0..3 ai portului D si cu pinii 4..7 ai portului E.
Pentru Cerebot 1:
Pentru Cerebot 2:
Pentru ilustarea mecanismului intreruperilor, vom scrie un program care va aprinde unul dintre
cele patru led-uri de pe placa, in functie de unul dintre cele patru butoane ale modulului Pmod
BTN. Vom conecta modulul cu butoane la intreruperile externe INT0…INT3:
- JE, pentru Cerebot 1
- JD, randul de jos, pentru Cerebot 2
Atentie la polaritate! Conectati PmodBTN cu butoanele in sus!
Programul pentru identificarea butoanelor este urmatorul:
.include "m64def.inc"
.org 0x0000 ; adresa absoluta pentru intreruperea RESET
rjmp reset
.org 0x0002 ; adresa absoluta pentru intreruperea externa 0
rjmp btn1
.org 0x0004 ; adresa absoluta pentru intreruperea externa 1
rjmp btn2
.org 0x0006 ; adresa absoluta pentru intreruperea externa 2
rjmp btn3
.org 0x0008 ; adresa absoluta pentru intreruperea externa 3
rjmp btn4
reset: ; programul principal, initializarile
ldi r16, low(ramend) ; stiva
out SPL, r16
ldi r16, high(ramend)
out SPH, r16
ldi r16, 0xff ; PORTE iesire, conectat la leduri
out DDRE, r16
ldi r16, 0b11111111 ; se configureaza declansarea intreruperilor externe pe front
sts EICRA, r16 ; crescator (buton apasat). EICRA e in spatiul I/O extins
ldi r16, 0b00001111 ; se activeaza intreruperile externe 0, 1, 2, 3
out EIMSK, r16
sei ; activare intreruperi
donothing: ; programul se blocheaza in acest ciclu infinit
rjmp donothing
btn1:
ldi r16, 0b00010000 ; aprindem LED1 (conectat la PE4)
out PORTE, r16
reti ; return from interrupt
btn2:
ldi r16, 0b00100000 ; aprindem LED2 (conectat la PE5)
out PORTE, r16
reti
btn3:
ldi r16, 0b01000000 ; aprindem LED3 (conectat la PE6)
out PORTE, r16
reti
btn4:
ldi r16, 0b10000000 ; aprindem LED4 (conectat la PE7)
out PORTE, r16
reti
Prima parte a programului asociaza pentru fiecare adresa absoluta corespunzatoare intreruperilor
externe 0..3 cate o procedura (ISR – interrupt service routine), care se va executa in momentul in
care se declanseaza intreruperea. Adresele absolute sunt luate din datasheet-ul
microcontrollerului:
In continuare, programul initializeaza stiva, si directia portului E (iesire). Apoi, pentru fiecare
intrerupere externa folosita, se configureaza modul ei de declansare (in cazul nostru, pe front
crescator, corespunzator evenimentului apasare buton). Configurarea se face prin scrierea
registrului EICRA, registru din spatiul de adrese I/O extins (accesibil doar cu instructiuni de tip
Load si Store).
Intreruperile sunt apoi activate prin scrierea bitilor din registrul EIMSK. Sistemul global de
intreruperi se activeaza prin instructiunea sei, iar apoi programul principal este blocat intr-un
ciclu infinit.
2. Tastatura PMod KYPD. Conectarea si utilizarea acestei tastaturi
Tastatura cu 4x4 taste PMod KYPD este un dispozitiv pasiv, cu patru linii si patru coloane,
apasarea unei taste realizand un contact intre electrodul liniei si cel al coloanei. Electrozii linie si
coloana sunt conectati la pinii dispozitivului conform tabelului de mai jos.
Schema electrica a dispozitivului este prezentata in figura urmatoare.
Pentru identificarea unei taste, trebuie sa baleiem coloanele pe rand, punand cate o valoare logica
‘0’ pe cate o coloana, si valoarea logica ‘1’ pe toate celelalte. In acest timp, randurile sunt legate
la VCC prin intermediul unor rezistente “pull up”. La apasarea unei taste, daca tasta este pe
coloana ce primeste valoarea ‘0’, randul tastei va fi tras la ‘0’. Astfel, tasta va fi identificata prin
perechea (coloana cu valoare ‘0’, rand cu valoare ‘0’).
Pseudocodul pentru identificarea unei taste este:
Repeat:
For c = 0 to 3 do
Coloane[0]=Coloane[1]=Coloane[2]=Coloane[3]=1
Coloane[c]=0
port_iesire_coloane = Coloane
Delay()
Randuri = citeste_port_rand
For r = 0 to 3 do
If (Randuri[r]==0)
Tasta = c * 4 + r
End if
End for
End for
Goto Repeat
Codul tastei, un numar intre 0 si 15, va fi generat prin formula 4*c+r. In acest moment, nu ne
intereseaza ca acest cod sa corespunda cu numarul scris pe tasta, ci doar ca acest cod sa fie unic
pentru fiecare tasta in parte. Inmultirea cu 4 se poate face prin doua deplasari la stanga.
Conform pseudocodului, avem nevoie de doua porturi: unul de iesire, unde vom scoate valoarea
pentru coloane, pentru a realiza procedul de baleiere, si unul de intrare, unde vom citi starea
randurilor. Totusi, in continuare vom prefera o alta abordare. In loc sa citim starea randurilor si
sa vedem care dintre ele devine zero, vom folosi mecanismul de intreruperi, si vom conecta pinii
randurilor la intreruperile externe INT0…INT3. Pseudocodul se transforma astfel:
Configurare intreruperi externe INT0…INT3 pentru declansare pe front descrescator
c – variabila globala, contorul coloanelor
Repeat:
For c = 0 to 3 do
Coloane[0]=Coloane[1]=Coloane[2]=Coloane[3]=1
Coloane[c]=0
port_iesire_coloane = Coloane
Delay()
End for
Goto Repeat
INT0_ISR – se declanseaza cand apare 0 pe randul 0
Tasta = c * 4 + 0
PORTE = TASTA << 4
Reti
INT1_ISR – se declanseaza cand apare 0 pe randul 1
Tasta = c * 4 + 1
PORTE = TASTA << 4
Reti
INT2_ISR – se declanseaza cand apare 0 pe randul 2
Tasta = c * 4 + 2
PORTE = TASTA << 4
Reti
INT3_ISR – se declanseaza cand apare 0 pe randul 3
Tasta = c * 4 + 3
PORTE = TASTA << 4
Reti
Fiecare intrerupere se declanseaza doar cand randul corespunzator ei devine zero, adica atunci
cand pe acest rand exista o tasta apasata. Dar o tasta apasata nu va duce la o valoare zero pe rand
daca coloana acestei taste nu este activata prin valoarea zero. Astfel, in momentul in care apare
zero pe un rand, coloana este cunoscuta (coloana activa), si randul este de asemenea cunoscut,
deci tasta este complet identificata.
In continuare, vom conecta tastatura la placa Cerebot II. Pentru realizarea conexiunii, vom utiliza
cablul 12pini la 2x6 pini. Capatul cu 12 pini il vom conecta la tastatura, cu semnul in dreptul
VCC, ca in imaginile de mai jos:
Cele doua capete de 6 pini ale cablului sunt conectate, in acest moment, astfel:
- Capatul marcat cu A este conectat la coloane
- Capatul marcat cu B este conectat la randuri
Capatul A trebuie conectat la placa Cerebot la pinii unui port de iesire, unde vom trimite valori
de genul 0111, 1011, 1101, 1110, in mod repetat. In figura de mai jos acest capat este conectat la
JA, randul de sus, corespunzator bitilor PA3…PA0.
Capatul B trebuie conectat la conectorul unde gasim intreruperile externe INT0… INT3. Pentru
placa Cerebot II, acest conector este JD, randul de jos.
Pentru baleierea coloanelor puteti folosi urmatorul cod:
ldi r16, 0 ; r16, numarul coloanei
baleiere:
rcall codecol ; functie care genereaza numar ‘0’ pe pozitia indicata in r16
out PORTA, r17 ; transmitem pe portul atasat coloanelor
rcall delay ; intarziere necesara
inc r16 ; crestem numarul coloanei
cpi r16, 4 ; am trecut de 3 ?
brne baleiere
ldi r16, 0 ; daca da, reluam baleierea de la prima coloana
rjmp baleiere
Functia codecol foloseste operatia de deplasare pentru a pozitiona valoarea de activare pe pozitia
specificata de intrarea r16:
; input r16, number of col, from 0 to 7
; output r17, col made zero, others one
codecol:
push r16
ldi r17, 1
shift:
cpi r16, 0
breq shift_done
lsl r17
dec r16
rjmp shift
shift_done:
com r17
pop r16
ret
Pentru verificarea functiei de baleiere, conectati la portul de iesire, in locul capatului A al
cablului de la tastatura, un bloc de led-uri, ca in figura de mai jos. Daca baleierea este corecta, se
va observa cum led-urile se sting pe rand.
Pentru conectarea tastaturii la Cerebot 1, vom utiliza pentru baleiere portul F, ai carui pini
sunt accesabili prin conectorul JF. Portul F este in spatial I/O extins, astfel incat pentru
configurarea directiei veti scrie:
sts DDRF, r16
Pentru transmiterea unei valori la iesire se va scrie:
sts PORTF, r16
Capatul B il vom atasa la conectorul JE, unde se afla intreruperile externe.
Daca baleierea este corecta, apasarea unei taste va produce un front descrescator pe pinul
corespunzator randului. Acest front se detecteaza configurand intreruperile externe sa sesizeze
frontul descrescator.
Lucru individual
1) Compilati si rulati programul pentru verificarea intreruperilor externe. Modificati modul
de detectie al intreruperilor (front crescator, nivel). Activati si dezactivati intreruperi
individuale.
2) Conectati tastatura la placa, urmand instructiunile corespunzatoare placii pe care o aveti.
Verificati baleierea folosind led-urile.
3) Identificati tasta si afisati codul acesteia pe led-urile de pe placa, folosind intreruperi.
4) Folosind un LUT, decodificati tasta astfel incat numarul afisat pe led-uri sa corespunda
cifrei hexazecimale desenata pe tasta.
5) Extra: afisati codul tastei pe SSD (e suficienta 1 cifra, fara baleiere)
Documente suplimentare:
PModKYPD_rm.pdf