Cuprins:

Microcontroler AVR. LED-uri clipește folosind temporizator. Temporizatoare se întrerupe. Mod CTC temporizator: 6 pași
Microcontroler AVR. LED-uri clipește folosind temporizator. Temporizatoare se întrerupe. Mod CTC temporizator: 6 pași

Video: Microcontroler AVR. LED-uri clipește folosind temporizator. Temporizatoare se întrerupe. Mod CTC temporizator: 6 pași

Video: Microcontroler AVR. LED-uri clipește folosind temporizator. Temporizatoare se întrerupe. Mod CTC temporizator: 6 pași
Video: LDmicro 8: Intruder Alarm with Timers (Microcontroller PLC Ladder Programming with LDmicro) 2024, Noiembrie
Anonim
Image
Image

Bună ziua tuturor!

Temporizatoarele sunt un concept important în domeniul electronicii. Fiecare componentă electronică funcționează pe o bază de timp. Această bază de timp ajută la menținerea tuturor lucrărilor sincronizate. Toate microcontrolerele funcționează la o anumită frecvență de ceas predefinită, toate au o dispoziție pentru configurarea cronometrelor. AVR se mândrește cu un cronometru foarte precis, precis și fiabil. Acesta oferă o mulțime de caracteristici, făcându-l astfel un subiect vast. Cea mai bună parte este că temporizatorul este total independent de CPU. Astfel, rulează paralel cu CPU-ul și nu există nicio intervenție a CPU-ului, ceea ce face ca temporizatorul să fie destul de precis. În această secțiune explic conceptele de bază ale cronometrelor AVR. Scriu un program simplu în cod C pentru a controla intermitentul cu LED-uri, folosind temporizatoare.

Pasul 1: Descriere

Afirmația problemei 1: Să aprindem primul LED (verde) la fiecare 50 ms
Afirmația problemei 1: Să aprindem primul LED (verde) la fiecare 50 ms

În ATMega328 există trei tipuri de temporizatoare:

Timer / Counter0 (TC0) - este un modul Timer / Counter de 8 biți de uz general, cu două unități OutputCompare independente și suport PWM;

Timer / Counter1 (TC1) - Unitatea Timer / Counter pe 16 biți permite sincronizarea exactă a execuției programului (gestionarea evenimentelor), generarea undelor și măsurarea sincronizării semnalului;

Timer / Counter2 (TC2) -este un modul de timp general, canal, Timer / Counter pe 8 biți cu PWM și funcționare asincronă;

Pasul 2: Declarație de problemă 1: Să aprindem primul LED (verde) la fiecare 50 ms

Afirmația problemei 1: Să aprindem primul LED (verde) la fiecare 50 ms
Afirmația problemei 1: Să aprindem primul LED (verde) la fiecare 50 ms
Declarație de problemă 1: Să aprindem primul LED (verde) la fiecare 50 ms
Declarație de problemă 1: Să aprindem primul LED (verde) la fiecare 50 ms

Metodologie:

- utilizarea unui precaler Timer0 pentru a reduce un semnal electric de înaltă frecvență la o frecvență mai mică prin diviziune întreagă;

- utilizarea unei întreruperi de fiecare dată când Timer0 se revarsă;

Timer0 (8 biți) contează de la 0 la 255 după aceea, se revarsă, această valoare se schimbă la fiecare impuls de ceas.

F_CPU = 16MHz: Perioada de timp a ceasului = 1000ms / 16000000Hz = 0.0000625ms

Număr temporizator = (Întârziere necesară / Perioada de timp a ceasului) -1 = (50ms / 0,0000625ms) = 799999

Ceasul a bifat deja de 799999 de ori pentru a da o întârziere de numai 50 ms!

Putem folosi tehnica de diviziune a frecvenței se numește prescalare pentru a reduce numărul de temporizatoare. AVR ne oferă următoarele valori de prescaler pentru a alege dintre: 8, 64, 256 și 1024. Consultați tabelul rezumă rezultatele utilizării diferitelor prescalere.

Valoarea contorului trebuie să fie întotdeauna un număr întreg. Să alegem un prescaler 256!

În majoritatea microcontrolerelor, există ceva numit Întrerupere. Această întrerupere poate fi declanșată ori de câte ori sunt îndeplinite anumite condiții. Acum, ori de câte ori este declanșată o întrerupere, AVR se oprește și salvează execuția rutinei principale, participă la apelul de întrerupere (executând o rutină specială, numită Rutină de serviciu de întrerupere, ISR) și odată ce a fost terminată, revine la rutina principală și continuă să o execute.

Deoarece întârzierea necesară (50ms) este mai mare decât întârzierea maximă posibilă: 4, 096ms = 1000ms / 62500Hz * 256, evident, cronometrul se va revărsa. Și ori de câte ori cronometrul se revarsă, se declanșează o întrerupere.

De câte ori ar trebui să fie declanșată întreruperea?

50ms / 4.096ms = 3125/256 = 12.207 Dacă temporizatorul a survolat de 12 ori, 12 * 4.096ms = 49.152ms ar fi trecut. În cea de-a 13-a iterație, avem nevoie de o întârziere de 50ms - 49.152ms = 0.848ms.

La o frecvență de 62500Hz (prescaler = 256), fiecare bifă durează 0,016 ms. Astfel, pentru a obține o întârziere de 0,848 ms, ar necesita 0,848 ms / 0,016 ms = 53 de căpușe. Astfel, în cea de-a 13-a iterație, permitem temporizatorului să numere până la 53 și apoi să-l resetați.

Inițializați Timer0 / Counter (a se vedea imaginea):

TCCR0B | = (1 << CS02) // configurați temporizatorul cu prescaler = 256 TCNT0 = 0 // inițializați contorul TIMSK0 | = (1 << TOIE0) // activați întreruperea overflow sei () // activați întreruperile globale tot_overflow = 0 // inițializează variabila contorului de revărsare

Pasul 3: Declarație de problemă 2: Să clipim al doilea LED (albastru) la fiecare 1s

Declarație de problemă 2: Să clipim al doilea LED (albastru) la fiecare 1s
Declarație de problemă 2: Să clipim al doilea LED (albastru) la fiecare 1s
Declarație de problemă 2: Să clipim al doilea LED (albastru) la fiecare 1s
Declarație de problemă 2: Să clipim al doilea LED (albastru) la fiecare 1s
Declarație de problemă 2: Să clipim al doilea LED (albastru) la fiecare 1s
Declarație de problemă 2: Să clipim al doilea LED (albastru) la fiecare 1s

Metodologie:

- utilizarea unui precaler Timer1 pentru a reduce semnalul electric de înaltă frecvență la o frecvență mai mică prin diviziune întreagă;

- utilizarea Clear Timer în modul Comparare (CTC);

- utilizarea întreruperilor cu modul CTC;

Timer1 (16 biți) contează de la 0 la 65534 după aceea, se revarsă. Această valoare se schimbă la fiecare impuls de ceas.

F_CPU = 16MHz: Perioada de timp a ceasului = 1000ms / 16000000Hz = 0.0000625ms Numărul de temporizatori = (Întârziere necesară / Perioada de timp a ceasului) -1 = (1000ms / 0.0000625ms) = 15999999

Ceasul a bifat deja 15999999 de ori pentru a da o întârziere de 1s!

Putem folosi tehnica de diviziune a frecvenței se numește prescalare pentru a reduce numărul de temporizatoare. AVR ne oferă următoarele valori de prescaler pentru a alege dintre: 8, 64, 256 și 1024. Consultați tabelul rezumă rezultatele utilizării diferitelor prescalere. Valoarea contorului trebuie să fie întotdeauna un număr întreg. Să alegem un prescaler 256!

În modul Clear timer on Compare (CTC), registrul OCR1A sau ICR1 sunt utilizate pentru a manipula rezoluția contorului. În modul CTC, contorul este eliminat la zero atunci când valoarea contorului (TCNT1) se potrivește fie cu OCR1A, fie cu ICR1. OCR1A sau ICR1 definesc valoarea maximă pentru contor, deci și rezoluția sa. Acest mod permite un control mai mare al frecvenței de ieșire a meciului de comparare. De asemenea, simplifică funcționarea numărării evenimentelor externe. Trebuie să spunem AVR-ului să reseteze Timer1 / Counter de îndată ce valoarea acestuia atinge valoarea 62500, pentru a obține astfel o întârziere de 1s.

Inițializați Timer1 / Counter (a se vedea imaginea):

TCCR1B | = (1 << WGM12) | (1 << CS12) // configurați temporizatorul cu prescaler = 256 și modul CTC TCNT1 = 0 // inițializați contorul TIMSK1 | = (1 << OCIE1A) // activați întreruperea de comparare OCR1A = 62500 // inițializează valoarea de comparare

Pasul 4: Declarație de problemă 3: Să aprindem al treilea LED (roșu) la fiecare 16 ms

Declarație de problemă 3: Să clipim al treilea LED (roșu) la fiecare 16 ms
Declarație de problemă 3: Să clipim al treilea LED (roșu) la fiecare 16 ms
Declarație de problemă 3: Să clipim al treilea LED (roșu) la fiecare 16 ms
Declarație de problemă 3: Să clipim al treilea LED (roșu) la fiecare 16 ms
Declarație de problemă 3: Să clipim al treilea LED (roșu) la fiecare 16 ms
Declarație de problemă 3: Să clipim al treilea LED (roșu) la fiecare 16 ms
Declarație de problemă 3: Să clipim al treilea LED (roșu) la fiecare 16 ms
Declarație de problemă 3: Să clipim al treilea LED (roșu) la fiecare 16 ms

Metodologie:

- utilizarea unui precaler Timer2 pentru a reduce un semnal electric de înaltă frecvență la o frecvență mai mică prin diviziune întreagă;

- utilizarea Clear Timer în modul Comparare (CTC);

- utilizarea modului Hardware CTC fără întreruperi;

Timer2 (8 biți) contează de la 0 la 255 după aceea, se revarsă. Această valoare se schimbă la fiecare impuls de ceas.

F_CPU = 16MHz: Perioada de timp a ceasului = 1000ms / 16000000Hz = 0.0000625ms

Număr temporizator = (Întârziere necesară / Perioada de timp a ceasului) -1 = (16 ms / 0,0000625 ms) = 255999

Ceasul a bifat deja 255999 de ori pentru a da o întârziere de 16 ms!

Vezi tabelul rezumă rezultatele utilizării diferitelor prescalere. Valoarea contorului trebuie să fie întotdeauna un număr întreg. Să alegem un prescaler 1024!

În modul CTC, contorul este eliminat la zero atunci când valoarea contorului (TCNT2) se potrivește fie cu OCR2A, fie cu ICR2. Pinul PB3 este și pinul de comparare a ieșirii din TIMER2 - OC2A (vezi diagrama).

Timer / Counter2 Control Register A - TCCR2A Bit 7: 6 - COM2A1: 0 - Compare Output Mode for Compare Unit A. Întrucât trebuie să comutăm LED-ul, alegem opțiunea: Comutați OC2A pe Match Match Ori de câte ori apare o potrivire de comparare, Pinul OC2A este comutat automat. Nu este nevoie să verificați niciun bit de semnalizare, nu este nevoie să participați la întreruperi.

Inițializați Timer2 / Counter

TCCR2A | = (1 << COM2A0) | (1 << WGM21) // configurați temporizatorul pin OC2A în modul de comutare și modul CTC TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20) // configurați temporizatorul cu prescaler = 1024 TCNT2 = 0 // inițializați contorul OCR2A = 250 // inițializați valoarea de comparare

Pasul 5: Scrierea codului pentru un program în C. Încărcarea fișierului HEX în memoria flash a microcontrolerului

Scrierea codului pentru un program în C. Încărcarea fișierului HEX în memoria flash a microcontrolerului
Scrierea codului pentru un program în C. Încărcarea fișierului HEX în memoria flash a microcontrolerului
Scrierea codului pentru un program în C. Încărcarea fișierului HEX în memoria flash a microcontrolerului
Scrierea codului pentru un program în C. Încărcarea fișierului HEX în memoria flash a microcontrolerului

Scrierea și construirea aplicației de microcontroler AVR în cod C folosind platforma de dezvoltare integrată - Atmel Studio.

F_CPU definește frecvența ceasului în Hertz și este comună în programele care utilizează biblioteca avr-libc. În acest caz, este utilizat de rutinele de întârziere pentru a determina modul de calcul al întârzierilor.

#ifndef F_CPU

#define F_CPU 16000000UL // indicând frecvența cristalului (16 MHz AVR ATMega328P) #endif

#include // header pentru a permite controlul fluxului de date peste pini. Definește pini, porturi etc.

Primul fișier include include avr-libc și va fi folosit în aproape orice proiect AVR la care lucrați. io.h va determina procesorul pe care îl utilizați (motiv pentru care specificați partea la compilare) și, la rândul său, includeți antetul de definiție IO adecvat pentru cipul pe care îl folosim. Pur și simplu definește constantele pentru toți pinii, porturile, registrele speciale etc.

#include // header pentru a activa întreruperea

volatil uint8_t tot_overflow; // variabila globala pentru a numara numarul de revarsari

Metodologia declarației problemei: LED-ul Flash (verde) la fiecare 50 ms

- utilizarea unui precaler Timer0 pentru a reduce un semnal electric de înaltă frecvență la o frecvență mai mică prin diviziune întreagă;

- utilizarea unei întreruperi de fiecare dată când Timer0 se revarsă;

void timer0_init () // inițializează timer0, întrerupere și variabilă

{TCCR0B | = (1 << CS02); // configurați temporizatorul cu prescaler = 256 TCNT0 = 0; // inițializează contorul TIMSK0 | = (1 << TOIE0); // activate overflow nterrupt sei (); // activează întreruperile globale tot_overflow = 0; // inițializează variabila contorului de revărsare}

Metodologia enunțului problemei: bliț al doilea LED (albastru) la fiecare 1s

- utilizarea unui precaler Timer1 pentru a reduce semnalul electric de înaltă frecvență la o frecvență mai mică prin diviziune întreagă;

- utilizarea Clear Timer în modul Comparare (CTC);

- utilizarea întreruperilor cu modul CTC;

void timer1_init () // inițializează timer1, întrerupe și variabilă {TCCR1B | = (1 << WGM12) | (1 << CS12); // configurați temporizatorul cu prescaler = 256 și modul CTC TCNT1 = 0; // inițializați contorul OCR1A = 62500; // inițializează valoarea de comparare TIMSK1 | = (1 << OCIE1A); // activați întreruperea comparării}

Metodologia declarației problemei: bliț al treilea LED (roșu) la fiecare 16 ms

- utilizarea unui precaler Timer2 pentru a reduce un semnal electric de înaltă frecvență la o frecvență mai mică prin diviziune întreagă;

- utilizarea Clear Timer în modul Comparare (CTC);

- utilizarea modului Hardware CTC fără întreruperi;

void timer2_init () // initialize timer2 {TCCR2A | = (1 << COM2A0) | (1 << WGM21); // configurați pinul OC2A temporizator în modul de comutare și modul CTC TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20); // configurați temporizatorul cu prescaler = 1024 TCNT2 = 0; // inițializează contorul OCR2A = 250; // inițializează valoarea de comparare}

Rutina de servicii de întrerupere a depășirii TIMER0 apelată ori de câte ori deversează TCNT0:

ISR (TIMER0_OVF_vect)

{tot_overflow ++; // țineți o evidență a numărului de revărsări}

Acest ISR este declanșat ori de câte ori apare o potrivire, prin urmare, comutați aici:

ISR (TIMER1_COMPA_vect) {PORTC ^ = (1 << 1); // comutați aici}

int main (nul)

{DDRB | = (1 << 0); // conectați 1 (verde) condus la pinul PB0 DDRC | = (1 << 1); // conectați 2 (albastru) condus la pinul PC1 DDRB | = (1 << 3); // conectați 3 (roșu) condus la pinul PB3 (OC2A) timer0_init (); // inițializează timer0 timer1_init (); // inițializează timer1 timer2_init (); // inițializați timer2 în timp ce (1) // buclați definitiv {

Dacă Timer0 a survolat de 12 ori, ar fi trecut 12 * 4.096ms = 49.152ms. În cea de-a 13-a iterație, avem nevoie de o întârziere de 50ms - 49.152ms = 0.848ms. Astfel, în cea de-a 13-a iterație, permitem temporizatorului să numere până la 53 și apoi să-l resetăm.

if (tot_overflow> = 12) // verificați dacă nu. de revărsări = 12 NOTĂ: se utilizează „> =”

{if (TCNT0> = 53) // verificați dacă numărul temporizatorului ajunge la 53 {PORTB ^ = (1 << 0); // comută ledul TCNT0 = 0; // resetare contor tot_overflow = 0; // resetează contorul de revărsare}}}}

Încărcarea fișierului HEX în memoria flash a microcontrolerului:

tastați în fereastra de prompt DOS comanda:

avrdude –c [nume programator] –p m328p –u –U flash: w: [numele fișierului hexagonal] În cazul meu este: avrdude –c ISPProgv1 –p m328p –u –U flash: w: Timers.hex

Această comandă scrie un fișier hexagonal în memoria microcontrolerului. Urmăriți videoclipul cu o descriere detaliată a arderii memoriei flash a microcontrolerului:

Microcontroler de memorie flash în curs de ardere …

Bine! Acum, microcontrolerul funcționează în conformitate cu instrucțiunile programului nostru. Hai să verificăm!

Pasul 6: Realizarea circuitului electric

Realizarea circuitului electric
Realizarea circuitului electric
Realizarea circuitului electric
Realizarea circuitului electric
Realizarea circuitului electric
Realizarea circuitului electric

Conectați componentele în conformitate cu diagrama schematică.

Recomandat: