duminică, 28 august 2011

Timere-le Timer 1

Timer-ul 1 funcţionează exact ca timerul 0 singura diferenţă fiind că regiştrii sunt pe 16 biţi.Timerul 1 are mai multe facilităţi, el putând fi folosit ca şi comparator la ieşire şi la intrare, generator de frecvenţă,generator de semnale PWM şi numărător de evenimente externe.
Momentan ne vom concentra asupra modului standard de folosire ca numărător.Numărătorul liber central este reprezentat de registrul TCNT1:
Acest registru este împărţit în doi regiştrii de 8 biţi,TCNT1H şi TCNT1L.La scrierea acestui registru trebuie mai întâi să scriem registrul TCNT1H apoi TCNT1L.Citirea se face exact invers citind mai întâi registrul TCNT1L apoi registrul TCNT1H.Aceste reguli sunt utile pentru păstrarea cât mai mare a preciziei NLC-ului deoarece el se incrementează şi în momentul operaţiei de scriere sau citire.Folosind un compilator în C citirea şi scrierea se face folosind o singură variabilă însă procesorul va face aceste operaţii în doi paşi.Acest lucru este periculos atunci când o rutină de tratare a unei întreruperi a fost lansată în timpul citirii sau scrierii acestui registru.Pentru a înlătura această problemă înainte de a efectua o operaţie cu regiştrii de 16 biţi se blochează sistemul de întreruperi.De exemplu în C codul necesar pentru o citire sigură arată cam aşa:

unsigned char
sreg;
unsigned int i;
//salveaza starea registrului SREG
sreg = SREG;
#asm
cli; opreste sistemul de intreruperi
#endasm
// copiaza TCNT1 in variabila i
i = TCNT1;
//pornim sistemul de intreruperi
SREG = sreg;

Un alt registru important pentru setarea caracteristicilor numărătorului este registrul de control TCCR1B:
Biţii 7 şi 6 sunt folosiţi pentru captura la intrare , bitul 5 este un bit rezervat iar biţii 4 şi 3 sunt folosiţi pentru comparatoare.Biţii 2:0 sunt cei care ne interesează mai mult deoarece prin ei setăm selecţia sau prescalarea ceasului:

CS12 CS11 CS10 Sursă/Prescalare
000-timerul este oprit;
001-ceasul intern fară prescalare;
010-ceasul intern prescalat cu 8;
011-ceasul intern prescalat cu 64;
100-ceasul intern prescalat cu 256;
101-ceasul intern prescalat cu 1024;
110-sursă externă a tactului la pinul T1,incrementare pe frontul descrescător;
111-sursă externă a tactului la pinul T1,incrementare pe frontul crescător;
Dacă dorim să folosim şi sistemul de întreruperi va trebui să folosim registrul TIMSK:
Pentru ca timerul să genereze o întrerupere la supraîncărcarea registrului TCNT1 trebuie să se permită folosirea sistemului de întreruperi şi trebuie ca bitul 2 din registru, bitul TOIE, să fie 1.Cererea de întrerupere este marcată în registrul TIFR prin bitul TOV1:
Dacă se generează o cerere de întrerupere bitul TOV1 devine 0 el fiind automat setat cu valoarea 1.După ce este executată rutina de tratare a întreruperii bitul se setează automat 1.

În exemplu următor vom avea un LED conectat la microcontroler care îşi va schimba starea la intervalul de 5 secunde.LED-ul va fi conectat la pinul 0 al portului B.Programul îl puteţi downloada de la secţiunea Download- Timer1- Aplicaţia1.Schema electrică este una simplă:

Calculul frecvenţei de numărare a NLC-ului se face ca la timer 1 însă se va lua în calcul că numărătorul este pe 16 biţi:

În CodeVision AVR va trebui să aveţi următoarea setare a timerului 1 pe lângă setarea pinului 0 al portului B:

Partea în care se întâmplă toată acţiunea este reprezentată de rutina de tratare a întreruperii generate de supraîncărcarea NLC-ului:

interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// setarea valorilor NLC-ului
#asm
cli
#endasm

TCNT1H=0x4C;
TCNT1L=0x4B;
#asm
sei
#endasm
//schimbarea starii portului
PORTB.0 = ~PORTB.0;
}
În această rutină nu facem altceva decât să initializăm TCNT-ul şi să schimbăm valoarea portului B.
Cam atât despre timerul 1 momentan.

0 comentarii:

Trimiteți un comentariu

Twitter Delicious Facebook Digg Stumbleupon Favorites More