luni, 15 noiembrie 2010

Modulul Timer

Lucrarea de laborator Nr. 5

 

Tema: Modulul periferic Timer

Scopul lucrării: Utilizarea TIMERULUI în rezolvarea problemelor ce ţin de măsurarea timpului, executarea unor acţiuni la anumite intervale de timp.

Expunerea problemei: Să se elaboreze un sistem bazat pe microprocesoare care să afişeze conţinutul unui tablou pe un afişor bazat pe un set de opt afişoare cu şapte segmente. Să se utilizeze Timer 0 pentru a genera semnalul de selecţie a afişorului.


Consideraţii teoretice: Microcontrollerele familiei AVR au de la 2 la 4 contoare de timp de uz general, în dependenţă de model (tab.1)

Tabel 1. Timere/contoare de uz general

După cum se observă din tabel, în toate modelele familiei ATmega există, cel puţin, două timere/contoare – T0 şi T1. Timer/contor T0 are setul minimal de funcţii, care însă depinde de modelul micorcontrollerului. În unele modele el poate fi utilizat doar pentru numărarea şi măsurarea intervalelor de timp sau contor de evenimente externe. În unele modele la aceste funcţionalităţi se adaugă şi posibilatea generării de semnale cu modulare în lungimea pulsului (PWM - Pulse Width Modulation) cu o rezoluţie fixă, şi posibilitatea de lucru în regim asincron în calitate de ceas al timpului real.
Timer/contor-ul T1 de asemenea poate fi utilizat pentru numărarea intervalelor de timp şi ca contor al evenimentelor externe. În afară de aceea, el poate memora starea sa în dependenţă de semnale externe. Ca şi timer/contor-ul T0, el poate lucra în regim PWM, dar deja cu o rezoluţie variabilă şi cu mai multe canale (numărul de canale depinde de model).
Timer/contor-ul T2 e absolut analogic timer/contor-ului T0. Dacă în microcontroller sunt prezenţi ambii timer/contori, unul poate lucra în regim asincron, altul – în calitate de contor a evenimentelor externe. Timer/contor-ul T3 după posibilităţile funcţionale e identic timer/contor-ului T1.
Întreruperea TIMER
Modulul de întrerupere timer este un modul periferic inclus în majoritatea controllerelor seriei AVR, care la rândul său poate conţine de la 1 până la 3 module TIMER.
Modulul TIMER de regulă se foloseşte pentru măsurarea timpului. În cazul când avem nevoie de măsurat frecvenţa, generarea unui semnal de o anumită frecvenţă şi alte efecte ce presupun folosirea timpului, se recomandă aplicarea modului TIMER. Componen ţa principală al acestui modul este registrul numărător TCNT.
Modulele Timer/Conters
Modulul de timer este cel mai fregvent modul utilizat. Un microntroller poate conţine de la 1 – 3 timere. Un modul timer are la bază un numărător care incrementează un registru, acest registru numărător poate fi de 8 sau 16 biţi. Modulul timer 0 se poate utiliza pentru formarea intervalelor între generarea întreruperii de timp.
Situaţia de întrerupere va fi provocată la supraîncărcarea registrului contor. Odată întreruperea generată poate chema o funcţie de prelucrare a ei.
ATmega16 dispune de două numărătoare/timere de uz general, unul de 8 biţi şi unul de 16 biţi. Fiecăruia i se poate selecta o valoare individuală pentru prescaler din acelaşi prescaler de 10 biţi. Ambele module pot fi folosite ca timere cu un clock generat intern sau ca numărătoare cu un clock extern de la un pin I/O. Cele 4 valori pentru prescaler sunt CK/8, CK/64, CK/256 şi CK/1024 unde CK este clock-ul dat de oscilatorul extern. Ambele timere pot genera întreruperi ale căror biţi de validare se află în registrul Timer/Counter Interrupt Mask Register (TIMSK) şi ale căror flaguri de întrerupere se află in registrul Timer/Counter Interrupt Flag Register (TIFR).
Timer/Counter0 este un numărător pe 8 biţi. Registrul de control al acestuia este Timer/Counter0 Control Register (TCCR0) din care se setează valoarea prescalerului, ceasul intern sau extern şi starea pornit/oprit a modulului. La trecerea din 0xFF în 0x00 flagul overflow este setat şi este generată întreruperea TMR0_OVR dacă aceasta este validată. Ceasul extern este sincronizat cu oscilatorul microcontrollerului. Pentru a asigura o numărare corectă a impulsurilor externe, durata dintre două tranziţii ale clock-ului extern trebuie să fie mai mare ca perioada oscilatorului microcontrolerului.
Timer/Counter1 este un numărător pe 16 biţi. Registrele de control ale acestuia sunt Timer/Counter1 Control Registers (TCCR1A and TCCR1B). Diferite flaguri de stare (overflow, captura unui eveniment, etc) se află în registrul Timer/Counter Interrupt Flag Register (TIFR). De asemenea ceasul extern trebuie să îndeplinească condiţia ca perioada dintre două tranziţii să fie mai mare decât perioada oscilatorului microcontrollerului pentru a asigura o funcţionare corectă a modulului.
Modulul Timer/Counter1 suportă funcţia de comparare folosind registrele Output Compare Register 1 A şi B (OCR1A şi OCR1B) pe care le compară cu registrul TCNT1. Funcţiile de comparare includ resetarea numărătorului la egalitatea cu registrul OCR1A sau alte acţiuni pe pinii de ieşire la egalitatea cu ambele registre A şi B. Modulul poate fi utilizat şi ca modulator de impulsuri în durată pe 8, 9 sau 10 biţi. De asemnea funcţia Input Capture poate salva conţinutul TCNT1 în registrul Input Capture Register (ICR1) la apariţia unui eveniment extern pe pinul de captură ICP. Setările evenimentului de captură sunt definite de registrul Timer/Counter1 Control Registers B (TCCR1B). În plus modulul Analog Comparator poate genera evenimentul de captură.
Pentru configurarea modulului Timer/Counter0 se utilizează registrul TCCR0, iar pentru a configura frecvenţa apariţiilor situaţiilor de întrerupere se va seta prescalerul ce se află în TCCR0.


