Timer d'Arduino: juga amb la temporització als teus projectes

Timer Arduino UNO

Fa un temps publiquem més informació sobre la funció millis() de Arduino, ara ens endinsarem més a fons al Timer d'Arduino, per començar a treballar amb aquesta característica per a la característica, comprendre com gestiona el temps aquesta placa amb MCU, a més d'altres funcions més enllà de millis().

Què és el Timer d'Arduino?

timer d'Arduino

El Timer d'Arduino, o temporitzador, és una funció implementada per maquinari (al microcontrolador, amb ajuda del vidre de quars que genera els polsos de rellotge i que marca el «ritme», sense necessitat de maquinari extern ni CIs 555) que permet controlar esdeveniments temporals gràcies a uns rellotges interns. Per exemple, fer que una tasca es faci a intervals, fer mesuraments de temps precisos, etc., de forma independent del codi de l'esquetx.

Com que Arduino UNO té un xip MCU que treballa a 16 Mhz, se'n podrien executar 16.000.000 cada segon. Les instruccions necessiten X cicles per executar-se, no totes s'executen en els mateixos cicles de rellotge, per exemple, les de 16 bits necessiten més cicles en aquesta arquitectura AVR.

Imagina que uses la funció delay(), això bloquejarà l'execució a la MCU d'Arduino fins que transcorri el temps especificat i després continuarà amb el programa, però amb el timer no es bloquejarà. S'estarà temporitzant alhora que la MCU segueix executant altres instruccions de manera simultània. Aquest és el gran avantatge.

El timer està relacionat amb les interrupcions d'Arduino, ja que seran executats a través d'elles per atendre alguna tasca específica. En altres paraules, el Timer d'Arduino és una funció que es dispara en un temps determinat, executant una funció d'interrupció. Per això també és important conèixer aquestes interrupcions.

maneres

El Timer d'Arduino té 2 modes de funcionament, podent-ho utilitzar en:

  • Senyal PWM: es pot controlar els pins d'Arduino (~).
  • CTC (Clear timer on compare match): comptabilitza el temps dins d'un comptador i quan arriba al valor especificat en un registre dels timers, s'executa la interrupció.

Quants temporitzadors té? Tipus de Timers

Arduino UNO funcions Millis

Existeixen 3 temporitzadors a les plaques Arduino UNO, encara que hi pot haver més en altres plaques superiors:

  • Temporitzador 0: de 8-bit, poden comptar des de 0 a 255 (256 valors possibles). Usat per funcions com delay(), millis(), i micros(). No se'n recomana la modificació per no alterar els programes.
  • Temporitzador 1: igual al Timer 0. Usat per la biblioteca Servo en UNO (Timer 5 per a MEGA).
  • Temporitzador 2: de 16 bits, podent anar des de 0 a 65.525 (65.536 valors possibles). Usat per a la funció tone(), si no es fa servir, es pot utilitzar de forma lliure per a la teva aplicació.
  • Timer 3, 4, 5 (només a Arduino MEGA): tots de 16 bits.

Com funciona el Timer d'Arduino?

Timers, temporitzadors

Per poder treballar amb un Timer d'Arduino, és vital conèixer com funciona tot això a nivell electrònic al MCU d'aquesta placa de desenvolupament:

  • Freqüència de rellotge: és la quantitat de cicles per segon que és capaç de desenvolupar, en el cas d'Arduino són 16 Mhz, o el que és el mateix, el senyal de rellotge oscil·la 16.000.000 vegades en un segon (cicles).
  • Període: es representa amb la T, i es mesura en segons, i és la inversa dels cicles. Per exemple, T=1/C, cosa que deixaria com a resultat 1/16000000 = 0.0000000625, el temps que trigaria a completar-se cada cicle. I la freqüència és la inversa del període, per la qual cosa f = 1/T.
  • cicle: és cadascuna de les repeticions del senyal que es donen per unitat de temps. A Arduino serien 16M en un segon. O el que és el mateix, en aquest cas, quan hi passen 16 milions de cicles ha passat un segon. Per tant, es pot dir que un cicle triga 625 ns.
  • Flanc d'un senyal: els senyals de rellotge són quadrats, i els flancs poden ser de pujada o de baixada. Un flanc és la línia recta del senyal quan canvia de:
    • 0 (baix) a 1 (alt): flanc de pujada.
    • 1 (alt) a 0 (baix): flanc de baixada.

Els flancs són importants perquè els temporitzadors d'Arduino mesuren els cicles a partir dels flancs del senyal. Així el comptador es va incrementant amb cada cicle i quan arriba al valor del registre, s'executa la interrupció.

Per tant, una vegada se sap això, si es té 16 Mhz a la MCU d'Arduino, i es fa servir un Timer de 8-bit, es pot dir que es produiran les interrupcions cada 16 μs (256/16000000) o 4 ms per als de 16-bit (65536/16000000). Per tant, si configureu el registre del comptador de 16 bits al màxim, amb el valor 65535, llavors es produirà la interrupció als 4 ms per executar la tasca que sigui.

Quan el comptador arriba al valor màxim possible, tornarà a 0 novament. És a dir, es produeix un desbordament i tornarà a comptar des del començament.

Per controlar la velocitat d'increment del temporitzador també es pot fer servir un prescaler, que pren valors 1, 8, 64, 256 i 1024 i altera la temporització d'aquesta manera:

Velocitat del temporitzador (Hz) = Freqüència de rellotge d'Arduino / Prescaler

Si és 1 el prescaler el controlador s'incrementarà a 16 Mhz, si és 8 a 2 Mhz, si és 64 a 250 kHz, i així successivament. Recorda que hi haurà un comparador d'estat del comptador del timer per anar comparant el valor del comptador i el preescalador fins que són iguals i llavors executa una acció. Per tant, la freqüència d'interrupció ve donada per la fórmula:

+1 és perquè el registre del comptador està indexat a 0, és a dir, no comença a comptar a 1, sinó a 0.

Velocitat d'interrupció (Hz) = Freqüència de rellotge d'Arduino / Prescaler · (valor del registre de comparador + 1)

Afortunadament, no hem de modificar els registres dels Timers d'Arduino, ja que se n'ocuparà les biblioteques que fem servir al codi. Però si no es fan servir, sí que s'haurien de configurar.

Exemples a Arduino IDE

Arduino IDE, tipus de dades, programació

Per poder comprendre tot això una mica millor, aquí mostro dos codis de sketch per a Arduino IDE amb què es pot arribar a experimentar l'ús dels timers. El primer és un codi que farà titil·lar un LED connectat al pin 8 d'Arduino cada segon:

#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
}

Programar el titile o parpelleig del LED, com en l'anterior cas a cada segon, però aquesta vegada usant CTC, és a dir, comparació:

#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
}

Més sobre la programació d'Arduino

Comprar una placa Arduino UNO Rev3

Sigues el primer a comentar

Deixa el teu comentari

La seva adreça de correu electrònic no es publicarà. Els camps obligatoris estan marcats amb *

*

*

  1. Responsable de les dades: Miguel Ángel Gatón
  2. Finalitat de les dades: Controlar l'SPAM, gestió de comentaris.
  3. Legitimació: El teu consentiment
  4. Comunicació de les dades: No es comunicaran les dades a tercers excepte per obligació legal.
  5. Emmagatzematge de les dades: Base de dades allotjada en Occentus Networks (UE)
  6. Drets: En qualsevol moment pots limitar, recuperar i esborrar la teva informació.