För en tid sedan publicerade vi mer information om millis() funktion de ArduinoNu ska vi fördjupa oss i Arduino timer, för att komma igång med den här funktionen för funktionen, förstå hur det här kortet med MCU hanterar tid, såväl som andra funktioner bortom millis().
Vad är Arduino Timer?
El Arduino timer, eller timer, är en funktion implementerad av hårdvara (i mikrokontrollern, med hjälp av kvartskristallen som genererar klockpulserna och som ställer in "rytmen", utan behov av extern hårdvara eller ICs 555) som tillåter styrning av tillfälliga händelser tack vare klockor inre. Till exempel att få en uppgift att hända med intervaller, göra exakta tidsmätningar etc., oberoende av skisskoden.
Föreställ dig att du använder delay() funktion, kommer detta att blockera exekvering på Arduino MCU tills den angivna tiden går och sedan fortsätta med programmet, men timern blockerar inte. Det kommer att ske när MCU:n fortsätter att utföra andra instruktioner samtidigt. Det är den stora fördelen.
Timern är relaterad till avbrott av Arduino, eftersom de kommer att köras genom dem för att delta i någon specifik uppgift. Med andra ord är Arduino Timer en funktion som utlöses vid en viss tidpunkt, som utför en avbrottsfunktion. Därför är det också viktigt att känna till dessa avbrott.
Lägen
Arduino Timer har 2 driftlägen, att kunna använda den i:
- PWM-signal: Du kan styra Arduino-stift (~).
- CTC (Rensa timer vid jämför match): räknar tiden inuti en räknare och när den når det värde som anges i ett register över tidtagarna, exekveras avbrottet.
Hur många timers har den? Typer av timers
Det 3 timers på tallrikarna Arduino UNO, även om det kan finnas mer på andra toppplattor:
- timer 0: 8-bitar, kan räkna från 0 till 255 (256 möjliga värden). Används av funktioner som delay(), millis() och micros(). Dess modifiering rekommenderas inte för att inte ändra programmen.
- timer 1: lika med Timer 0. Används av Servo-biblioteket i UNO (Timer 5 för MEGA).
- timer 2: 16-bitars och kan variera från 0 till 65.525 65.536 (XNUMX XNUMX möjliga värden). Används för funktionen tone(), om den inte används kan den användas fritt för din applikation.
- Timer 3, 4, 5 (endast på Arduino MEGA): alla 16-bitars.
Hur fungerar Arduino Timer?
Till arbeta med en Arduino Timer, det är viktigt att veta hur allt detta fungerar elektroniskt i MCU på detta utvecklingskort:
- Klockfrekvens: är antalet cykler per sekund som den är kapabel att utveckla, i fallet med Arduino är det 16 Mhz, eller vad som är samma, klocksignalen svänger 16.000.000 XNUMX XNUMX gånger på en sekund (cykler).
- period: representeras av T, och mäts i sekunder, och är inversen av cyklerna. Till exempel, T=1/C, vilket skulle resultera i 1/16000000 = 0.0000000625, den tid det skulle ta för varje cykel att slutföra. Och frekvensen är inversen av perioden, så f = 1/T.
- cykel: är var och en av de upprepningar av signalen som sker per tidsenhet. På Arduino skulle det vara 16M på en sekund. Eller vad är detsamma, i det här fallet, när 16 miljoner cykler har passerat, har en sekund gått. Därför kan en cykel sägas ta 625 ns.
- kanten på en signal: Klocksignalerna är fyrkantiga och kanterna kan stiga eller falla. En kant är den räta linjen för signalen när den ändras från:
- 0 (låg) till 1 (hög): stigande kant.
- 1 (hög) till 0 (låg): fallande kant.
Kanter är viktiga eftersom Arduino-timers mäter cykler från signalkanter. A) Ja contador den ökar med varje cykel och när den når registervärdet exekveras avbrottet.
Därför, när du vet detta, om du har 16Mhz på Arduino MCU, och en 8-bitars timer används, kan man säga att avbrott kommer att inträffa var 16:e μs (256/16000000) eller 4 ms för 16-bitars (65536/16000000). Så, om du ställer in 16-bitars räknarregistret till maximum, med värdet 65535, kommer avbrottet att inträffa vid 4 ms för att utföra vilken uppgift det än är.
När räknaren når maximalt möjliga värde, den kommer att återgå till 0 igen. Det vill säga ett spill uppstår och det kommer att räknas tillbaka från början.
För att styra ökningshastigheten för timern kan du också använda en förskalare, som tar värdena 1, 8, 64, 256 och 1024 och ändrar timingen så här:
Timerhastighet (Hz) = Klockfrekvens för Arduino / Prescaler
Om det är 1 kommer förskalaren att öka till 16 Mhz, om det är 8 till 2 Mhz, om det är 64 till 250 kHz, och så vidare. Kom ihåg att det kommer att finnas en timerräknartillståndsjämförare för att jämföra värdet på räknaren och förskalaren tills de är lika och sedan utföra en åtgärd. Så, avbrottsfrekvens ges av formeln:
Avbrottshastighet (Hz) = Arduino / Prescaler klockfrekvens (komparatorregistervärde + 1)
Lyckligtvis får vi inte ändra poster av Arduino Timers, eftersom det kommer att tas om hand av biblioteken som vi använder i koden. Men om de inte används bör de konfigureras.
Exempel i Arduino IDE
För att förstå allt detta lite bättre visar jag här två skisskoder för Arduino IDE som du kan få uppleva användningen av timers med. Den första är kod som blinkar en lysdiod ansluten till Arduino pin 8 varje sekund:
#define ledPin 8 void setup() { pinMode(ledPin, OUTPUT); // Configurar Timer1 TCCR1A = 0; //Registro control A a 0, pines OC1A y OC1B deshabilitados TCCR1B = 0; //Limpia el registrador TCCR1B |= (1<<CS10)|(1 << CS12); //Configura prescaler a 1024: CS12 = 1 y CS10 = 1 TCNT1 = 0xC2F8; //Iniciar timer para desbordamiento a 1 segundo //65536-(16MHz/1024/1Hz - 1) = 49912 = 0xC2F8 en hexadecimal TIMSK1 |= (1 << TOIE1); //Habilitar interrupción para Timer1 } void loop() { } ISR(TIMER1_OVF_vect) //Interrupción del TIMER1 { TCNT1 = 0xC2F7; // Reniciar Timer1 digitalWrite(ledPin, digitalRead(ledPin) ^ 1); //Invierte el estado del LED }
Programmera blinkning eller blinkning av lysdioden, som i föregående fall varje sekund, men denna gång med CTC dvs jämförelse:
#define ledPin 8 void setup() { pinMode(ledPin, OUTPUT); // Configuración Timer1 TCCR1A = 0; //Registro de control A a 0 TCCR1B = 0; //Limpiar registro TCNT1 = 0; //Inicializar el temporizador OCR1A = 0x3D08; //Carga el valor del registro de comparación: 16MHz/1024/1Hz -1 = 15624 = 0X3D08 TCCR1B |= (1 << WGM12)|(1<<CS10)|(1 << CS12); //Modo CTC, prescaler de 1024: CS12 = 1 y CS10 = 1 TIMSK1 |= (1 << OCIE1A); //Habilita interrupción por igualdad de comparación } void loop() { } ISR(TIMER1_COMPA_vect) //Interrupción por igualdad de comparación en TIMER1 { digitalWrite(ledPin, digitalRead(ledPin) ^ 1); //Invierte el estado del LED }köp en tallrik Arduino UNO Rev 3