CS02, CS01, CS00 - cu ajutorul lor vom seta viteza de progresie a timerului.

Tabelul de adevăr:
T0 - frontul negativ a pinului T0.

Situaţia de întrerupere va fi generată la supraîncărcarea registrului TCNT0.


Fig.1 Prezentarea grafică a funcţionării Timerului.

Pentru a configura fregvenţa apariţiei situaţiei de intrerupere se va seta prescalerul care se configura în TCCR0.
Pentru a seta mai fin întreruperea trebuie de reiniţializat registrul TCNT la fiecare întrerupere.
Pentru a organiza un sistem care va utiliza întreruperea de Timer trebuie să:
  • validăm utilizarea modulului întreruperii din registrul TIMSK;
  • înregistrăm în vectorul de întreruperi chemarea funcţiei de prelucrare a întreruperii;
  • descriem subrutina de prelucrare a întreruperii;
Fiecare modul periferic are regiştri in spaţiu de 64 I/O. Comunicaţia modulelor periferice are loc prin intermediul acestor regiştri. Există 3 tipuri de regiştri periferice:
  • TCNT0 - de date (transfer de date dintre nucleu şi periferie)
  • TCCR0 - de configurare (se utilizează pentru configurarea modulului periferic)
  • TIFR, TIMSK - de fanioane(reprezintă starea curenta a modulului periferic)
Regiştri de multe ori sunt combinaţi cei de configurare şi fanioane. Registrul TCNT (timer counter) conţine 8 biţi. Trecerea valorii registrului de numărare de la valoarea maximală în zero, se numeşte supraîncărcare/depăşire (overflow). Evenimentul de supraîncărcare este legat cu modulul de întrerupere a timer-ului. Când are loc depăşirea , se setează un bit TIFR.TOUF0 în 1.
Frecvenţa apariţiei întreruperii Timer overflow poate fi reglată prin:
  • Reglarea prin setarea divizorului de la semnalul de clock pentru sursa de încrementare.
  • Setarea valorii iniţiale.
Regimurile de lucru ale Modulul TIMER
Modulul TIMER poate lucra în mai multe regimuri:
1)  Numărător – destinat lucrului cu timpul.
2)  Imput Capture – capturarea intrării care presupune determinarea apariţiei unui eveniment extern. Principala sarcină a unităţii de capturare la intrare este de a pune la dispoziţie suficientă memorie din cea a procesorului pentru apariţia de evenimente eventuale. Timpul dintre două evenimente este critic. Dacă procesorul nu a citit valoarea asociată capturii în Registrul ICR1, înainte de apariţia unui nou eveniment ICR1 va fi suprascris cu o nouă valoare. În acest caz valoarea asociată capturii va fi incorectă. Utilizând input capture interrupt, registrul ICR1 poate fi citit înaintea producerii rutinei întreruperilor. Chiar dacă input capture interrupt are prioritate ridicată, timpul maxim de răspuns la întrerupere depinde de numărul maxim de cicluri necesare tratării unei cereri de întrerupere. Durata unui ciclu pentru un semnal extern impune ca declanşatorul de nivel să fie schimbat după fiecare captură.
3) Output Capture – modul în care se poate genera un semnal extern la coincidenţa registrului timer cu o valoare prestabilită. Comparatorul pe 16 biţi compară TCNT1 cu ieşirea registrului Output Compare Register (OCR1x). Dacă TCNT este egal cu OCR1x comparatorul semnalizează o potrivire. Aceasta setează Output Compare Flag (OCF1x) pentru următorul ciclu de ceas. Dacă OCIE1x =1, Output Compare flag generează o ieşire output compare interrupt. OCF1x flag este dezactivat automat atunci când se execută o întrerupere. OCF1x flag poate fi de asemenea dezactivat prin trecerea în ‘1’ logic a bitului I/O. Ţinând cont că scrierea lui TCNT1 în orice mod de operare va bloca orice comparare pentru un singur ciclu de ceas, există riscuri la schimbarea unuia din canalele output compare ale lui TCNT1 indiferent dacă Timer/Counter este pornit sau oprit. Dacă TCNT1 este egal cu OCR1x rezultatul comparării va fi pierdut, generându-se o formă de undă greşită.
4) Puls Width Modulation (PWM) – modulaţia impulsurilor de durată. Permite modularea unui semnal cu bandă reglabilă, modulată.
Watch Dog Timer
Microcontrollerul seriei AVR are inclus în componenţa sa modulul Watch Dog, ce permite resetarea sistemului în caz de un comportament de ciclare al său.
Mersul lucrării:
Pentru implementarea problemei propuse în cadrul lucrării, avem nevoie de un algoritm în baza căruia vom efectua unele calcule. Pentru afişarea conţinutului unui tablou pe un afişor bazat pe un set de opt afişoare cu şapte segmente am avea nevoie de 8 x 7 = 56 de pini, dacă pentru fiecare segment am utiliza un pin, ceea ce ar fi utilizarea neraţională a microcontrollerului, iar dacă să luăm în consideraţie că microcontrollerele nu posedă atâţia pini, aceasta nici nu pare a fi real.
În continuare vom construi o schemă şi vom scrie un program pentru ea, astfel încât vor fi nevoie doar de 16 pini, sau 2 porturi intrare/ieşire. Pinii primului port (PORA) vor fi uniţi cu segmentele afişoare, astfel încât pinul zero e unit cu segmentul “a” de la toate afişoarele, pinul unu – segmentul “b” de la toate afişoarele ş.a.m.d. pe când pinii celuilalt port (PORTB) sunt uniţi la catodurile afişorilor, fiecare pin la un catod respectiv. În aşa mod, PORTA determină ce va fi afişat in PORTB.
Afişarea se va face pe rând, câte un element al tabloului la un timp. Pentru ca microcontrollerul să nu fie ocupat doar cu afişarea, vom utilza un timer, cu ajutorul căruia vom seta o frecvenţă de împrospătare a afişorului, aproximativ de 25Hz, destul pentru ca ochiul uman să nu perceapă schimbări.
Deci afişarea indicatorilor se va face cu frecvenţa 25Hz x 8 = 400Hz sau la fiecare 2,5ms.
Microcontrollerul va lucra cu frecvenţa 4Mhz, deci un tact de sistemă va dura 0.25μs. Selectăm prescalerul timerului T0 ca 256, deci frecvenţa sa va fi fTO=1526, iar fiecare incrementare va avea loc la fiecare 64μs. Deci întreruperea trebuie să apară odată la 2500μs / 64μs = 39.0625 ≈ 39 incrementări, valoare care va fi introdusă în registrul OC0, astfel timerul/contorul T0, la fiecare 39 incrementări va genera o întrerupere.
1)  Imlementăm algoritmul şi construi schema- bloc a programului:






2) Următorul pas este crearea ciruitului în programul de simulare PROTEUS, în baza algoritmului prezentat în punctul 1. Aici,  cu ajutorul programului care se va creea, se va verifica funcţionalitatea programului şi aschemei.


Fig. 2 Scheme electrică

3)  În baza schemei-bloc creem listingul programului:
    ...


4) Compilarea programului, şi verificarea funcţionării sale (executării) pas cu pas cu scopul de a găsi şi elimina erorile.
5) Ultimul pas este simularea circuitului creat în PROTEUS, corecţia acestuia în caz de necesitate, în urma căreia ne putem convinge că programul funcţionează corect şi că microcontrollerul execută toate comenzile cu exactitate, obţinînd rezultatul dorit.
Descrierea instrucţiunilor utilizate:
ST(Store Indiret) - operanzii X, Rr, comanda stochează in mod indirect (Y)<-Rr;
ST(Store Indirect and post increment) – operanzii X+, Rr, comanda stocează in mod indirect apoi efectuiaza post incrementare Rd<-( Y), Y <-Y+1;
ST(Store Indirect and pre decrement) – operanzii X-, Rr, comanda stochează indirect apoi pre-decrementează Rd<-(Y), Y<-Y-1;
ADIW(Add immediate to work) – operanzii Rd, k, comanda efectuiază adunarea constantei cu un cuvînt Rdh:Rd<- Rdh:Rdl+K;
MOV(Copy Register) – operanzii Rd, Rr, comandaefectuiază copierea registrului Rd<-Rr;