0% au considerat acest document util (0 voturi)
4 vizualizări17 pagini

Lab 2

Lucrarea se concentrează pe utilizarea microcontrolerului ATmega32, în special pe modulele timer, inclusiv Timer/Counter0 pe 8 biți și timerul pe 16 biți. Se discută despre sistemul de întreruperi, modul de funcționare al timerelor și aplicații practice folosind placa de dezvoltare EasyAVRv7. Documentul detaliază modurile de funcționare, registrele de control și pașii necesari pentru programarea timerelor.

Încărcat de

razvanstoica28
Drepturi de autor
© All Rights Reserved
Respectăm cu strictețe drepturile privind conținutul. Dacă suspectați că acesta este conținutul dumneavoastră, reclamați-l aici.
Formate disponibile
Descărcați ca PDF, TXT sau citiți online pe Scribd
0% au considerat acest document util (0 voturi)
4 vizualizări17 pagini

Lab 2

Lucrarea se concentrează pe utilizarea microcontrolerului ATmega32, în special pe modulele timer, inclusiv Timer/Counter0 pe 8 biți și timerul pe 16 biți. Se discută despre sistemul de întreruperi, modul de funcționare al timerelor și aplicații practice folosind placa de dezvoltare EasyAVRv7. Documentul detaliază modurile de funcționare, registrele de control și pașii necesari pentru programarea timerelor.

Încărcat de

razvanstoica28
Drepturi de autor
© All Rights Reserved
Respectăm cu strictețe drepturile privind conținutul. Dacă suspectați că acesta este conținutul dumneavoastră, reclamați-l aici.
Formate disponibile
Descărcați ca PDF, TXT sau citiți online pe Scribd

Laborator Microcontrolere

Lucrarea 2
Microcontrolerul ATmega32. Utilizarea modulelor timer

Scopul lucrării

a) Prezentarea modulului Timer/Counter0 pe 8 biţi


b) Prezentarea modulului timer pe 16 biţi
c) Programarea unor aplicaţii utilizând placa de dezvoltare EasyAVRv7

1. Noţiuni generale privind sistemul de întreruperi

Microcontrolerul ATmega32 dispune de mai multe tipuri de module hardware


care pot funcţiona independent de unitatea centralǎ utilizând sistemul de întreruperi.
Astfel, dupǎ ce un modul terminǎ activitatea pe care trebuie sǎ o realizeze, genereazǎ
o întrerupere pentru a avertiza procesorul cǎ este pregǎtit sǎ execute o nouǎ sarcinǎ.
Ca exemple de module hardware se pot menţiona:
- douǎ numǎrǎtoare (timere) de 8 biţi şi un numǎrǎtor (timer) de 16 biţi
- modul de comunicaţie serialǎ pe douǎ fire TWI
- modul de comunicaţie serialǎ USART
- convertor analog – digital
- comparator analogic.

Tabela de întreruperi se plasează de obicei la începutul zonei de memorie flash.


În cazul microcontrolerului ATmega32, fiecare linie din tabela de întreruperi
ocupă două locaţii de memorie. Această structură permite utilizarea instrucţiunii
jmp pentru saltul către rutina de tratare a întreruperii. Instrucţiunea jmp, spre
deosebire de rjmp, ocupă un număr dublu de biţi (32) şi oferă posibilitatea de a
accesa orice zonă din cei 32KB de memorie flash ai microcontrolerului ATmega32.
Cea mai uzuală amplasare a întreruperilor este descrisă în tabelul de mai jos.
Nr. Adresa în
Descriere
crt. memoria Flash
1 0x00 Generată la alimentare sau la un semnal pe pinul RESET
2 0x02 Întrerupere externă 0
3 0x04 Întrerupere externă 1
4 0x06 Întrerupere externă 2
5 0x08 Generată când Timer/Counter2 atinge valoarea de prag
6 0x0A Generată când Timer/Counter2 atinge valoarea maximă
7 0x0C Generată de unitatea de captură a timerului pe 16 biţi
8 0x0E Generată când timerul pe 16 biţi atinge valoarea de prag A
9 0x10 Generată când timerul pe 16 biţi atinge valoarea de prag B
10 0x12 Generată când timerul pe 16 biţi atinge valoarea maximă
11 0x14 Generată când Timer/Counter0 atinge valoarea de prag
12 0x16 Generată când Timer/Counter0 atinge valoarea maximă
13 0x18 Generată de unitatea SPI
Generată la recepţia completă a unor date de către modulul
14 0x1A
USART
15 0x1C Generată când registrul de date al modulului USART este gol
Generată la transmisia completă a unor date de către modulul
16 0x1E
USART
17 0x20 Generată de modulul ADC
18 0x22 Generată de modulul EEPROM
19 0x24 Generată de comparatorul analogic
20 0x26 Generată de modulul TWI
21 0x28 Generată de modulul de auto-scriere a memoriei Flash

Pentru orice sursă de întrerupere, există un bit specific de activare/dezactivare.


În afară de biţii specifici, toate întreruperile sunt controlate de bitul I din registrul de
stare. Astfel, dacă acest bit este 0, nu se va executa nici o întrerupere, indiferent de
setarea biţilor individuali. Bitul I se poate face 0 cu instrucţiunea cli şi 1 cu
instrucţiunea sei.

În rutina de tratare a întreruperii, utilizatorul trebuie să salveze de la început


registrul de stare SREG şi apoi să îl restaureze la sfârşitul rutinei. De asemenea,
ieşirea din rutina de tratare a întreruperii se face cu instrucţiunea reti.
Un exemplu tipic de rutină pentru întreruperi este prezentat mai jos:
intrerupere:
in r20, SREG ; salvarea registrului de stare in r20
.......
.......
.......
out SREG, r20 ; restaurarea registrului de stare din r20
reti

2. Modulul Timer/Counter0 pe 8 biţi

Modulul Timer/Counter0 pe 8 biţi poate fi utilizat pentru realizarea de


temporizări, numărarea evenimentelor externe sau generarea de forme de undă. În
Figura 1 este prezentată schema bloc a modulului timer. Dintre cele mai importante
caracteristici se pot menţiona:
- un prag independent de comparaţie
- poate număra impulsuri externe
- posibilitate de auto-iniţializare
- posibilitate de generare facilă a semnalelor Pulse Width Modulation (PWM)

2
Figura 1. Schema bloc a modulului Timer/Counter0 pe 8 biţi

Regiştrii alocaţi acestui timer pot fi împărţiţi în trei mari categorii:


- registrul de numărare: TCNT0
- pragul de comparaţie: OCR0
- comandă şi control: TCCR0, TIMSK şi TIFR

Conţinutul regiştrilor de comandă şi control este prezentat în Figura 2.

Figura 2. Conţinutul regiştrilor de comandă şi control ai Timer/Counter0

Modurile principale de funcţionare ale Timer/Counter0 sunt:


- funcţionare normală
- re-iniţializare la atingerea valorii de prag (CTC)
- semnal PWM rapid
- semnal PWM corect în fază

Biţii care selectează modul de funcţionare se regăsesc în registrul TCCR0.


Rezultatul posibilelor combinaţii ale acestora este dat în Figura 3.

3
Figura 3. Setarea modului de funcţionare al Timer/Counter0

Toate modurile de funcţionare se bazează pe incrementarea sau decrementarea


automată a registrului de numărare TCNT0. Frecvenţa de incrementare/decrementare
este controlată de combinaţia biţilor CS02, CS01, CS00 din registrul TCCR0 conform
tabelului de mai jos (cu fosc s-a notat frecvenţa ceasului microcontrolerului).

CS02 CS01 CS00 Frecvenţa de inc/dec


0 0 0 timer oprit
0 0 1 fosc/1
0 1 0 fosc/8
0 1 1 fosc/64
1 0 0 fosc/256
1 0 1 fosc/1024
frecvenţa semnalului de pe pinul
1 1 0
T0, frontul descendent
frecvenţa semnalului de pe pinul
1 1 1
T0, frontul ascendent

Unitatea timer compară în permanenţă valoarea TCNT0 cu OCR0. În


modurile de funcţionare normală şi re-iniţializare la atingerea valorii de prag,
valoarea 1 a bitul OCIE0 din registrul TIMSK determină generarea unei întreruperi
când TCNT0 atinge valoarea registrului de prag OCR0.
În vederea utilizării timerului Timer/Counter0, programatorul trebuie să
prevadă o secvenţă iniţială de cod pentru setarea parametrilor de funcţionare. Această
secvenţă trebuie să cuprindă cel puţin următorii paşi:
- dezactivarea globală a întreruperilor (folosind cli);
- setarea porturilor ce urmează a fi folosite, dacă este cazul;
- alegerea modului de funcţionare dorit prin modificarea biţilor
corespunzători din registrul de control. Se va avea în vedere să nu se
pornească timerul.
- iniţializarea cu o valoarea a registrului de numărare şi/sau a pragului, dacă
este cazul;
- activarea întreruperilor dorite prin modificarea biţilor corespunzători din
registrul TIMSK. Se va avea în vedere să nu se modifice biţii
corespunzători altui modul timer.
- pornirea timerului la frecvenţa dorită, având în vedere să nu se modifice
valoarea altor biţi din registrul de control;
4
- activarea globală a întreruperilor folosind sei, dacă este cazul.

2.1. Modul de funcţionare normală

În acest mod valoarea TCNT0 este incrementată continuu la fiecare tact de


numărare. Când se atinge valoarea maximă reprezentabilă pe 8 biţi, TCNT0 ia
valoarea 0 şi apoi continuă să numere.
Dacă bitul TOIE0 din registrul TIMSK are valoarea 1, se va genera o
întrerupere când se atinge valoarea maximă reprezentabilă pe 8 biţi.

2.2. Modul de funcţionare cu re-iniţializare la atingerea valorii de prag (CTC)

În acest mod valoarea TCNT0 este incrementată la fiecare tact de numărare


până când devine egală cu OCR0. În acest moment, TCNT0 se re-iniţializează cu 0 şi
numărătoarea reîncepe.
În funcţie de valorile biţilor COM01 şi COM00 din registrul TCCR0 (Figura
4), este posibil să se programeze modificarea nivelului logic al pinului OC0 când
TCNT0 atinge valoarea registrului de prag OCR0. În acest caz pinul trebuie setat ca
ieşire.

Figura 4. Efectul combinaţiilor posibile ale biţilor COM01 şi COM00

2.3. Modul de funcţionare semnal PWM rapid

În acest mod de funcţionare, TCNT0 este incrementat până atinge valoarea


0xFF. În acest moment se iniţializează TCNT0 cu 0 şi se reia numărătoarea.
Valoarea logică a pinului OC0 se modifică numai când TCNT0 este egal cu o
valoare de prag şi când ajunge la valoarea 0, aşa cum se poate vedea în Figura 5.
În acest mod de funcţionare utilizatorul poate modifica oricând valoarea de
prag deoarece ea nu va fi transferată în modulul timer decât după ce TCNT0 a realizat
un ciclu complet de numărare.

Figura 5. Modul de funcţionare semnal PWM rapid


5
2.4. Modul de funcţionare semnal PWM corect în fază

În acest mod de funcţionare TCNT0 este incrementat până atinge valoarea


0xFF. În acest moment TCNT0 începe să fie decrementat până ajunge la 0 după care
se reia ciclul.
Valoarea logică a pinului OC0 se modifică numai când TCNT0 este egal cu
valoarea de prag în timp ce creşte şi apoi în timp ce descreşte, aşa cum se poate vedea
în Figura 6.
În acest mod de funcţionare utilizatorul poate modifica oricând valoarea de
prag deoarece ea nu va fi transferată în modulul timer decât după ce TCNT0 a realizat
un ciclu complet de numărare.

Figura 6. Modul de funcţionare semnal PWM corect în fază

3. Modulul timer pe 16 biţi

Modulul timer pe 16 biţi poate fi utilizat pentru realizarea de temporizări,


numărarea evenimentelor externe sau generarea de forme de undă. În Figura 7 este
prezentată schema bloc a modulului timer. Dintre cele mai importante caracteristici
se pot menţiona:
- lucrează cu registre de 16 biţi
- două praguri independente de comparaţie
- unitate de captură evenimente
- posibilitate de auto-iniţializare
- posibilitate de generare facilă a semnalelor Pulse Width Modulation (PWM)

6
Figura 7. Schema bloc a modulului timer pe 16 biţi

Regiştrii alocaţi acestui timer pot fi împărţiţi în trei mari categorii:


- registrul de numărare: TCNT1H şi TCNT1L
- praguri de comparaţie: OCR1AL şi OCR1AH, OCR1BL şi OCR1BH,
ICR1H şi ICR1L
- comandă şi control: TCCR1A, TCCR1B, TIMSK şi TIFR

Conţinutul regiştrilor de comandă şi control este prezentat în Figura 8.

Figura 8. Conţinutul regiştrilor de comandă şi control ai timerului pe 16 biţi

Toţi regiştrii utilizaţi ca praguri de comparaţie şi registrul de numărare sunt de


16 biţi dar utilizatorul nu are acces direct la octeţii superiori şi inferiori ai acestora. În
schimb, se utilizează un registru temporar de 8 biţi invizibil pentru programator şi o
secvenţă specială de scriere şi citire.

7
Astfel, pentru a scrie o valoare în regiştrii de tip prag sau în cel de numărare,
se va scrie mai întâi partea superioară (de exemplu OCR1AH) şi apoi partea
inferioară (de exemplu OCR1AL). Când se citeşte o valoare din regiştrii de tip prag
ai timerului sau din cel de numărare, se va citi mai întâi partea inferioară şi apoi
partea superioară.
Modurile principale de funcţionare ale timerului de 16 biţi sunt:
- funcţionare normală
- re-iniţializare la atingerea valorii de prag (CTC)
- semnal PWM rapid
- semnal PWM corect în fază
- semnal PWM corect în fază şi frecvenţă

Biţii care selectează modul de funcţionare se regăsesc în regiştrii TCCR1A şi


TCCR1B. Rezultatul posibilelor combinaţii ale acestora este dat în Figura 9.

Figura 9. Setarea modului de funcţionare al timerului de 16 biţi

Toate modurile de funcţionare se bazează pe incrementarea sau decrementarea


automată a registrului de numărare TCNT1. Frecvenţa de incrementare/decrementare
este controlată de combinaţia biţilor CS12, CS11, CS10 din registrul TCCR1B
conform tabelului de mai jos (cu fosc s-a notat frecvenţa ceasului microcontrolerului).

CS12 CS11 CS10 Frecvenţa de inc/dec


0 0 0 timer oprit
0 0 1 fosc/1
0 1 0 fosc/8
0 1 1 fosc/64

8
1 0 0 fosc/256
1 0 1 fosc/1024
frecvenţa semnalului de pe pinul
1 1 0
T1, frontul descendent
frecvenţa semnalului de pe pinul
1 1 1
T1, frontul ascendent

În modurile de funcţionare normală şi re-iniţializare la atingerea valorii de prag


se poate utiliza unitatea de captură evenimente. Aceasta este controlată de tranziţiile
semnalului de pe pinul ICP1 sau cele ale ieşirii comparatorului analogic. Când se
produce o anumită tranziţie selectată de utilizator, unitatea de captură copiază
registrul TCNT1 (16 biţi) în registrul ICR1, obţinându-se astfel o amprentă temporală
a producerii evenimentului.
Dacă bitul TICIE1 din registrul TIMSK are valoarea 1, se va genera o
întrerupere când are loc copierea amprentei temporale.
Unitatea timer compară în permanenţă valoarea TCNT1 cu OCR1A şi
OCR1B. În modurile de funcţionare normală şi re-iniţializare la atingerea valorii de
prag, valoarea 1 a bitul OCIE1A sau OCIE1B din registrul TIMSK determină
generarea unei întreruperi când TCNT1 atinge valoarea registrului de prag OCR1A
respectiv OCR1B.
În vederea utilizării timerului pe 16 biţi, programatorul trebuie să prevadă o
secvenţă iniţială de cod pentru setarea parametrilor de funcţionare. Această secvenţă
trebuie să cuprindă cel puţin următorii paşi:
- dezactivarea globală a întreruperilor (folosind cli);
- setarea porturilor ce urmează a fi folosite, dacă este cazul;
- alegerea modului de funcţionare dorit prin modificarea biţilor
corespunzători din regiştrii de control. Se va avea în vedere să nu se
pornească timerul.
- iniţializarea cu o valoarea a registrului de numărare şi/sau a pragurilor, dacă
este cazul;
- activarea întreruperilor dorite prin modificarea biţilor corespunzători din
registrul TIMSK. Se va avea în vedere să nu se modifice biţii
corespunzători altui modul timer.
- pornirea timerului la frecvenţa dorită, având în vedere să nu se modifice
valoarea altor biţi din registrul de control;
- activarea globală a întreruperile folosind sei, dacă este cazul.

3.1. Modul de funcţionare normală

În acest mod valoarea TCNT1 este incrementată continuu la fiecare tact de


numărare. Când se atinge valoarea maximă reprezentabilă pe 16 biţi, TCNT1 ia
valoarea 0 şi apoi continuă să numere.
Dacă bitul TOIE1 din registrul TIMSK are valoarea 1, se va genera o
întrerupere când se atinge valoarea maximă reprezentabilă pe 16 biţi.

9
3.2. Modul de funcţionare cu re-iniţializare la atingerea valorii de prag (CTC)

În acest mod valoarea TCNT1 este incrementată la fiecare tact de numărare


până când devine egală cu OCR1A sau ICR1, în funcţie de setările făcute. În acest
moment, TCNT1 se re-iniţializează cu 0 şi numărătoarea reîncepe.
În funcţie de valorile biţilor COM1A1/COM1B1 şi COM1A0/COM1B0 din
registrul TCCRA, este posibil să se programeze modificarea nivelului logic al pinului
OC1A când TCNT1 atinge valoarea registrului de prag OCRA1/OCRB1. În acest caz
pinul respectiv trebuie setat ca ieşire.

3.3. Modul de funcţionare semnal PWM rapid

În acest mod de funcţionare, TCNT1 este incrementat, în funcţie de setări, până


atinge una din valorile 0x00FF, 0x01FF, 0x03FF, valoarea din ICR1 sau cea din
OCR1A. În acest moment se iniţializează TCNT1 cu 0 şi se reia numărătoarea.
Valoarea logică a pinilor OC1A sau OC1B se modifică numai când TCNT1
este egal cu o valoare de prag şi când ajunge la valoarea maximă, aşa cum se poate
vedea în Figura 10.
În acest mod de funcţionare, când TCNT1 este setat să numere până la valoarea
registrului OCR1A, utilizatorul o poate modifica oricând deoarece ea nu va fi
transferată în modulul timer decât după ce TCNT1 a realizat un ciclu complet de
numărare.

Figura 10. Modul de funcţionare semnal PWM rapid

3.4. Modul de funcţionare semnal PWM corect în fază

În acest mod de funcţionare, TCNT1 este incrementat, în funcţie de setări, până


atinge una din valorile 0x00FF, 0x01FF, 0x03FF, valoarea din ICR1 sau cea din
OCR1A. În acest moment TCNT1 începe să fie decrementat până ajunge la 0 după
care se reia ciclul.
Valoarea logică a pinilor OC1A sau OC1B se modifică numai când TCNT1
este egal cu o valoare de prag în timp ce creşte şi apoi în timp ce descreşte, aşa cum
se poate vedea în Figura 11.

10
În acest mod de funcţionare, când TCNT1 este setat să numere până la valoarea
registrului OCR1A, utilizatorul o poate modifica oricând deoarece ea nu va fi
transferată în modulul timer decât după ce TCNT1 a ajuns la valoarea maximă.

Figura 11. Modul de funcţionare semnal PWM corect în fază

3.5. Modul de funcţionare semnal PWM corect în fază şi frecvenţă

În acest mod de funcţionare, TCNT1 este incrementat, în funcţie de setări, până


atinge valoarea din ICR1 sau cea din OCR1A. În acest moment TCNT1 începe să fie
decrementat până ajunge la 0 după care se reia ciclul.
Valoarea logică a pinilor OC1A sau OC1B se modifică numai când TCNT1
este egal cu o valoare de prag în timp ce creşte şi apoi în timp ce descreşte, aşa cum
se poate vedea în Figura 12.
În acest mod de funcţionare, când TCNT1 este setat să numere până la valoarea
registrului OCR1A, utilizatorul o poate modifica oricând deoarece ea nu va fi
transferată în modulul timer decât după ce TCNT1 a terminat un ciclu.

Figura 12. Modul de funcţionare semnal PWM corect în fază şi frecvenţă

11
4. Exemple de programe
a) Să se scrie un program care generează pe pinul OC0 (PB3) un semnal dreptunghiular cu
frecvenţa de aproximativ 15 Hz şi factor de umplere 50%.

START

Setare porturi

Setare Timer 0

Buclă infinită

.include "[Link]"
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
reset:
ldi r16,high(RAMEND)
out SPH,r16
ldi r16,low(RAMEND)
out SPL,r16
ldi r16,0xFF
out DDRB,r16 ; OC0 este pe pinul PB3
main:
cli ;dezactivare intreruperi
ldi r16,0b00011000 ;setare timer: se utilizeaza pinul OC0, timerul este oprit deocamdata
out TCCR0,r16 ;modul va fi CTC cu prag dat de OCR0
in r16, TIMSK
andi r16,0b11111100 ;nu se utiliz. nici o intrer., fara a modifica alti biti din TIMSK
out TIMSK, r16
ldi r16, 0xFA ;se incarca valoarea de prag: 0xFA=250
out OCR0,r16 ;250 * 1/(8MHz/1024) =~ 32ms
in r16,TCCR0
andi r16,0b11111101 ;se porneste timerul si este setat sa numere
ori r16,0b00000101 ;la fiecare 1024 perioade de ceas, fara a modifica alti biti
out TCCR0,r16
bucla:
rjmp bucla

12
b) Să se scrie un program care într-un interval de aproximativ 8s efectuează următoarele operaţii:
după 2s aprinde ledurile portului A, după 6,5s aprinde ledurile portului C iar la finalul
intervalului stinge toate ledurile.

START

Setare porturi

Setare Timer 1

S-a produs
întrerupere
DA Aprinde
leduri port A
la prag A?

NU

S-a produs
întrerupere
DA Aprinde
leduri port C
la prag B?

NU

S-a produs
DA Stinge leduri
întrerupere
port A şi C
la val. max?

Pre-iniţializare
contor Timer 1
NU

.include "[Link]"
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp prag_2sec
jmp prag_6_5sec
jmp prag_8sec
jmp reset

13
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
reset:
ldi r16,high(RAMEND)
out SPH,r16
ldi r16,low(RAMEND)
out SPL,r16
ldi r16,0xFF
out DDRA,r16
out DDRC,r16
main:
cli ;dezactivare globala intreruperi
ldi r16,0b00000000 ;setare timer: nu se utiliz. OC1A si OC1B, oprit deocamdata
out TCCR1A,r16 ;modul va fi normal
ldi r16,0b00000000
out TCCR1B,r16
in r16, TIMSK
andi r16,0b11000011
ori r16,0b00011100 ;se utiliz. toate intreruperile, fara a modifica alti biti din TIMSK
out TIMSK, r16
ldi r16, 0x3D ;se incarca valoarea de prag A: 0x3D09=15625
out OCR1AH,r16 ;15625 * 1/(8MHz/1024) =~ 2s
ldi r16, 0x09
out OCR1AL,r16
ldi r16, 0xC6 ;se incarca valoarea de prag: 0xC65D=50781
out OCR1BH,r16 ;50781 * 1/(8MHz/1024) =~ 6,5s
ldi r16, 0x5D
out OCR1BL,r16
ldi r16, 0x0B ;se incarca o valoarea initiala: 0x0BDB=3035 si 65535-3035=62500
out TCNT1H,r16 ;62500 * 1/(8MHz/1024) = 8s
ldi r16, 0xDB
out TCNT1L,r16

in r16,TCCR1B
andi r16,0b11111101 ;se porneste timerul care va numara la 1024 impulsuri de ceas
ori r16,0b00000101
out TCCR1B,r16
sei ;activare globala a intreruperilor
bucla:
rjmp bucla

prag_2sec:
in r20, SREG
ldi r18,0xFF
out PORTA,r18
out SREG,r20
reti

prag_6_5sec:
in r20, SREG
ldi r18,0xFF
out PORTC,r18
out SREG,r20
reti

prag_8sec:
in r20, SREG
ldi r18,0x00
out PORTA,r18
out PORTC,r18
ldi r16, 0x0B ;se incarca o valoarea initiala: 0x0BDB=3035 si 65535-3035=62500
out TCNT1H,r16 ;62500 * 1/(8MHz/1024) = 8s

14
ldi r16, 0xDB
out TCNT1L,r16
out SREG,r20
reti

c) Să se scrie un program care schimbă starea ledului conectat pe pinul PA7 dacă s-a ţinut apăsat
cel puţin 6s pe butonul conectat pe PC7.

START

Setare porturi

Setare timere

Resetare contor
secunde (r18)

S-a produs Se
întrerupere prag
DA apasă
DA
A Timer 1? PC7?

Inc. r18
NU NU

S-a produs
NU întrerupere val. DA
max Timer 0?

Se
DA NU
apasă
PC7?

r18≥6?
DA
Timer
Resetare NU 1
contor Timer 1
pornit?
NU Schimbare
stare PA0
Pornire
Timer 1
DA
Resetare r18

Oprire Timer 1

15
.include "[Link]"
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp prag_1sec
jmp reset
jmp reset
jmp reset
jmp scanare_butoane ;la fiecare 32ms se verifica starea butonului
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
jmp reset
reset:
ldi r16,high(RAMEND)
out SPH,r16
ldi r16,low(RAMEND)
out SPL,r16
ldi r16,0x00
out DDRC,r16
ldi r16,0xFF
out DDRA,r16
out PORTC,r16
ldi r18,0x00 ;r18 este contorul de secunde
main:
cli ;dezactivare globala intreruperi
ldi r16,0b00000000 ;setare timer: nu se utiliz. OC1A si OC1B, oprit deocamdata
out TCCR1A,r16 ;modul va fi CTC
ldi r16,0b00001000
out TCCR1B,r16
in r16, TIMSK
andi r16,0b11000011
ori r16,0b00010000 ;se utiliz. doar intrer. prag A fara a modifica alti biti din TIMSK
out TIMSK, r16
ldi r16, 0x7A ;se incarca valoarea de prag A: 0x7A12=31250
out OCR1AH,r16 ;31250 * 1/(8MHz/256) = 1s
ldi r16, 0x12
out OCR1AL,r16

ldi r16,0b00000000 ;setare timer0: nu se utiliz OC0, oprit deocamdata


out TCCR0,r16 ;modul va fi normal
in r16, TIMSK
andi r16,0b11111100 ;se utiliz. intrer. la depasire,
ori r16,0b00000001 ;fara a modifica alti biti din TIMSK
out TIMSK, r16
in r16,TCCR0
andi r16,0b11111101 ;se porneste timerul si este setat sa numere
ori r16,0b00000101 ;la fiecare 1024 perioade de ceas, fara a modifica alti biti
out TCCR0,r16 ; va ajunge la val max. in aprox 32ms
sei ;activare globala a intreruperilor
bucla:
rjmp bucla

scanare_butoane:
in r20, SREG
in r16,PINC
sbrc r16,PC7 ;verific daca se apasa pe buton
rjmp turn_off
in r16,TCCR1B
mov r17,r16
andi r17,0b00000111

16
cpi r17,0b00000100 ;daca timerul e deja pornit nu il mai pornesc
breq end
ldi r17,0x00
out TCNT1H,r17
out TCNT1L,r17 ;inainte de o noua pornire se reseteaza
andi r16,0b11111000 ;se porneste timerul cu numarare la fiecare 256 impulsuri de ceas
ori r16,0b00000100
out TCCR1B,r16
rjmp end
turn_off:
cpi r18,6 ;s-a tinut apasat cel putin 6s ?
brlo end1 ;nu, se opreste timer si se iese din intrerupere
in r16,PINA ;am tinut apasat cel putin 6s, citesc starea ledului
ldi r17,0b10000000 ; ca sa o pot schimba
eor r16,r17
out PORTA, r16 ;trimit noua stare a ledului
end1:
ldi r18,0x00 ;pregatesc contorul pt. o noua numarare
in r16,TCCR1B
andi r16,0xF8
out TCCR1B,r16
end:
out SREG,r20
reti

prag_1sec:
in r20, SREG
in r16,PINC
sbrs r16,PC7 ;verific daca inca se mai apasa pe buton
inc r18
out SREG,r20
reti

5. Teme şi exerciţii

a) Să se scrie un program care generează pe pinul OC1A (PD5) un semnal dreptunghiular cu


frecvenţa de 0,5 Hz şi factor de umplere 50%.
b) Să se scrie un program care numără câte secunde s-a ţinut apăsat pe butonul conectat pe PB6
sau cel conectat pe PC5 şi reflectă reprezentarea binară a acestui număr pe portul A respectiv
portul D.

17

S-ar putea să vă placă și