Kazalo:

Mikrokrmilnik AVR. LED utripa z uporabo časovnika. Časovniki prekinejo. Časovnik CTC način: 6 korakov
Mikrokrmilnik AVR. LED utripa z uporabo časovnika. Časovniki prekinejo. Časovnik CTC način: 6 korakov

Video: Mikrokrmilnik AVR. LED utripa z uporabo časovnika. Časovniki prekinejo. Časovnik CTC način: 6 korakov

Video: Mikrokrmilnik AVR. LED utripa z uporabo časovnika. Časovniki prekinejo. Časovnik CTC način: 6 korakov
Video: Использование плат Digispark Attiny85 Mini Arduino: Урок 108 2024, Julij
Anonim
Image
Image

Pozdravljeni vsi skupaj!

Merilniki časa so pomemben koncept na področju elektronike. Vsaka elektronska komponenta deluje časovno. Ta časovni okvir pomaga sinhronizirati vse delo. Vsi mikrokrmilniki delujejo na vnaprej določeni taktni frekvenci, vsi imajo možnost nastavitve časovnikov. AVR se ponaša s časovnikom, ki je zelo natančen, natančen in zanesljiv. Ponuja veliko funkcij, zato je obsežna tema. Najboljši del je, da je časovnik popolnoma neodvisen od procesorja. Tako deluje vzporedno s CPE -jem in ni posredovanja CPU -ja, zaradi česar je časovnik precej natančen. V tem razdelku razlagam osnovne koncepte AVR Timerjev. Pišem preprost program v kodi C za krmiljenje LED utripajočih s časovniki.

1. korak: Opis

Izjava o problemu 1: Najprej utripa LED (zelena) vsakih 50 ms
Izjava o problemu 1: Najprej utripa LED (zelena) vsakih 50 ms

V ATMega328 obstajajo tri vrste časovnikov:

Timer/Counter0 (TC0) - je 8 -bitni Timer/Counter modul za splošne namene z dvema neodvisnima enotama OutputCompare in podporo PWM;

Timer/Counter1 (TC1) - 16 -bitna Timer/Counter enota omogoča natančen čas izvajanja programa (upravljanje dogodkov), generiranje valov in merjenje časa signala;

Timer/Counter2 (TC2) -je splošni namenski kanal, 8 -bitni timer/counter modul s PWM in asinhronim delovanjem;

2. korak: Izjava o problemu 1: Najprej utripa prva LED (zelena) vsakih 50 ms

Izjava o problemu 1: Najprej utripa LED (zelena) vsakih 50 ms
Izjava o problemu 1: Najprej utripa LED (zelena) vsakih 50 ms
Izjava o problemu 1: Najprej utripa LED (zelena) vsakih 50 ms
Izjava o problemu 1: Najprej utripa LED (zelena) vsakih 50 ms

Metodologija:

- z uporabo predčasovnika Timer0 za zmanjšanje visokofrekvenčnega električnega signala na nižjo frekvenco z delitvijo na celo število;

- z uporabo prekinitve vsakič, ko se Timer0 prelije;

Timer0 (8 bit) po tem šteje od 0 do 255, se prelivajo, ta vrednost se spreminja pri vsakem taktu.

F_CPU = 16MHz: časovno obdobje = 1000ms / 16000000Hz = 0,0000625ms

Števec časovnika = (zahtevana zakasnitev / časovno obdobje ure) -1 = (50 ms / 0,0000625 ms) = 799999

Ura je že tekla 799999 krat, kar pomeni zamudo le 50 ms!

Za zmanjšanje števila časovnikov lahko uporabimo tehniko delitve frekvence, imenovano predskaliranje. AVR nam ponuja med naslednjimi vrednostmi predkalerja, med katerimi lahko izbiramo: 8, 64, 256 in 1024. Glejte tabelo povzetek rezultatov uporabe različnih predkalerjev.

Vrednost števca mora biti vedno celo število. Izberemo predkaler 256!

V večini mikrokrmilnikov obstaja nekaj, kar se imenuje Prekinitev. Ta prekinitev se lahko sproži, kadar so izpolnjeni določeni pogoji. Zdaj, ko se sproži prekinitev, se AVR ustavi in shrani izvajanje glavne rutine, sodeluje pri klicu prekinitve (z izvajanjem posebne rutine, imenovane rutina prekinitvene storitve, ISR) in se po končanem postopku vrne v main rutino in jo nadaljuje z izvajanjem.

Ker je zahtevana zakasnitev (50 ms) večja od največje možne zamude: 4, 096ms = 1000ms / 62500Hz * 256, se bo časovnik očitno prelival. In kadar se časovnik preplavi, se sproži prekinitev.

Kolikokrat je treba prekinitev sprožiti?

50ms / 4.096ms = 3125 /256 = 12.207 Če je časovnik preletel 12 -krat, bi minilo 12 * 4.096ms = 49.152ms. V 13. ponovitvi potrebujemo zakasnitev 50 ms - 49,152 ms = 0,848 ms.

Pri frekvenci 62500Hz (predkaler = 256) vsak klop traja 0,016 ms. Tako bi za dosego zamude 0,848ms potrebovali 0,848ms / 0,016ms = 53 klopov. Tako v 13. ponovitvi dopuščamo, da časovnik šteje le do 53, nato pa ga ponastavimo.

Inicializiraj Timer0/Counter (glej sliko):

TCCR0B | = (1 << CS02) // nastavite časovnik s predkalerjem = 256 TCNT0 = 0 // inicializirajte števec TIMSK0 | = (1 << TOIE0) // omogočite prekinitev prelivanja sei () // omogočite globalne prekinitve tot_overflow = 0 // inicializiramo spremenljivko števca prelivanja

3. korak: Izjava o problemu 2: Utripajmo drugo LED (modro) vsake 1 s

Izjava o problemu 2: Utripajmo drugo LED (modro) vsake 1 s
Izjava o problemu 2: Utripajmo drugo LED (modro) vsake 1 s
Izjava o problemu 2: Utripajmo drugo LED (modro) vsake 1 s
Izjava o problemu 2: Utripajmo drugo LED (modro) vsake 1 s
Izjava o problemu 2: Utripajmo drugo LED (modro) vsake 1 s
Izjava o problemu 2: Utripajmo drugo LED (modro) vsake 1 s

Metodologija:

- z uporabo predčasovnika Timer1 za zmanjšanje visokofrekvenčnega električnega signala na nižjo frekvenco z delitvijo na celo število;

- z uporabo načina Clear Timer on Compare (CTC);

- uporaba prekinitev v načinu CTC;

Timer1 (16 bit) po tem šteje od 0 do 65534, se prelivajo. Ta vrednost se spreminja pri vsakem taktu.

F_CPU = 16 MHz: Časovno obdobje = 1000 ms / 16000000 Hz = 0,0000625 ms Število časa = (zahtevana zakasnitev / časovno obdobje ure) -1 = (1000 ms / 0,0000625 ms) = 15999999

Ura je že tekla 15999999 krat, kar je pomenilo zamudo 1 s!

Za zmanjšanje števila časovnikov lahko uporabimo tehniko delitve frekvence, imenovano predskaliranje. AVR nam ponuja med naslednjimi vrednostmi predkalerja, med katerimi lahko izbiramo: 8, 64, 256 in 1024. Glejte tabelo povzetek rezultatov uporabe različnih predkalerjev. Vrednost števca mora biti vedno celo število. Izberemo predkaler 256!

V načinu Clear timer on Compare (CTC) se register OCR1A ali ICR1 uporablja za manipulacijo ločljivosti števca. V načinu CTC se števec počisti na nič, če se vrednost števca (TCNT1) ujema z OCR1A ali ICR1. OCR1A ali ICR1 določata najvišjo vrednost števca, zato tudi njegovo ločljivost. Ta način omogoča večji nadzor izhodne frekvence primerjave in poenostavi tudi štetje zunanjih dogodkov. AVR -ju moramo povedati, da ponastavi časovnik 1/števec, takoj ko njegova vrednost doseže vrednost 62500, s čimer doseže zakasnitev 1 s.

Inicializiraj Timer1/Counter (glej sliko):

TCCR1B | = (1 << WGM12) | (1 << CS12) // nastavite časovnik s predkalerjem = 256 in načinom CTC TCNT1 = 0 // inicializirajte števec TIMSK1 | = (1 << OCIE1A) // omogočite primerjavo prekinitve OCR1A = 62500 // inicializiraj primerjalno vrednost

4. korak: Izjava o problemu 3: Utripajmo tretjo LED (rdečo) vsakih 16 ms

Izjava o problemu 3: Naj utripa tretja LED (rdeča) vsakih 16 ms
Izjava o problemu 3: Naj utripa tretja LED (rdeča) vsakih 16 ms
Izjava o problemu 3: Naj utripa tretja LED (rdeča) vsakih 16 ms
Izjava o problemu 3: Naj utripa tretja LED (rdeča) vsakih 16 ms
Izjava o problemu 3: Naj utripa tretja LED (rdeča) vsakih 16 ms
Izjava o problemu 3: Naj utripa tretja LED (rdeča) vsakih 16 ms
Izjava o problemu 3: Naj utripa tretja LED (rdeča) vsakih 16 ms
Izjava o problemu 3: Naj utripa tretja LED (rdeča) vsakih 16 ms

Metodologija:

- z uporabo predčasovnika Timer2 za zmanjšanje visokofrekvenčnega električnega signala na nižjo frekvenco z delitvijo na celo število;

- z uporabo načina Clear Timer on Compare (CTC);

- uporaba strojne opreme CTC Mode brez prekinitev;

Timer2 (8 bit) po tem šteje od 0 do 255, se prelivajo. Ta vrednost se spreminja pri vsakem taktu.

F_CPU = 16MHz: časovno obdobje = 1000ms / 16000000Hz = 0,0000625ms

Števec časovnika = (zahtevana zakasnitev / časovno obdobje ure) -1 = (16 ms / 0,0000625 ms) = 255999

Ura je že odštekala 255999 krat, kar pomeni 16 ms zamude!

Glej tabelo povzema rezultate uporabe različnih predkalerjev. Vrednost števca mora biti vedno celo število. Izberemo predceler 1024!

V načinu CTC se števec počisti na nič, če se vrednost števca (TCNT2) ujema z OCR2A ali ICR2. Pin PB3 je tudi pin za primerjavo izhodov TIMER2 - OC2A (glej diagram).

Krmilni register časovnika/števca2 A - TCCR2A Bit 7: 6 - COM2A1: 0 - Primerjaj izhodni način za primerjalno enoto A. Ker moramo preklopiti LED, izberemo možnost: Preklopite OC2A na primerjalno ujemanje Kadarkoli pride do primerjave OC2A pin se samodejno preklopi. Ni vam treba preverjati nobenega bitja zastavice, ni treba skrbeti za prekinitve.

Inicializirajte Timer2/Counter

TCCR2A | = (1 << COM2A0) | (1 << WGM21) // nastavite zatič OC2A časovnika v preklopnem načinu in načinu CTC TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20) // nastavite časovnik s predkalerjem = 1024 TCNT2 = 0 // inicializirajte števec OCR2A = 250 // inicializirajte primerjalno vrednost

5. korak: Pisanje kode za program v C. Nalaganje HEX datoteke v pomnilnik mikrokontrolerja

Pisanje kode za program v C. Nalaganje HEX datoteke v pomnilnik mikrokontrolerja
Pisanje kode za program v C. Nalaganje HEX datoteke v pomnilnik mikrokontrolerja
Pisanje kode za program v C. Nalaganje HEX datoteke v pomnilnik mikrokontrolerja
Pisanje kode za program v C. Nalaganje HEX datoteke v pomnilnik mikrokontrolerja

Pisanje in izdelava aplikacije mikrokrmilnika AVR v kodi C z uporabo integrirane razvojne platforme - Atmel Studio.

F_CPU definira frekvenco ure v Hercih in je pogosta v programih, ki uporabljajo knjižnico avr-libc. V tem primeru ga rutine zamude uporabljajo za določitev načina izračuna časovnih zamud.

#ifndef F_CPU

#define F_CPU 16000000UL // povedana frekvenca kristala krmilnika (16 MHz AVR ATMega328P) #endif

#include // glava za omogočanje nadzora pretoka podatkov nad zatiči. Določa zatiče, vrata itd.

Prva datoteka za vključitev je del avr-libc in bo uporabljena v skoraj vsakem projektu AVR, na katerem delate. io.h bo določil CPU, ki ga uporabljate (zato pri sestavljanju določite del) in nato vključil ustrezno glavo definicije IO za čip, ki ga uporabljamo. Preprosto definira konstante za vse vaše zatiče, vrata, posebne registre itd.

#include // glava za omogočanje prekinitve

hlapni uint8_t tot_overflow; // globalna spremenljivka za štetje števila prelivov

Metodologija izjave o težavi: LED najprej utripa (zelena) vsakih 50 ms

- z uporabo predčasovnika Timer0 za zmanjšanje visokofrekvenčnega električnega signala na nižjo frekvenco z delitvijo na celo število;

- z uporabo prekinitve vsakič, ko se Timer0 prelije;

void timer0_init () // inicializira timer0, prekinitev in spremenljivko

{TCCR0B | = (1 << CS02); // nastavitev časovnika s predkalerjem = 256 TCNT0 = 0; // inicializiraj števec TIMSK0 | = (1 << TOIE0); // omogočimo prelivanje nterrupt sei (); // omogočimo globalne prekinitve tot_overflow = 0; // inicializiraj spremenljivko števca prelivanja}

Metodologija izjavljanja problema: utripa druga LED (modra) vsake 1 s

- z uporabo predčasovnika Timer1 za zmanjšanje visokofrekvenčnega električnega signala na nižjo frekvenco z delitvijo na celo število;

- z uporabo načina Clear Timer on Compare (CTC);

- uporaba prekinitev v načinu CTC;

void timer1_init () // inicializiraj timer1, prekinitev in spremenljivko {TCCR1B | = (1 << WGM12) | (1 << CS12); // nastavite časovnik s predkalerjem = 256 in načinom CTC TCNT1 = 0; // inicializiraj števec OCR1A = 62500; // inicializiraj primerjalno vrednost TIMSK1 | = (1 << OCIE1A); // omogoči primerjalno prekinitev}

Metodologija izjave o težavi: Tretja LED (rdeča) utripa vsakih 16 ms

- z uporabo predčasovnika Timer2 za zmanjšanje visokofrekvenčnega električnega signala na nižjo frekvenco z delitvijo na celo število;

- z uporabo načina Clear Timer on Compare (CTC);

- uporaba strojne opreme CTC Mode brez prekinitev;

void timer2_init () // inicializira timer2 {TCCR2A | = (1 << COM2A0) | (1 << WGM21); // nastavimo zatič časovnika OC2A v preklopnem načinu in načinu CTC TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20); // nastavitev časovnika s predkalerjem = 1024 TCNT2 = 0; // inicializiraj števec OCR2A = 250; // inicializiraj primerjalno vrednost}

TIMER0 prelivna prekinitvena rutinska storitev, ki se pokliče, kadar se TCNT0 prelije:

ISR (TIMER0_OVF_vect)

{tot_overflow ++; // spremljajte število prelivov}

Ta ISR se sproži vsakič, ko pride do ujemanja, zato preklopite tukaj:

ISR (TIMER1_COMPA_vect) {PORTC ^= (1 << 1); // stikalo vodi tukaj}

int main (void)

{DDRB | = (1 << 0); // priključimo 1 (zeleno) na pin PB0 DDRC | = (1 << 1); // priključimo 2 (modra) na pin PC1 DDRB | = (1 << 3); // priključimo 3 (rdeče) vodilo na pin PB3 (OC2A) timer0_init (); // inicializiramo timer0 timer1_init (); // inicializiramo timer1 timer2_init (); // inicializiramo timer2 while (1) // zanko za vedno {

Če je Timer0 preletel 12 -krat, bi minilo 12 * 4,096 ms = 49,152 ms. V 13. ponovitvi potrebujemo zamudo 50 ms - 49,152 ms = 0,848 ms. Tako v 13. ponovitvi dopuščamo, da časovnik šteje le do 53, nato pa ga ponastavimo.

if (tot_overflow> = 12) // preveri, če ne. pretokov = 12 OPOMBA: '> =' se uporablja

{if (TCNT0> = 53) // preveri, če števec časovnika doseže 53 {PORTB ^= (1 << 0); // preklopi LED TCNT0 = 0; // ponastavi števec tot_overflow = 0; // ponastavi števec prelivov}}}}

Nalaganje datoteke HEX v pomnilnik mikrokrmilnika:

v okno poziva DOS vnesite ukaz:

avrdude –c [ime programerja] –p m328p –u –U bliskavica: w: [ime vaše šestnajstiške datoteke] V mojem primeru je to: avrdude –c ISPProgv1 –p m328p –u –U bliskavica: w: Timers.hex

Ta ukaz zapiše šestnajstiško datoteko v pomnilnik mikrokrmilnika. Oglejte si video s podrobnim opisom zapisovanja bliskovnega pomnilnika mikrokrmilnika:

Zapis flash pomnilnika mikrokrmilnika …

V redu! Zdaj mikrokrmilnik deluje v skladu z navodili našega programa. Preverimo!

6. korak: Izdelava električnega vezja

Izdelava električnega vezja
Izdelava električnega vezja
Izdelava električnega vezja
Izdelava električnega vezja
Izdelava električnega vezja
Izdelava električnega vezja

Priključite komponente v skladu s shematskim diagramom.

Priporočena: