Innholdsfortegnelse:

AVR mikrokontroller. Lysdioder Blinker ved hjelp av tidtaker. Timere avbryter. Timer CTC -modus: 6 trinn
AVR mikrokontroller. Lysdioder Blinker ved hjelp av tidtaker. Timere avbryter. Timer CTC -modus: 6 trinn

Video: AVR mikrokontroller. Lysdioder Blinker ved hjelp av tidtaker. Timere avbryter. Timer CTC -modus: 6 trinn

Video: AVR mikrokontroller. Lysdioder Blinker ved hjelp av tidtaker. Timere avbryter. Timer CTC -modus: 6 trinn
Video: Lesson 2: Getting Arduino Software and using Documentation for SunFounder Arduino Kit | SunFounder 2024, Juli
Anonim
Image
Image

Hei alle sammen!

Timere er et viktig konsept innen elektronikk. Hver elektronisk komponent fungerer tidsmessig. Denne tidsbasen hjelper til med å holde alt arbeidet synkronisert. Alle mikrokontrollerne jobber med en forhåndsdefinert klokkefrekvens, de har alle en bestemmelse for å sette opp tidtakere. AVR skryter av å ha en timer som er veldig nøyaktig, presis og pålitelig. Det tilbyr mange funksjoner i det, og gjør det dermed til et stort tema. Det beste er at timeren er helt uavhengig av CPU. Dermed går den parallelt med CPU'en, og det er ingen CPU -inngrep, noe som gjør timeren ganske nøyaktig. I denne delen forklarer jeg de grunnleggende konseptene til AVR -tidtakere. Jeg skriver enkelt program i C -kode for å kontrollere LED -blink, ved hjelp av tidtakere.

Trinn 1: Beskrivelse

Problemerklæring 1: Let's Flash First LED (grønn) Hver 50. ms
Problemerklæring 1: Let's Flash First LED (grønn) Hver 50. ms

I ATMega328 er det tre typer tidtakere:

Timer/Counter0 (TC0) - er en generell 8 -biters Timer/Counter -modul, med to uavhengige OutputCompare Units og PWM -støtte;

Timer/Counter1 (TC1) - 16 -biters Timer/Counter -enhet tillater nøyaktig programkjøringstidspunkt (hendelsesstyring), bølgegenerering og signaltiming;

Timer/Counter2 (TC2) -er en generell formål, kanal, 8 -biters Timer/Counter -modul med PWM og asynkron drift;

Trinn 2: Problemerklæring 1: Let's Flash First LED (grønn) Hver 50. ms

Problemerklæring 1: Let's Flash First LED (grønn) Hver 50. ms
Problemerklæring 1: Let's Flash First LED (grønn) Hver 50. ms
Problemerklæring 1: Let's Flash First LED (grønn) Hver 50. ms
Problemerklæring 1: Let's Flash First LED (grønn) Hver 50. ms

Metodikk:

- bruk av en Timer0 -forkalkning for å redusere et høyfrekvent elektrisk signal til en lavere frekvens ved heltallsdeling;

- bruk av et avbrudd hver gang Timer0 flyter over;

Timer0 (8 bit) det teller fra 0 til 255 etter det, de flyter over, denne verdien endres for hver klokkepuls.

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

Tidtaker = (Påkrevd forsinkelse / klokkeperiode) -1 = (50ms / 0.0000625ms) = 799999

Klokken har allerede krysset 799999 ganger for å gi en forsinkelse på bare 50 ms!

Vi kan bruke teknikken for frekvensdeling kalles forskalering for å redusere timertallet. AVR tilbyr oss følgende verdier for forkalking å velge mellom: 8, 64, 256 og 1024. Se tabellen som oppsummerer resultatene av bruk av forskjellige forkalkere.

Tellerverdien skal alltid være et heltall. La oss velge en forkalkningsmaskin 256!

I de fleste mikrokontrollere er det noe som heter Interrupt. Dette avbruddet kan avfyres når visse betingelser er oppfylt. Når en avbrudd utløses, stopper AVR og lagrer utførelsen av hovedrutinen, går til avbruddssamtalen (ved å utføre en spesiell rutine, kalt Interrupt Service Routine, ISR), og når den er ferdig med den, går den tilbake til hovedrutinen og fortsetter å utføre den.

Siden den nødvendige forsinkelsen (50 ms) er større enn den maksimale mulige forsinkelsen: 4, 096 ms = 1000 ms / 62500Hz * 256, vil timeren åpenbart flyte over. Og hver gang timeren flyter over, blir det avbrutt.

Hvor mange ganger skal avbruddet avfyres?

50ms / 4.096ms = 3125 /256 = 12.207 Hvis timeren har overflyttet 12 ganger, ville 12 * 4.096ms = 49.152ms ha passert. I den 13. iterasjonen trenger vi en forsinkelse på 50 ms - 49,152 ms = 0,848 ms.

Ved en frekvens på 62500Hz (prescaler = 256) tar hvert kryss 0,016ms. For å oppnå en forsinkelse på 0,848 ms, ville det derfor kreve 0,848 ms / 0,016 ms = 53 flått. I den 13. iterasjonen tillater vi derfor bare timeren å telle opptil 53, og deretter tilbakestille den.

Initialiser timer 0/teller (se bilde):

TCCR0B | = (1 << CS02) // sette opp timer med prescaler = 256 TCNT0 = 0 // initialisere teller TIMSK0 | = (1 << TOIE0) // aktivere overløp avbryte sei () // aktivere globale avbrudd tot_overflow = 0 // initialiser overløpstellervariabel

Trinn 3: Problemerklæring 2: Let's Flash Second LED (blå) Hver 1

Problemerklæring 2: Let's Flash Second LED (blå) Hver 1
Problemerklæring 2: Let's Flash Second LED (blå) Hver 1
Problemerklæring 2: Let's Flash Second LED (blå) Hver 1
Problemerklæring 2: Let's Flash Second LED (blå) Hver 1
Problemerklæring 2: Let's Flash Second LED (blå) Hver 1
Problemerklæring 2: Let's Flash Second LED (blå) Hver 1

Metodikk:

- bruk av en Timer1 -forkalkning for å redusere et høyfrekvent elektrisk signal til en lavere frekvens ved heltallsdeling;

- ved hjelp av Clear Timer på Compare (CTC) -modus;

- bruk avbrudd med CTC -modus;

Timer1 (16 bit) det teller fra 0 til 65534 etter det, de flyter over. Denne verdien endres for hver klokkepuls.

F_CPU = 16MHz: Klokkeperiode = 1000ms / 16000000Hz = 0.0000625msTimerantall ((påkrevd forsinkelse / klokkeperiode) -1 = (1000ms / 0.0000625ms) = 15999999

Klokken har allerede merket 15999999 ganger for å gi en forsinkelse på 1s!

Vi kan bruke teknikken for frekvensdeling kalles forskalering for å redusere timertallet. AVR tilbyr oss følgende verdier for forkalking å velge mellom: 8, 64, 256 og 1024. Se tabellen som oppsummerer resultatene av bruk av forskjellige forkalkere. Tellerverdien skal alltid være et heltall. La oss velge en forkalkningsmaskin 256!

I Clear timer på Compare (CTC) -modus brukes OCR1A eller ICR1 -registeret til å manipulere telleroppløsningen. I CTC -modus telleren tømmes til null når tellerverdien (TCNT1) matcher enten OCR1A eller ICR1. OCR1A eller ICR1 definerer toppverdien for telleren, derav også dens oppløsning. Denne modusen gir større kontroll over sammenligningsutgangsfrekvensen. Det forenkler også driften av å telle eksterne hendelser. Vi må be AVR om å tilbakestille Timer1/Counter så snart verdien når verdien 62500, og dermed oppnå en forsinkelse på 1s.

Initialiser tidtaker1/teller (se bilde):

TCCR1B | = (1 << WGM12) | (1 << CS12) // oppsett timer med prescaler = 256 og CTC -modus TCNT1 = 0 // initialiser teller TIMSK1 | = (1 << OCIE1A) // aktiver sammenligne avbryt OCR1A = 62500 // initialiser sammenligningsverdi

Trinn 4: Problemerklæring 3: Let’s Flash Third LED (rød) hver 16. ms

Problemerklæring 3: Let’s Flash Third LED (rød) hver 16. ms
Problemerklæring 3: Let’s Flash Third LED (rød) hver 16. ms
Problemerklæring 3: Let’s Flash Third LED (rød) hver 16. ms
Problemerklæring 3: Let’s Flash Third LED (rød) hver 16. ms
Problemerklæring 3: Let’s Flash Third LED (rød) hver 16. ms
Problemerklæring 3: Let’s Flash Third LED (rød) hver 16. ms
Problemerklæring 3: Let’s Flash Third LED (rød) hver 16. ms
Problemerklæring 3: Let’s Flash Third LED (rød) hver 16. ms

Metodikk:

- bruk av en Timer2 -forkalkning for å redusere et høyfrekvent elektrisk signal til en lavere frekvens ved heltallsdeling;

- ved hjelp av Clear Timer på Compare (CTC) -modus;

- bruk av maskinvare CTC -modus uten avbrudd;

Timer2 (8 bit) det teller fra 0 til 255 etter det, de flyter over. Denne verdien endres for hver klokkepuls.

F_CPU = 16MHz: Klokke tidsperiode = 1000ms / 16000000Hz = 0.0000625ms

Tidtaker = (Påkrevd forsinkelse / klokkeperiode) -1 = (16ms / 0.0000625ms) = 255999

Klokken har allerede krysset 255999 ganger for å gi en forsinkelse på 16 ms!

Se tabellen oppsummerer resultatene av bruk av forskjellige prescalers. Tellerverdien skal alltid være et heltall. La oss velge en prescaler 1024!

I CTC -modus telleren tømmes til null når tellerverdien (TCNT2) matcher enten OCR2A eller ICR2. Pin PB3 er også Output Compare -pinnen til TIMER2 - OC2A (se diagram).

Timer/Counter2 Control Register A - TCCR2A Bit 7: 6 - COM2A1: 0 - Compare Output Mode for Compare Unit A. Siden vi må bytte LED, velger vi alternativet: Toggle OC2A på Compare Match Når en sammenligning oppstår, vil OC2A -pinnen veksles automatisk. Du trenger ikke å sjekke noen flaggbit, du trenger ikke å ta vare på noen avbrudd.

Initialiser Timer2/Counter

TCCR2A | = (1 << COM2A0) | (1 << WGM21) // sett opp timer OC2A -pin i vekselmodus og CTC -modus TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20) // sette opp tidtaker med prescaler = 1024 TCNT2 = 0 // initialisere teller OCR2A = 250 // initialisere sammenligningsverdi

Trinn 5: Skrive kode for et program i C. Laste opp HEX -fil til mikrokontrollerens flashminne

Skrive kode for et program i C. Laste opp HEX -fil til mikrokontrollerens flashminne
Skrive kode for et program i C. Laste opp HEX -fil til mikrokontrollerens flashminne
Skrive kode for et program i C. Laste opp HEX -fil til mikrokontrollerens flashminne
Skrive kode for et program i C. Laste opp HEX -fil til mikrokontrollerens flashminne

Skrive og bygge AVR -mikrokontrollerprogrammet i C -kode ved hjelp av den integrerte utviklingsplattformen - Atmel Studio.

F_CPU definerer klokkefrekvensen i Hertz og er vanlig i programmer som bruker avr-libc-biblioteket. I dette tilfellet brukes det av forsinkelsesrutinene for å bestemme hvordan man skal beregne forsinkelser.

#ifndef F_CPU

#define F_CPU 16000000UL // forteller kontrolleren krystallfrekvens (16 MHz AVR ATMega328P) #endif

#include // header for å aktivere dataflytkontroll over pins. Definerer pinner, porter, etc.

Den første inkluderer-filen er en del av avr-libc og vil bli brukt i stort sett alle AVR-prosjekter du jobber med. io.h vil bestemme CPU -en du bruker (det er derfor du angir delen når du kompilerer) og vil deretter inkludere den riktige IO -definisjonsoverskriften for brikken vi bruker. Den definerer ganske enkelt konstantene for alle dine pinner, porter, spesielle registre osv.

#include // header for å aktivere avbrudd

flyktig uint8_t tot_overflow; // global variabel for å telle antall overløp

Metode for problemformulering: Flash First (grønn) LED hver 50 ms

- bruk av en Timer0 -forkalkning for å redusere et høyfrekvent elektrisk signal til en lavere frekvens ved heltallsdeling;

- bruk av et avbrudd hver gang Timer0 flyter over;

void timer0_init () // initialize timer0, interrupt and variable

{TCCR0B | = (1 << CS02); // sette opp timer med prescaler = 256 TCNT0 = 0; // initialiser telleren TIMSK0 | = (1 << TOIE0); // aktiver overløp nterrupt sei (); // aktivere globale avbrudd tot_overflow = 0; // initialiser overløpstellervariabel}

Metodikk for problemformulering: Flash Second LED (blå) hver 1

- bruk av en Timer1 -forkalkning for å redusere et høyfrekvent elektrisk signal til en lavere frekvens ved heltallsdeling;

- ved hjelp av Clear Timer på Compare (CTC) -modus;

- bruk avbrudd med CTC -modus;

void timer1_init () // initialize timer1, interrupt and variable {TCCR1B | = (1 << WGM12) | (1 << CS12); // sette opp timer med prescaler = 256 og CTC -modus TCNT1 = 0; // initialiser teller OCR1A = 62500; // initialiser sammenligningsverdi TIMSK1 | = (1 << OCIE1A); // aktiver sammenligningsavbrudd}

Metode for problemformulering: Blits tredje LED (rød) hver 16. ms

- bruk av en Timer2 -forkalkning for å redusere et høyfrekvent elektrisk signal til en lavere frekvens ved heltallsdeling;

- ved hjelp av Clear Timer på Compare (CTC) -modus;

- bruk av maskinvare CTC -modus uten avbrudd;

void timer2_init () // initialize timer2 {TCCR2A | = (1 << COM2A0) | (1 << WGM21); // sette opp timer OC2A -pin i vekselmodus og CTC -modus TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20); // sette opp timer med prescaler = 1024 TCNT2 = 0; // initialiser teller OCR2A = 250; // initialiser sammenligningsverdi}

TIMER0 overløpsavbruddsrutine kalles når TCNT0 flyter over:

ISR (TIMER0_OVF_vect)

{tot_overflow ++; // holde oversikt over antall overløp}

Denne ISR -en blir avfyrt hver gang en kamp oppstår, og vekslingen ledet her selv:

ISR (TIMER1_COMPA_vect) {PORTC ^= (1 << 1); // veksle ledet her}

int main (ugyldig)

{DDRB | = (1 << 0); // koble 1 (grønn) til pin PB0 DDRC | = (1 << 1); // koble 2 (blå) led til pin PC1 DDRB | = (1 << 3); // koble 3 (rød) til pin PB3 (OC2A) timer0_init (); // initialiser timer0 timer1_init (); // initialiser timer1 timer2_init (); // initialiser timer2 mens (1) // loop for alltid {

Hvis Timer0 har overflyttet 12 ganger, ville 12 * 4,096 ms = 49,152 ms ha passert. I den 13. iterasjonen trenger vi en forsinkelse på 50 ms - 49,152 ms = 0,848 ms. I den 13. iterasjonen tillater vi derfor bare timeren å telle opptil 53, og deretter tilbakestille den.

if (tot_overflow> = 12) // sjekk om nei. av overløp = 12 MERK: '> =' brukes

{if (TCNT0> = 53) // sjekk om timertallet når 53 {PORTB ^= (1 << 0); // bytter ledet TCNT0 = 0; // reset reset tot_overflow = 0; // tilbakestill overløpsteller}}}}

Laster opp HEX -fil til mikrokontrollerens flashminne:

skriv inn kommandoen DOS -ledetekst:

avrdude –c [navn på programmerer] –p m328p –u –U flash: w: [navn på hex -filen din] I mitt tilfelle er det: avrdude –c ISPProgv1 –p m328p –u –U flash: w: Timers.hex

Denne kommandoen skriver hex -fil til mikrokontrollerens minne. Se videoen med en detaljert beskrivelse av brenning av mikrokontroller -flashminne:

Mikrokontroller blitsminne brenner …

Ok! Nå fungerer mikrokontrolleren i henhold til instruksjonene i programmet vårt. La oss sjekke det ut!

Trinn 6: Lag den elektriske kretsen

Gjør den elektriske kretsen
Gjør den elektriske kretsen
Gjør den elektriske kretsen
Gjør den elektriske kretsen
Gjør den elektriske kretsen
Gjør den elektriske kretsen

Koble til komponenter i henhold til skjematisk diagram.

Anbefalt: