Curs de formare avr

De fapt, temporizatorul microcontrolerului este un contor digital, numai "sofisticat". Intrarea ceasului este alimentată la intrarea contorului, contorul își mărește valoarea în funcție de fluctuațiile contorului. Când apar evenimente - contorul este depășit sau valoarea sa este aceeași cu cea specificată - este generată o cerere de întrerupere.







Să aruncăm o privire asupra modului de utilizare a cronometrului T0 în modul Normal. În acest mod, temporizatorul contorizează de la o valoare inițială a registrului de numărare la cel maxim posibil (până la 255 sau 0xFF). Când temporizatorul T0 contează până la maxim, următorul ciclu temporizator Contor registru preaplinul apare TCNT0 - este resetată, iar steagul este setat TOV0. În cazul în care întreruperile globale de program activat (pavilion SREG registru I) și întrerup T0 depășirea timer-ului (TOIE0 TIMSK pavilion registru), microcontrolerul va provoca handler corespunzătoare. Dacă valoarea contorului registru se potrivește comparația înregistrare OCR0, consacrat, pavilion OCF0 și întrerupe permit eveniment coincidență, handler său de pornire.

Să luăm în considerare o problemă practică - trebuie să cercetăm butonul la fiecare 20 ms. Frecvența microcontrolerului este de 8 MHz, microcontrolerul este ATmega16.

Primul lucru pe care trebuie să-l faceți este să determinați alegerea prescalerului de timer și să calculați valoarea inițială pentru registrul de registru TCNT0.

Timerul T0 poate fi cronometrat de semnalul ceasului intern al microcontrolerului sau de cel extern, care este alimentat la terminalul T0. Când se utilizează un semnal de ceas intern, utilizatorul poate selecta factorii de divizare a frecvenței pentru acest semnal. Timerul T0 are cinci opțiuni posibile pentru raportul prescaler - 1, 8, 64, 256, 1024.

Pentru a rezolva această problemă, susțin următoarele. Dacă un ciclu de ceas T0 a avut o perioadă de 1 ms, atunci aș fi avut-o. 20 de cicluri dau 20 ms. Care factor de prescaler al temporizatorului va permite obținerea unei perioade de frecvență a ceasului de aproape 1 ms? Poți conta.

Frecvența tactului microcontrolerului Fcpu = 8000000 Hz
Perioada de ceas a microcontrolerului Tcpu = 1 / Fcpu
Perioada de ceas a timerului T0 este Tt0 = (1 / Fcpu) / k = k / Fcpu

Cu k = 1024, perioada frecvenței ceasului timerului T0 va fi Tt0 = 1024/8000000 = 0,128 ms

Aceasta este perioada maximă a semnalului de ceas al timerului pe care îl putem obține în condițiile noastre (Fcpu = 8 MHz). Cu coeficienți mai mici, perioada este chiar mai mică.

Ei bine, lasati un ceas al timerului sa fie 0.128 ms, este numarul de registru suficient pentru a conta acest interval de timp si cate cicluri pentru aceasta? Împărțim intervalul de timp necesar (20 ms) pe durata unui ciclu de ceas și obține răspunsul.

n = t / Tto = 20 ms / 0,128 ms = 156,25

Rotunjit la ansamblu, primim 156 de măsuri. Aceasta este mai mică de 255 (valoarea maximă a registrului de registru), astfel încât numărul contabilului de numărare TCNT0 este suficient.

Valoarea inițială pentru TCNT0 registru de numărare calculate ca diferența dintre numărul maxim de cicluri necesare și T0 timer, adică 256 - 156 = 100 (256 - numărul maxim de sloturi care se poate conta, fie cronometrul de 8 biți).







Cred că acum este clar cum se calculează valoarea inițială a TCNT0 pentru modul Normal:

- calculați perioada unui singur ciclu de ceas Tt0 = k / Fcpu,
- calcula numărul necesar de cicluri pentru un interval dat n = t / Tto,
- calcula valoarea inițială pentru registrul de numărare TCNT0 = 256 - n.

Puteți automatiza această procedură cu macrocomenzi. De exemplu, aceasta:

Dar cu o astfel de macrocomandă trebuie să fii atent, cu anumite valori ale timpului și pot să apară erori k.

Acum mergeți la cod. Pentru a utiliza temporizatorul T0 (și oricare altul), trebuie să configurați (inițializați) și să descrieți procedura de întrerupere (dacă sunt utilizate).

Inițializarea timerului constă în următoarele etape:

- stop timer,
- Setarea modului Normal la TCCR0 fără pornire,
- stabilirea valorii inițiale a TCNT0,
- resetarea steagurilor din registrul TIFR,
- care să permită întreruperea debitului în TIMSK,
- setarea prescalerului în TCCR0, adică pornirea cronometrului

Sunt posibile variații în această secvență.

Pentru sarcina noastră, codul de inițializare va arăta astfel:

A doua linie de inițializare, de fapt, este inutilă, este adăugată pentru claritate. Pentru a vedea clar ce mod de temporizare este setat.

Steagurile de întrerupere din registrul TIFR sunt resetate prin scrierea 1 pe bitul corespunzător. Această operație trebuie efectuată prin suprascrierea registrului, nu prin bitul OR. Și de asta.

Să presupunem că în registrul TIFR sunt setate două pavilioane de întrerupere - TOV1 și TOV0. TOV0 trebuie să resetăm. Când setați descărcarea necesară folosind OR, se întâmplă următorul lucru.

Drept urmare, ambele steaguri sunt abandonate și am vrut să reinițializăm una.

Sintaxa pentru descrierea procesatorilor de întrerupere pentru compilarele diferite este puțin diferită. Pentru IAR'a manipulatorul de întrerupere al temporizatorului T0 pentru suprapunerea evenimentului va arăta astfel:

Prima linie a handlerului (TCNT0 = T_POLL;) suprascrie registrul de registru, apoi își stabilește valoarea inițială. Dacă nu faceți acest lucru, cronometrul va continua să conta de la 0. Pentru a suprascrie registrul de contor, trebuie să rulați la începutul procesului de întrerupere.

Tot codul pentru sarcina noastră va arăta așa. (Codul este pentru IAR `.Pentru alte compilatoare, trebuie să modificați fișierele antet și procedura de întrerupere.)

În modul Normal, timerul T0 poate schimba starea ieșirii OC0 atunci când registrul de numărare și registrul comparațional se potrivesc. Și chiar fără întreruperi. Opțiunile de control sunt definite de biții COM01 și COM00 din registrul TCCR0.

Curs de formare avr


Iată un exemplu de program care generează un semnal dreptunghiular pe ieșirea OS0.

Ieșirea OS0 își va schimba starea la contrariul cu o valoare zero a registrului de registru.

Operatorul de întrerupere al temporizatorului (și orice alte periferice) trebuie să fie cât mai scurt posibil.

Dacă valoarea calculată pentru registrul de numărare (sau registrul de comparație) este rotunjită, intervalul de timp va fi luat în calcul de cronometrul cu o eroare.

Dacă doriți să contorizați un interval lung de timp, este posibil ca temporizatorul să nu fie suficient. În acest caz, trebuie să utilizați fie un cronometru pe 16 biți, fie un cronometru software.

Și ultimul. Este posibil să existe o situație în care procesarea întreruperii temporizatorului va fi întârziată (de exemplu, din cauza unei erori a altui operator), iar registrul TCNT0 va conta deja câteva cicluri de ceas. Dacă purtați pur și simplu valoarea TCNT0, următoarea întrerupere va fi apelată mai târziu decât este necesar. Se pare că întreruperile anterioare (întârziate) și noi nu vor supraviețui intervalului necesar.

Această situație poate fi netezită prin efectuarea unei rescrieri a registrului de registru, astfel:

TCNT0 = TCNT0 + startValue;

Adăugarea valorii actuale a registrului de registru cu registrul inițializat va lua în considerare aceste măsuri suplimentare. Adevărul este unul DAR! Dacă valoarea startValue este mare, operația de adăugare poate determina depășirea registrului de numere.

De exemplu, startValue = 250 și cronometrul a reușit să ajungă la 10. Apoi operația de adăugare va duce la acest rezultat:

Luăm 8 cifre de la 260 pentru a obține 4. TCNT0 va scrie 4.

Curs de formare AVR. Timerul este contorul T0. Registre. n1


Curs de formare avr







Articole similare

Trimiteți-le prietenilor: