Exemplu de setare și de lucru cu cronometrul în avr, mainloop

În microcontrolerele avr există un astfel de modul periferic ca contorul temporizatorului. După numele său, el consideră timpul. Timerul contrar are un registru TCNT din care puteți citi cât timp a trecut de la pornirea cronometrului. Valoarea din acest registru nu este în minute sau secunde, ci în "papagalii" - "căpușe" ale cronometrului. Ceea ce este egal cu un singur bifat depinde de frecvența ceasului pe care funcționează microcontrolerul avr și de setările cronometrului.

De asemenea, cronometrul contracurent are un divizor de frecvență configurabil care determină cât de mult va fi împărțită frecvența ceasului microcontrolerului înainte ca contorul să fie alimentat la cronometru. Timpul de cronometrare este cel reciproc al frecvenței obținute prin împărțire.

De exemplu:
Viteza tactului = 11059200 Hz (11.0592 MHz)
Divizorul = 1024
Frecvența temporizatorului frecvenței = frecvența ceasului / divizor = 11059200/1024 = 10800 Hz
Durata perioadei (bifați) = 1/10800 = 92.593 * 10 ^ -6 secunde = 92.593 μs

Pentru a regla divizorul, se folosesc biții CS din registrul TCCR.

De exemplu, pentru timerul 1 în atmega8, se utilizează registrul TCCR1B și biți CS10, CS11, CS12.

Dependența divizorului de starea biților CS pentru timerul 1 în atmega8

TCCR1B = (1lt; CS12) | (0lt; CS11) | (1lt; CS10); // xtall / 1024

În avr, cronometrele pot fi lungi de 8 sau 16 biți. Adâncimea de biti determină numărul maxim de căpușe pe care un contor poate conta. Pentru 8 biți este de 256 căpușe, pentru 16 este 65536.

În acest caz, o căpușă este 92,593 microsecunde, respectiv valoare maximă, care poate măsura cronometrul de 16 biți este 92,593 * 65536 * 10 ^ -6 = 6.068 secunde, 8 biți - 0,0237 secunde.

După ce cronometrul are valoarea maximă, acesta depășește, adică începe să numere de la zero. Această situație poate fi tratată cu întreruperi. Pentru a face acest lucru, trebuie să activați întreruperea depășirii timerului și să setați bitul de activare a întreruperii generale.

Codul exemplu pentru întreruperea temporizării permite 1 avr atmega8:

TIMSK | = (1lt; TOIE1); // permite întreruperea la depășirea temporizatorului de counter sei (); // setați bitul de activare a întreruperii generale

De asemenea, trebuie să definiți procedura de întrerupere pentru această întrerupere - funcția care va fi apelată atunci când cronometrul depășește.

Adăugați la acest cod funcția care modifică starea piciorului PB0, la care este conectat LED-ul.

Exemplu de cod de funcționare al rutinei de întrerupere pentru cronometrul 1 avr atmega8:

ISR (TIMER1_OVF_vect)

LED-ul își va schimba starea la fiecare 6 secunde.

Pentru ca LED-ul să-și schimbe starea cu o frecvență de 10 Hz, este necesar ca numărul de timp să nu fie de 65536 căpușe sau mai puțin. Calculăm numărul necesar de căpușe:

Pentru numărul de timer nu este zero, ci o anumită valoare, la inițializare, și de fiecare dată întreruperea TCNT1 Registrul va înregistra numărul (65,536-1080) = 64456.

Afișarea programului sumar pentru cronometrul 1 avr atmega8:

#include lt; avr / io.hgt; #include avr / interrupt.hgt; ISR (TIMER1_OVF_vect)

De asemenea, puteți citi alte articole din titlul "Microcontrolere avr".

Arhiva cu sursele aflate sub avr-gcc (WinAvr) poate fi descărcată aici.

Artem Kolesnikov spune:

Artem Dvinin spune:

Vă mulțumim pentru feedback. Da, aveți dreptate, va trebui să completați articolul sau puteți scrie o notă separată.

Mulțumesc. GRIJĂ. Există o întrebare. Cronometrul începe când MC este pornit. Și cum puteți să o porniți și să o opriți manual (folosind, de exemplu, butonul).

Artem Dvinin spune:

Te rog :)
Pornirea cronometrului când divizor de frecvență nu este zero, respectiv, care ar fi necesară pentru a opri setul cronometru pentru a divizor de frecvență de zero, de exemplu, Timer 1 ATmega8 trebuie să resetați biți CS12, CS11, CS10

Alo cum se obține semnalul de la receptorul IR (38 kHz) datele sale sunt conectate la PB0 y.
Nu știu cum să setăm cronometrele.
Ajută-te.
pentru mulțumiri devreme.

Artem Dvinin spune:

Bună ziua! Și ce microcontroler ai?

Ajută-te. Acum înțeleg cu UART pe avr studio4 (mega8)
Vreau să fac un program. în care prin terminal introducem un număr. iar LED-ul clipește. De exemplu, a scris 10, atunci va clipi de 10 ori pe secundă și așa mai departe.
Sfaturi de ajutor
Mulțumită în avans
Aici este codul meu

Artem Dvinin spune:

Poate cineva din asamblare să stabilească setarea cronometrului și blițul de pe LED-ul?

Bună ziua!
Am nevoie de ajutorul tau! Nu sunt un programator, încep cu unul simplu - cu Arduino (știu, un început prost, dar sa întâmplat așa). Iată codul

Arduin nu consideră timpul să fie mai mic de 4 microsecunde, este necesar să lucrați cu cronometrele pe o linie dreaptă. Dar nu știu cum sau ce. Ajutor, vă rog!

Artem Dvinin spune:

Nazar, o zi bună!
Îmi pare rău că nu răspund imediat, vară, vacanță ... M-am odihnit de la computer :)
Arduino este un început normal, atâta timp cât există suficiente oportunități pentru acest lucru, de ce să nu-l folosiți, mai ales că este mai ușor decât să scrie pe gol Si.
Vă pot spune cum să vă rezolvați problema fără biblioteci de la arduino, folosind doar taxa Arduinovsku.
Compilatorul va fi avr-gcc sau WinAvr.
Dacă sunteți interesat - scrieți, continuați să comunicați :)

Apropo, ce fel de dispozitiv ești în curs de dezvoltare?

Bună, Artem! Vă mulțumim pentru răspuns!
Am rezolvat problema mea, dispozitivul este un metru de capacitate de la 1pF + -0.25 pF la 1.5 mF + -2.5nF. Totul funcționează, dar ar fi interesant să faci totul nu pe ID-ul Arduino.
Aici este codul meu:

(1 lt; lt; / RTI & gt; TOIE0); // Dezactivați temporizatorul 0. TIMSK2 - =

Încă o întrebare: cum să faci ceva, valoarea timerului la depășire a continuat să crească, în loc să fie anulată și a început din nou? Asta este, vreau să fac timerul pe 32 de biți. Acest lucru este astfel încât să nu facă limite de măsurare separate, ci pur și simplu pentru a crește timpul de încărcare a condensatorului.
Vă mulțumim în avans!

PS Pot renunța la schemă dacă mă interesează.

Artem Dvinin spune:

Orei bune, Nazar!
Timpul în AVR este de 16 biți, pentru a obține 32 de biți, puteți configura întreruperea fluxului și în această întrerupere pentru a mări contorul de programe, să o numim cnt.
Apoi, valoarea măsurată va fi (cnt <<16) + TCNT1;

Și schema este cu siguranță interesantă, vă rugăm să o trimiteți!

PS Apropo, mi se pare, în această linie eroare:

în timp ce (((((ACSR - (1lt; ACO)) == 0)) - (TCNT1 = 14001)

Cazul poate fi că aveți un divizor = 1, adică cronometrul funcționează la o frecvență de 8MHz. Cu aceeași frecvență, comenzile microcontrolerului sunt executate (1 - 3 cicluri de ceas per comandă). Se pare că, dacă se execută mai mult de 256 cicluri de ceas, codul procesorului de întrerupere, frecvența va scădea. Încercați să dezasamblați firmware-ul și să vedeți ce cod este generat pentru dispozitivul de întrerupere.
Pentru a obține o frecvență mai mare de 8MHz / 256, puteți încerca să rescrieți handler-ul în asamblare sau să utilizați timer1 în modul CTC (Clear Timer on Compare).

prompte și în mod necesar valoarea în registrul OCR1A pentru a scrie în 16 format de culoare? și dacă este necesar să se scrie prima valoare pentru senior și apoi pentru cel mai mic, adică astfel:

TCCR0 = (1lt, lt0) | (1lt; 1); // Configurați prescaler TIMSK | = (1lt; lt; TOIE0); // // ___________________________________________________ TIMER1 TCCR1B = (1lt; lt; CS12) | (0LT; lt; CS11) | (0LT; lt; CS10); // Setați prescalerul la 256 TIMSK | = (1lt; lt; TOIE1); // TCNT1 = 0; // ___________________________________________________ TIMER2 // TCCR2 = (1lt; lt; CS12) | (0LT; lt; CS11) | (1lt; lt; CS10); // Setați prescalerul 1024 // TIMSK | = (1lt; lt; TOIE2); //

cu taverna 2 totul ca și cum nu funcționează

Artem Dvinin spune:

spune-mi te rog. În ATtiny2313a, în setările cronometrului de 16 biți din registrul TCCR1A există astfel de biți: COMnA1: 0. COMnB1: 0, COMnC1: 0. Din foaie de date am citit că, în coincidență cu registrul comparație (în conformitate cu valorile înregistrate în aceste registre) se va schimba nivelul de tensiune opus, pentru a prinde până la + 5 sau 0. Dar eu nu pot înțelege, când activați această funcție, dacă este posibil să se schimbe valorile acestor picioare în program?

Artem Dvinin spune:

Alexandru, salut.
Prin setarea biților COMnA1: 0. COMnB1: 0, COMnC1: 0 Activați funcția de ieșire alternativă și dezactivați-o ca să funcționeze ca un port I / O normal (adică nu puteți obține valoarea din program). În acest caz, nu uitați să configurați ieșirea corespunzătoare la ieșire.

Alexander M. spune:

Am încercat să interceptez programul sub AtMega 128 cu un cuarț extern la 16 MHz, programul din anumite motive nu a funcționat. Probabil trebuie să corectezi valorile biților?

Artem Dvinin spune:

O zi bună, Alexander.
Pot încerca mai întâi un program simplu?
Dacă clipește, este în setările cronometrului, dacă nu, atunci LED-ul nu funcționează.

#include #include int principal (void)

Ajutați-l pe începător!
Timerul pe Attiny44 nu pornește

/////
#define F_CPU 8000000UL
#include

void init (void)
TCCR0B | = (1< TIMSK0 | = (1<>

ISR (TIM0_OVF_vect) // întrerupe

int principal (void)
init (); // inițializați
sei (); // permite toate întreruperile
în timp ce (1)
asm ("nop");
>
>

/////////////////////////
În acest caz, cronometrul nu contează nici măcar!
Prompt în ce problemă?
Mulțumită în avans.

1. De la IDE, încarc schița în Arduino lui Leonardo, unde informația USB este trimisă la ieșirea din fiecare secundă. În consola văd o actualizare în fiecare secundă.
2. Conectez în loc de consola TeraTerm \ ttermpro.exe ». În fereastră văd fiecare a doua actualizare.
3. Închid totul, deconectați arduinul de la USB.
4. Conectați dispozitivul Arduino la USB. Conectez TeraTerm \ ttermpro.exe ». În fereastră văd actualizarea după 8 secunde.

Și nu este mai ușor să scrieți zero simultan în registrul de numărare. TCNT1 = 0;
Și în registrul de comparație există cât mai multe bare pe care trebuie să le numărați, de exemplu 500 OCR1A = 500;
Și setați temporizatorul să se întrerupă prin coincidență. Iată întregul cod de configurare:

TCCR1A | = (0 < TCCR1 | = (0 < TCCR1B | = (0 < TIMSK | = (1 < OCR1A = 461; // Numărul de comparat (când TCNT1 = OCR1A, o întrerupere apare prin coincidență)
TCNT1 = 0; // Resetați valoarea registrului de numărare al timerului / numărătorului1

Articole similare