Innehållsförteckning:

AVR -mikrokontroller. Lysdioder blinkar med timer. Timers avbryter. Timer CTC -läge: 6 steg
AVR -mikrokontroller. Lysdioder blinkar med timer. Timers avbryter. Timer CTC -läge: 6 steg

Video: AVR -mikrokontroller. Lysdioder blinkar med timer. Timers avbryter. Timer CTC -läge: 6 steg

Video: AVR -mikrokontroller. Lysdioder blinkar med timer. Timers avbryter. Timer CTC -läge: 6 steg
Video: LDmicro 8: Охранная сигнализация с таймерами (программирование лестничной схемы ПЛК микроконтроллера с помощью LDmicro) 2024, November
Anonim
Image
Image

Hej alla!

Timers är ett viktigt koncept inom elektronik. Varje elektronisk komponent fungerar på en tidsbas. Denna tidsbas hjälper till att hålla allt arbete synkroniserat. Alla mikrokontroller fungerar med någon fördefinierad klockfrekvens, de har alla en bestämmelse för att ställa in timers. AVR skryter med att ha en timer som är mycket exakt, exakt och pålitlig. Det erbjuder massor av funktioner i det, vilket gör det till ett stort ämne. Det bästa är att timern är helt oberoende av CPU: n. Således går den parallellt med CPU: n och det finns ingen CPU: s ingrepp, vilket gör timern ganska exakt. I detta avsnitt förklarar jag de grundläggande begreppen för AVR -timer. Jag skriver ett enkelt program i C -kod för att styra LED -blinkare, med hjälp av timers.

Steg 1: Beskrivning

Problemmeddelande 1: Let's Flash First LED (grönt) var 50: e ms
Problemmeddelande 1: Let's Flash First LED (grönt) var 50: e ms

I ATMega328 finns det tre typer av timers:

Timer/Counter0 (TC0) - är en 8 -bitars Timer/Counter -modul för allmänna ändamål, med två oberoende OutputCompare -enheter och PWM -stöd;

Timer/Counter1 (TC1) - 16 -bitars Timer/Counter -enheten möjliggör exakt programkörningstid (händelsehantering), våggenerering och signalmätning;

Timer/Counter2 (TC2) -är en allmän, kanal, 8 -bitars Timer/Counter -modul med PWM och asynkron drift;

Steg 2: Problemmeddelande 1: Let's Flash First LED (grönt) Var 50: e ms

Problemmeddelande 1: Let's Flash First LED (grönt) var 50: e ms
Problemmeddelande 1: Let's Flash First LED (grönt) var 50: e ms
Problemmeddelande 1: Let's Flash First LED (grönt) var 50: e ms
Problemmeddelande 1: Let's Flash First LED (grönt) var 50: e ms

Metodik:

- att använda en Timer0 -förkalkylator för att reducera en högfrekvent elektrisk signal till en lägre frekvens genom heltal;

- använder ett avbrott varje gång timern0 flyter över;

Timer0 (8 bit) det räknar från 0 till 255 efter det, de flödar över, detta värde ändras vid varje klockpuls.

F_CPU = 16MHz: Klockans tidsperiod = 1000ms / 16000000Hz = 0.0000625ms

Timerantal = (Obligatorisk fördröjning / klockperiod) -1 = (50ms / 0.0000625ms) = 799999

Klockan har redan tickat 799999 gånger för att ge en fördröjning på bara 50 ms!

Vi kan använda tekniken för frekvensdelning kallas förskalning för att minska timern. AVR erbjuder oss följande förkalkningsvärden att välja mellan: 8, 64, 256 och 1024. Se tabellen sammanfattar resultaten av att använda olika förkalkningsmedel.

Räknarvärdet ska alltid vara ett heltal. Låt oss välja en förkalkning 256!

I de flesta mikrokontroller finns det något som heter Avbrott. Detta avbrott kan avfyras när vissa villkor är uppfyllda. Nu när ett avbrott avfyras stannar AVR och sparar dess körning av huvudrutinen, tar hand om avbrottsanropet (genom att utföra en speciell rutin, kallad Interrupt Service Routine, ISR) och när det är klart med det, återgår till huvudrutin och fortsätter att köra den.

Eftersom den erforderliga fördröjningen (50 ms) är större än den maximala möjliga fördröjningen: 4, 096 ms = 1000 ms / 62500Hz * 256, kommer tydligen timern att flyta över. Och när timern rinner över avfyras ett avbrott.

Hur många gånger ska avbrottet avfyras?

50ms / 4.096ms = 3125 /256 = 12.207 Om timern har gått över 12 gånger hade 12 * 4.096ms = 49.152ms gått. I den 13: e iterationen behöver vi en fördröjning på 50 ms - 49,152 ms = 0,848 ms.

Vid en frekvens av 62500Hz (förkalkning = 256) tar varje fästing 0,016ms. Således för att uppnå en fördröjning på 0,848 ms, skulle det kräva 0,848ms / 0,016ms = 53 fästingar. Således, i den 13: e iterationen, tillåter vi bara timern att räkna upp till 53 och sedan återställa den.

Initiera timer 0/räknare (se bild):

TCCR0B | = (1 << CS02) // ställa in timer med förkalkning = 256 TCNT0 = 0 // initiera räknare TIMSK0 | = (1 << TOIE0) // aktivera överflödsavbrott sei () // aktivera globala avbrott tot_overflow = 0 // initiera variabel för överflödsräknare

Steg 3: Problemmeddelande 2: Let's Flash Second LED (blå) var 1: e

Problemmeddelande 2: Let's Flash Second LED (blå) var 1: e
Problemmeddelande 2: Let's Flash Second LED (blå) var 1: e
Problemmeddelande 2: Let's Flash Second LED (blå) var 1: e
Problemmeddelande 2: Let's Flash Second LED (blå) var 1: e
Problemmeddelande 2: Let's Flash Second LED (blå) var 1: e
Problemmeddelande 2: Let's Flash Second LED (blå) var 1: e

Metodik:

- att använda en Timer1 -förkalkylator för att reducera en högfrekvent elektrisk signal till en lägre frekvens genom heltal;

- använda Clear Timer i jämförelse (CTC) -läge;

- använder avbrott med CTC -läge;

Timer1 (16 bit) det räknas från 0 till 65534 efter det, de flödar över. Detta värde ändras vid varje klockpuls.

F_CPU = 16MHz: Klockans tidsperiod = 1000ms / 16000000Hz = 0.0000625msTimerantal = (Obligatorisk fördröjning / klockperiod) -1 = (1000ms / 0.0000625ms) = 15999999

Klockan har redan tickat 15999999 gånger för att ge en fördröjning på 1s!

Vi kan använda tekniken för frekvensdelning kallas förskalning för att minska timern. AVR erbjuder oss följande förkalkningsvärden att välja mellan: 8, 64, 256 och 1024. Se tabellen sammanfattar resultaten av att använda olika förkalkningsmedel. Räknarvärdet ska alltid vara ett heltal. Låt oss välja en förkalkning 256!

I Clear timer i jämförelse (CTC) -läget används OCR1A- eller ICR1 -registret för att manipulera räkneupplösningen. I CTC -läge raderas räknaren till noll när räknarvärdet (TCNT1) matchar antingen OCR1A eller ICR1. OCR1A eller ICR1 definierar toppvärdet för räknaren, därav också dess upplösning. Detta läge möjliggör större kontroll över jämförelseutgångsfrekvensen. Det förenklar också driften av att räkna externa händelser. Vi måste säga till AVR: n att återställa timern1/räknaren så snart dess värde når värdet 62500, för att uppnå en fördröjning på 1s.

Initiera Timer1/Counter (se bild):

TCCR1B | = (1 << WGM12) | (1 << CS12) // ställa in timer med prescaler = 256 och CTC -läge TCNT1 = 0 // initialisera räknare TIMSK1 | = (1 << OCIE1A) // aktivera jämför avbrott OCR1A = 62500 // initiera jämför värde

Steg 4: Problemmeddelande 3: Let's Flash Third LED (röd) var 16: e minut

Problemmeddelande 3: Let's Flash Third LED (röd) var 16: e minut
Problemmeddelande 3: Let's Flash Third LED (röd) var 16: e minut
Problemmeddelande 3: Let's Flash Third LED (röd) var 16: e minut
Problemmeddelande 3: Let's Flash Third LED (röd) var 16: e minut
Problemmeddelande 3: Let's Flash Third LED (röd) var 16: e minut
Problemmeddelande 3: Let's Flash Third LED (röd) var 16: e minut
Problemmeddelande 3: Let's Flash Third LED (röd) var 16: e minut
Problemmeddelande 3: Let's Flash Third LED (röd) var 16: e minut

Metodik:

- att använda en Timer2 -förkalkylator för att reducera en högfrekvent elektrisk signal till en lägre frekvens genom heltal;

- använda Clear Timer i jämförelse (CTC) -läge;

- använda maskinvarukortläge utan avbrott;

Timer2 (8 bit) det räknas från 0 till 255 efter det, de flödar över. Detta värde ändras vid varje klockpuls.

F_CPU = 16MHz: Klockans tidsperiod = 1000ms / 16000000Hz = 0.0000625ms

Timerantal = (Obligatorisk fördröjning / klockperiod) -1 = (16ms / 0.0000625ms) = 255999

Klockan har redan tickat 255999 gånger för att ge en fördröjning på 16 ms!

Se tabellen sammanfattar resultaten av att använda olika prescalers. Räknarvärdet ska alltid vara ett heltal. Låt oss välja en förkalkning 1024!

I CTC -läge raderas räknaren till noll när räknarvärdet (TCNT2) matchar antingen OCR2A eller ICR2. Pin PB3 är också Output Compare pin för TIMER2 - OC2A (se diagram).

Timer/Counter2 -kontrollregister A - TCCR2A Bit 7: 6 - COM2A1: 0 - Jämför utmatningsläge för jämförelse A. Eftersom vi måste växla mellan lysdioden väljer vi alternativet: Växla OC2A till Jämför matchning När en jämförelsematchning inträffar kommer OC2A -stift växlas automatiskt. Du behöver inte kontrollera någon flaggbit, du behöver inte ta hand om några avbrott.

Initiera Timer2/Counter

TCCR2A | = (1 << COM2A0) | (1 << WGM21) // ställ in timer OC2A -stift i växlingsläge och CTC -läge TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20) // ställa in timer med förkalkning = 1024 TCNT2 = 0 // initieringsräknare OCR2A = 250 // initiera jämför värde

Steg 5: Skriva kod för ett program i C. Överföring av HEX -fil till mikrokontrollerns flashminne

Skriva kod för ett program i C. Överföra HEX -fil till mikrokontrollerns flashminne
Skriva kod för ett program i C. Överföra HEX -fil till mikrokontrollerns flashminne
Skriva kod för ett program i C. Överföra HEX -fil till mikrokontrollerns flashminne
Skriva kod för ett program i C. Överföra HEX -fil till mikrokontrollerns flashminne

Skriva och bygga AVR -mikrokontrollerprogrammet i C -kod med hjälp av den integrerade utvecklingsplattformen - Atmel Studio.

F_CPU definierar klockfrekvensen i Hertz och är vanlig i program som använder avr-libc-biblioteket. I detta fall används det av fördröjningsrutinerna för att bestämma hur man beräknar tidsfördröjningar.

#ifndef F_CPU

#define F_CPU 16000000UL // berättar styrenhetens kristallfrekvens (16 MHz AVR ATMega328P) #endif

#include // header för att möjliggöra dataflödeskontroll över stift. Definierar stift, portar etc.

Den första inkluderar-filen är en del av avr-libc och kommer att användas i nästan alla AVR-projekt du arbetar med. io.h kommer att avgöra vilken processor du använder (det är därför du anger delen vid kompilering) och i sin tur inkludera lämplig IO -definitionhuvud för det chip vi använder. Det definierar helt enkelt konstanterna för alla dina stift, portar, specialregister, etc.

#include // header för att aktivera avbrott

flyktigt uint8_t tot_overflow; // global variabel för att räkna antalet överflöden

Metod för problemmeddelande: Flash First (grön) LED var 50: e ms

- att använda en Timer0 -förkalkylator för att reducera en högfrekvent elektrisk signal till en lägre frekvens genom heltal;

- använder ett avbrott varje gång timern0 flyter över;

void timer0_init () // initiera timer0, avbrott och variabel

{TCCR0B | = (1 << CS02); // ställa in timer med förkalkning = 256 TCNT0 = 0; // initiera räknaren TIMSK0 | = (1 << TOIE0); // aktivera överflöd nterrupt sei (); // aktivera globala avbrott tot_overflow = 0; // initiera överflödesräknare variabel}

Metod för problemmeddelande: Flash Second LED (blå) var 1: e

- att använda en Timer1 -förkalkylator för att reducera en högfrekvent elektrisk signal till en lägre frekvens genom heltal;

- använda Clear Timer i jämförelse (CTC) -läge;

- använda avbrott med CTC -läge;

void timer1_init () // initialize timer1, interrupt and variable {TCCR1B | = (1 << WGM12) | (1 << CS12); // ställa in timer med förkalkning = 256 och CTC -läge TCNT1 = 0; // initiera räknaren OCR1A = 62500; // initiera jämför värde TIMSK1 | = (1 << OCIE1A); // aktivera jämför avbrott}

Metod för problemmeddelande: Flash tredje LED (röd) var 16: e ms

- att använda en Timer2 -förkalkylator för att reducera en högfrekvent elektrisk signal till en lägre frekvens genom heltal;

- använda Clear Timer i jämförelse (CTC) -läge;

- använda maskinvarukortläge utan avbrott;

void timer2_init () // initialize timer2 {TCCR2A | = (1 << COM2A0) | (1 << WGM21); // ställa in timer OC2A -stift i växlingsläge och CTC -läge TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20); // ställa in timer med förkalkning = 1024 TCNT2 = 0; // initiera räknaren OCR2A = 250; // initiera jämför värde}

TIMER0 överflödsavbrottstjänstrutin anropas när TCNT0 flödar över:

ISR (TIMER0_OVF_vect)

{tot_overflow ++; // hålla koll på antalet överflöden}

Denna ISR avfyras varje gång en match inträffar, därför växlar ledningen här själv:

ISR (TIMER1_COMPA_vect) {PORTC ^= (1 << 1); // växla ledde här}

int main (void)

{DDRB | = (1 << 0); // anslut 1 (grön) ledde till stift PB0 DDRC | = (1 << 1); // anslut 2 (blå) led till pin PC1 DDRB | = (1 << 3); // anslut 3 (röd) ledde till stift PB3 (OC2A) timer0_init (); // initiera timer0 timer1_init (); // initiera timer1 timer2_init (); // initiera timer2 medan (1) // loop för alltid {

Om timern0 har gått över 12 gånger hade 12 * 4,096 ms = 49,152 ms passerat. I den 13: e iterationen behöver vi en fördröjning på 50 ms - 49,152 ms = 0,848 ms. Således, i den 13: e iterationen, tillåter vi bara timern att räkna upp till 53 och sedan återställa den.

if (tot_overflow> = 12) // kontrollera om nej. av överflöden = 12 OBS: '> =' används

{if (TCNT0> = 53) // kontrollera om timertalet når 53 {PORTB ^= (1 << 0); // växlar LED TCNT0 = 0; // reset counter tot_overflow = 0; // återställ överflödesräknare}}}}

Ladda upp HEX -fil till mikrokontrollerns flashminne:

skriv kommandot i DOS -promptfönstret:

avrdude –c [namn på programmerare] –p m328p –u –U blixt: w: [namn på din hex -fil] I mitt fall är det: avrdude –c ISPProgv1 –p m328p –u –U flash: w: Timers.hex

Detta kommando skriver hex -fil till mikrokontrollerns minne. Titta på videon med en detaljerad beskrivning av mikrokontrollerens flashminne:

Mikrokontroller flashminne brinner …

Ok! Nu fungerar mikrokontrollern i enlighet med instruktionerna i vårt program. Låt oss kolla upp det!

Steg 6: Gör den elektriska kretsen

Gör den elektriska kretsen
Gör den elektriska kretsen
Gör den elektriska kretsen
Gör den elektriska kretsen
Gör den elektriska kretsen
Gör den elektriska kretsen

Anslut komponenter enligt schematiskt diagram.

Rekommenderad: