INHOUDSOPGAWE:

AVR -mikrobeheerder. LED's flitser met timer. Timers onderbreek. Timer CTC -modus: 6 stappe
AVR -mikrobeheerder. LED's flitser met timer. Timers onderbreek. Timer CTC -modus: 6 stappe

Video: AVR -mikrobeheerder. LED's flitser met timer. Timers onderbreek. Timer CTC -modus: 6 stappe

Video: AVR -mikrobeheerder. LED's flitser met timer. Timers onderbreek. Timer CTC -modus: 6 stappe
Video: Lesson 62: Time control without delay, LED blink with millis() | Arduino Step By Step Course 2024, November
Anonim
Image
Image

Hallo almal!

Timers is 'n belangrike konsep op die gebied van elektronika. Elke elektroniese komponent werk op 'n tydsbasis. Hierdie tydsbasis help om al die werk gesinchroniseer te hou. Al die mikrobeheerders werk teen 'n voorafbepaalde klokfrekwensie; hulle het almal 'n voorsiening om tydopnemers in te stel. AVR spog met 'n timer wat baie akkuraat, presies en betroubaar is. Dit bied baie funksies daarin, en maak dit dus 'n groot onderwerp. Die beste deel is dat die timer heeltemal onafhanklik van die SVE is. Dit loop dus parallel met die SVE en daar is geen ingryping van die SVE nie, wat die timer baie akkuraat maak. In hierdie afdeling verduidelik ek die basiese konsepte van AVR Timers. Ek skryf 'n eenvoudige program in C -kode om LED -flitsers te beheer, met behulp van tydtellers.

Stap 1: Beskrywing

Probleemstelling 1: Kom ons flits eerste LED (groen) elke 50 me
Probleemstelling 1: Kom ons flits eerste LED (groen) elke 50 me

In ATMega328 is daar drie soorte tydtellers:

Timer/Counter0 (TC0) - is 'n algemene 8 -bis Timer/Counter -module vir algemene doeleindes, met twee onafhanklike OutputCompare Units en PWM -ondersteuning;

Timer/Counter1 (TC1) - Die 16 -bit Timer/Counter -eenheid laat akkurate programuitvoeringstyd (gebeurtenisbestuur), golfopwekking en seintydmeting toe;

Timer/Counter2 (TC2) -is 'n algemene, kanaal, 8 -bis Timer/Counter -module met PWM en asynchrone werking;

Stap 2: Probleemstelling 1: Kom ons flits eerste LED (groen) Elke 50 me

Probleemstelling 1: Kom ons flits eerste LED (groen) elke 50 me
Probleemstelling 1: Kom ons flits eerste LED (groen) elke 50 me
Probleemstelling 1: Laat ons eerste LED flits (groen) elke 50 me
Probleemstelling 1: Laat ons eerste LED flits (groen) elke 50 me

Metodiek:

- die gebruik van 'n Timer0 -voorverkoeler om 'n hoëfrekwensie elektriese sein na 'n laer frekwensie te verminder deur heelgetalverdeling;

- gebruik 'n onderbreking elke keer as die Timer0 oorloop;

Timer0 (8 bit) dit tel van 0 tot 255 daarna, hulle loop oor, hierdie waarde verander by elke klokpuls.

F_CPU = 16MHz: tydsduur van die klok = 1000ms / 16000000Hz = 0.0000625ms

Tydtelling = (Vereiste vertraging / tydsperiode) -1 = (50ms / 0.0000625ms) = 799999

Die klok het reeds 799999 keer gemerk om 'n vertraging van slegs 50 ms te gee!

Ons kan die tegniek gebruik om die frekwensieverdeling voorskaling te gebruik om die tydtelling te verminder. Die AVR bied ons die volgende voorwaardes om van te kies: 8, 64, 256 en 1024. Sien die tabel 'n opsomming van die resultate van die gebruik van verskillende voorskalkers.

Die tellerwaarde moet altyd 'n heelgetal wees. Kom ons kies 'n voorverkoeler 256!

In die meeste mikrobeheerders is daar iets wat Interrupt genoem word. Hierdie onderbreking kan geskiet word wanneer aan sekere voorwaardes voldoen word. Elke keer as 'n onderbreking gevuur word, stop die AVR en stoor die uitvoering van die hoofroetine, neem die onderbrekingsoproep by (deur 'n spesiale roetine uit te voer, genaamd die onderbrekingsdiensroetine, ISR) en sodra dit klaar is, keer hy terug na die hoofroetine en gaan voort met die uitvoering daarvan.

Aangesien die vereiste vertraging (50ms) groter is as die maksimum moontlike vertraging: 4, 096ms = 1000ms / 62500Hz * 256, sal die timer natuurlik oorloop. En wanneer die timer oorloop, word 'n onderbreking afgevuur.

Hoeveel keer moet die onderbreking afgedank word?

50ms / 4.096ms = 3125 /256 = 12.207 As die timer 12 keer oorgeloop het, sou 12 * 4.096ms = 49.152ms verbygegaan het. In die 13de iterasie benodig ons 'n vertraging van 50 ms - 49,152 ms = 0,848 ms.

Met 'n frekwensie van 62500Hz (prescaler = 256) neem elke regmerkie 0,016ms. Om 'n vertraging van 0,848 ms te bereik, benodig dit 0,848ms / 0,016ms = 53 bosluise. Dus, in die 13de iterasie, laat ons die timer slegs tot 53 tel en stel dit dan terug.

Initialiseer timer 0/teller (sien prent):

TCCR0B | = (1 << CS02) // instel timer met prescaler = 256 TCNT0 = 0 // initialiseer teller TIMSK0 | = (1 << TOIE0) // aktiveer oorloop onderbreek sei () // aktiveer globale onderbrekingen tot_overflow = 0 // initialiseer die oorloopteller veranderlike

Stap 3: Probleemstelling 2: Let's Flash Second LED (blou) Elke 1e

Probleemstelling 2: Let's Flash Second LED (blou) Elke 1e
Probleemstelling 2: Let's Flash Second LED (blou) Elke 1e
Probleemstelling 2: Let's Flash Second LED (blou) Elke 1e
Probleemstelling 2: Let's Flash Second LED (blou) Elke 1e
Probleemstelling 2: Let's Flash Second LED (blou) Elke 1e
Probleemstelling 2: Let's Flash Second LED (blou) Elke 1e

Metodiek:

- die gebruik van 'n Timer1 -voorskaler om 'n hoëfrekwensie -elektriese sein na 'n laer frekwensie te verminder deur heelgetalverdeling;

- die gebruik van Clear Timer in die vergelykingsmodus (CTC);

- die gebruik van onderbrekings in die CTC -modus;

Timer1 (16 bit) dit tel van 0 tot 65534, daarna loop hulle oor. Hierdie waarde verander by elke klokpuls.

F_CPU = 16MHz: tydsperiode klok = 1000ms / 16000000Hz = 0.0000625ms Tydtelling = (vereiste vertraging / kloktydperk) -1 = (1000ms / 0.0000625ms) = 15999999

Die klok het reeds 15999999 keer gemerk om 'n vertraging van 1s te gee!

Ons kan die frekwensieverdelingstegniek gebruik, wat voorskaling genoem word om die tydtelling te verminder. Die AVR bied ons die volgende voorwaardes om van te kies: 8, 64, 256 en 1024. Sien die tabel 'n opsomming van die resultate van die gebruik van verskillende voorskalkers. Die tellerwaarde moet altyd 'n heelgetal wees. Kom ons kies 'n voorverkoeler 256!

In Clear timer in Compare (CTC) -modus word die OCR1A- of ICR1 -register gebruik om die tellerresolusie te manipuleer. In die CTC -modus word die teller tot nul skoongemaak wanneer die tellerwaarde (TCNT1) by die OCR1A of die ICR1 pas. Die OCR1A of ICR1 definieer die hoogste waarde vir die teller, vandaar ook die resolusie daarvan. Met hierdie modus kan u die frekwensie van vergelyking van die vergelyking van die vergelyking beter beheer. Dit vergemaklik ook die werking van die tel van eksterne gebeurtenisse. Ons moet die AVR sê om die Timer1/Counter terug te stel sodra die waarde daarvan 62500 bereik het, om sodoende 'n vertraging van 1s te bereik.

Initialiseer Timer1/Teller (sien foto):

TCCR1B | = (1 << WGM12) | (1 << CS12) // instel timer met prescaler = 256 en CTC modus TCNT1 = 0 // initialiseer teller TIMSK1 | = (1 << OCIE1A) // aktiveer vergelyk onderbreek OCR1A = 62500 // initialiseer vergelyk waarde

Stap 4: Probleemstelling 3: Laat ons die derde LED (rooi) elke 16 ms flits

Probleemstelling 3: Laat ons die derde LED (rooi) elke 16 ms flits
Probleemstelling 3: Laat ons die derde LED (rooi) elke 16 ms flits
Probleemstelling 3: Laat ons die derde LED (rooi) elke 16 ms flits
Probleemstelling 3: Laat ons die derde LED (rooi) elke 16 ms flits
Probleemstelling 3: Laat ons die derde LED (rooi) elke 16 ms flits
Probleemstelling 3: Laat ons die derde LED (rooi) elke 16 ms flits
Probleemstelling 3: Laat ons die derde LED (rooi) elke 16 ms flits
Probleemstelling 3: Laat ons die derde LED (rooi) elke 16 ms flits

Metodiek:

- die gebruik van 'n Timer2 -voorskaler om 'n hoëfrekwensie elektriese sein na 'n laer frekwensie te verminder deur heelgetalverdeling;

- die gebruik van Clear Timer in die vergelykingsmodus (CTC);

- die gebruik van hardeware CTC -modus sonder onderbrekings;

Timer2 (8 bis) dit tel van 0 tot 255 daarna, hulle loop oor. Hierdie waarde verander by elke klokpuls.

F_CPU = 16MHz: tydsperiode = 1000ms / 16000000Hz = 0.0000625ms

Tydtelling = (Vereiste vertraging / tydsperiode) -1 = (16ms / 0.0000625ms) = 255999

Die klok het al 255999 keer gemerk om 'n vertraging van 16 ms te gee!

Sien die tabel 'n opsomming van die resultate van die gebruik van verskillende prescalers. Die tellerwaarde moet altyd 'n heelgetal wees. Kom ons kies 'n voorverkoeler 1024!

In die CTC -modus word die teller tot nul skoongemaak wanneer die tellerwaarde (TCNT2) by die OCR2A of die ICR2 pas. Pin PB3 is ook die Output Vergelyk pen van TIMER2 - OC2A (sien diagram).

Timer/Counter2 -beheerregister A - TCCR2A Bit 7: 6 - COM2A1: 0 - Vergelyk die uitvoermodus vir vergelyking van eenheid A. Aangesien ons die LED moet skakel, kies ons die opsie: Wissel OC2A by Vergelyk wedstryd Wanneer 'n vergelyking pas, vind die OC2A -speld word outomaties aangeskakel. U hoef nie 'n vlagbit te kontroleer nie, u hoef nie aandag te skenk aan enige onderbrekings nie.

Initialiseer Timer2/Counter

TCCR2A | = (1 << COM2A0) | (1 << WGM21) // stel timer OC2A -pin in in skakelmodus en CTC -modus TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20) // instel timer met prescaler = 1024 TCNT2 = 0 // initialiseer teller OCR2A = 250 // initialiseer vergelyk waarde

Stap 5: Skryf kode vir 'n program in C. Laai HEX -lêer op na die mikrobeheerder se flitsgeheue

Skryf kode vir 'n program in C. Laai HEX -lêer op na die mikrobeheerder se flitsgeheue
Skryf kode vir 'n program in C. Laai HEX -lêer op na die mikrobeheerder se flitsgeheue
Skryf kode vir 'n program in C. Laai HEX -lêer op na die mikrobeheerder se flitsgeheue
Skryf kode vir 'n program in C. Laai HEX -lêer op na die mikrobeheerder se flitsgeheue

Skryf en bou van die AVR -mikrobeheertoepassing in C -kode met behulp van die Integrated Development Platform - Atmel Studio.

F_CPU definieer die klokfrekwensie in Hertz en is algemeen in programme wat die avr-libc-biblioteek gebruik. In hierdie geval word dit deur die vertragingsroetines gebruik om te bepaal hoe om tydvertragings te bereken.

#ifndef F_CPU

#definieer F_CPU 16000000UL // vertel die kristalfrekwensie van die beheerder (16 MHz AVR ATMega328P) #endif

#include // header om die datavloeibeheer oor penne moontlik te maak. Definieer penne, poorte, ens.

Die eerste insluit-lêer is deel van avr-libc en sal in feitlik enige AVR-projek waarmee u werk, gebruik word. io.h bepaal die SVE wat u gebruik (daarom spesifiseer u die deel tydens die opstel) en sluit op sy beurt die toepaslike IO -definisie -kop vir die chip wat ons gebruik. Dit definieer eenvoudig die konstantes vir al u penne, hawens, spesiale registers, ens.

#include // header om onderbreking moontlik te maak

vlugtige uint8_t tot_overflow; // globale veranderlike om die aantal oorstromings te tel

Metodiek van probleemstelling: Flits eerste (groen) LED elke 50 ms

- die gebruik van 'n Timer0 -voorverkoeler om 'n hoëfrekwensie elektriese sein na 'n laer frekwensie te verminder deur heelgetalverdeling;

- gebruik 'n onderbreking elke keer as die Timer0 oorloop;

leegte timer0_init () // begin timer0, onderbreek en veranderlik

{TCCR0B | = (1 << CS02); // instel timer met prescaler = 256 TCNT0 = 0; // initialiseer teller TIMSK0 | = (1 << TOIE0); // oorloop moontlik maak nterrupt sei (); // aktiveer globale onderbrekings tot_overflow = 0; // initialiseer oorloop teller veranderlike}

Metodiek vir probleemstelling: flits tweede LED (blou) elke 1 sekonde

- die gebruik van 'n Timer1 -voorskaler om 'n hoëfrekwensie elektriese sein na 'n laer frekwensie te verminder deur heelgetalverdeling;

- die gebruik van Clear Timer in die vergelykingsmodus (CTC);

- die gebruik van onderbrekings in die CTC -modus;

leemte timer1_init () // initialiseer timer1, onderbreking en veranderlike {TCCR1B | = (1 << WGM12) | (1 << CS12); // instel timer met prescaler = 256 en CTC -modus TCNT1 = 0; // initialiseer teller OCR1A = 62500; // initialiseer vergelyk waarde TIMSK1 | = (1 << OCIE1A); // aktiveer vergelyk onderbreek}

Metodiek van probleemstelling: Flits derde LED (rooi) elke 16 ms

- die gebruik van 'n Timer2 -voorskaler om 'n hoëfrekwensie elektriese sein na 'n laer frekwensie te verminder deur heelgetalverdeling;

- die gebruik van Clear Timer in die vergelykingsmodus (CTC);

- die gebruik van hardeware CTC -modus sonder onderbrekings;

leemte timer2_init () // initialiseer timer2 {TCCR2A | = (1 << COM2A0) | (1 << WGM21); // stel timer OC2A -pen in in skakelmodus en CTC -modus TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20); // instel timer met prescaler = 1024 TCNT2 = 0; // initialiseer teller OCR2A = 250; // initialiseer vergelyk waarde}

TIMER0 oorloop onderbreek diensroetine wanneer TCNT0 oorloop:

ISR (TIMER0_OVF_vect)

{tot_overloop ++; // hou tred met die aantal oorstromings}

Hierdie ISR word afgedank elke keer as 'n wedstryd plaasvind, en skakel hier self:

ISR (TIMER1_COMPA_vect) {PORTC ^= (1 << 1); // wissel hier gelei}

int main (leeg)

{DDRB | = (1 << 0); // verbind 1 (groen) tot pin PB0 DDRC | = (1 << 1); // verbind 2 (blou) gelei tot pen PC1 DDRB | = (1 << 3); // verbind 3 (rooi) gelei tot pin PB3 (OC2A) timer0_init (); // begin timer0 timer1_init (); // begin timer1 timer2_init (); // initialiseer timer2 terwyl (1) // lus vir ewig {

As die Timer0 12 keer oorgeloop het, sou 12 * 4.096ms = 49.152ms geslaag het. In die 13de iterasie benodig ons 'n vertraging van 50 ms - 49,152 ms = 0,848 ms. Dus, in die 13de iterasie, laat ons die timer slegs tot 53 tel en stel dit dan terug.

if (tot_overloop> = 12) // kyk of nee. van oorloop = 12 LET WEL: '> =' word gebruik

{if (TCNT0> = 53) // kyk of die tydteller 53 bereik {PORTB ^= (1 << 0); // skakel die geleide TCNT0 = 0; // reset counter tot_overflow = 0; // stel oorloopteller terug}}}}

Laai HEX -lêer op in die mikrobeheerder se flitsgeheue:

tik die opdrag in die DOS -promptvenster in:

avrdude –c [naam van programmeerder] –p m328p –u –U flits: w: [naam van u hex -lêer] In my geval is dit: avrdude –c ISPProgv1 –p m328p –u –U flits: w: Timers.hex

Hierdie opdrag skryf heks -lêer na die geheue van die mikrobeheerder. Kyk na die video met 'n gedetailleerde beskrywing van die verbranding van die flitsgeheue van die mikrobeheerder:

Mikrokontroleerder flitsgeheue brand …

Ok! Die mikrobeheerder werk nou volgens die instruksies van ons program. Kom ons kyk!

Stap 6: Maak die elektriese stroombaan

Maak die elektriese stroombaan
Maak die elektriese stroombaan
Maak die elektriese stroombaan
Maak die elektriese stroombaan
Maak die elektriese stroombaan
Maak die elektriese stroombaan

Verbind komponente volgens die skematiese diagram.

Aanbeveel: