Î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 :) Alo cum se obține semnalul de la receptorul IR (38 kHz) datele sale sunt conectate la PB0 y. Artem Dvinin spune: Bună ziua! Și ce microcontroler ai? Ajută-te. Acum înțeleg cu UART pe avr studio4 (mega8) Artem Dvinin spune: Poate cineva din asamblare să stabilească setarea cronometrului și blițul de pe LED-ul? Bună ziua! 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ă! Apropo, ce fel de dispozitiv ești în curs de dezvoltare? Bună, Artem! Vă mulțumim pentru răspuns! (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. PS Pot renunța la schemă dacă mă interesează. Artem Dvinin spune: Orei bune, Nazar! Ș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. 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. 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. #include Ajutați-l pe începător! ///// void init (void) ISR (TIM0_OVF_vect) // întrerupe int principal (void) ///////////////////////// 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ă. Și nu este mai ușor să scrieți zero simultan în registrul de numărare. TCNT1 = 0;
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
Nu știu cum să setăm cronometrele.
Ajută-te.
pentru mulțumiri devreme.
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
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
Î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 :)
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:
Vă mulțumim în avans!
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;
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).
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.
Pot încerca mai întâi un program simplu?
Dacă clipește, este în setările cronometrului, dacă nu, atunci LED-ul nu funcționează.
Timerul pe Attiny44 nu pornește
#define F_CPU 8000000UL
#include
TCCR0B | = (1<
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.
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 î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 <
TCNT1 = 0; // Resetați valoarea registrului de numărare al timerului / numărătorului1Articole similare