Arduino Timer: lek med timing i dina projekt

timer Arduino UNO

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?

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.

Como Arduino UNO Den har ett MCU-chip som fungerar på 16 Mhz, 16.000.000 16 XNUMX kan exekveras varje sekund. Instruktionerna behöver X cykler för att exekveras, inte alla exekveras i samma klockcykler, till exempel, XNUMX-bitars behöver fler cykler i denna AVR-arkitektur.

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

Arduino UNO millis funktioner

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?

timers, timers

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:

+1 beror på att räknarregistret är indexerat till 0, d.v.s. det börjar inte räkna vid 1, utan vid 0.

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

Arduino IDE, datatyper, programmering

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
}

Mer om Arduino-programmering

köp en tallrik Arduino UNO Rev 3

Bli först att kommentera

Lämna din kommentar

Din e-postadress kommer inte att publiceras. Obligatoriska fält är markerade med *

*

*

  1. Ansvarig för uppgifterna: Miguel Ángel Gatón
  2. Syftet med uppgifterna: Kontrollera skräppost, kommentarhantering.
  3. Legitimering: Ditt samtycke
  4. Kommunikation av uppgifterna: Uppgifterna kommer inte att kommuniceras till tredje part förutom enligt laglig skyldighet.
  5. Datalagring: databas värd för Occentus Networks (EU)
  6. Rättigheter: När som helst kan du begränsa, återställa och radera din information.