fbpixel
Etiquetas: , ,
4.5
(2)

El uso de temporizadores en Arduino es un método avanzado para ejecutar código sin perturbar el resto del programa. Permiten activar funciones en intervalos de tiempo específicos. Los temporizadores se utilizan en muchas bibliotecas de forma totalmente transparente para el usuario (millis(), Servo.h, PWM, etc.)

En algunos casos, es posible utilizar bibliotecas que configuran temporizadores que simplificarán el uso.

Material

  • Arduino UNO
  • Cable USB A/ USB B

Descripción

Los temporizadores son registros del microprocesador que se incrementan según los impulsos del reloj o los impulsos externos. Es posible configurarlos para modificar su comportamiento.

El microprocesador Arduino UNO (ATmega328P) tiene 3 temporizadores:

  • timer0 (8 bits) cuenta de 0 a 256 y controla el PWM de los pines 5 y 6. También es utilizado por las funciones delay(), millis() y micros().
  • timer1 (16 bits) cuenta de 0 a 65535 y se utiliza para el control PWM de los pines 9 y 10. También es utilizado por la biblioteca Servo.h
  • timer2 (8 bits) que es utilizado por la función Tone() y la generación de PWM en los pines 3 y 11.

Configuración del temporizador

La parte más complicada del uso del sensor es su configuración. Un temporizador se configura mediante su registro de control. Aquí está el recordatorio de los registros.

Timer 0Timer 1Timer 2Rôle
TCNT0TCNT1LTCNT2Timer (bit 0 à 7)
TCNT1HTimer (bit 8 à 15)
TCCR0ATCCR1ATCCR2ARegistre de contrôle
TCCR0BTCCR1BTCCR2BRegistre de contrôle
TCCR1CRegistre de contrôle
OCR0AOCR1ALOCR2AOutput Compare (bit 0 à 7)
OCR1AHOutput Compare (bit 8 à 15)
OCR0BOCR1BLOCR2BOutput Compare (bit 0 à 7)
OCR1BHOutput Compare (bit 8 à 15)
ICR1LInput Capture (bit 0 à 7)
ICR1HInput Capture (bit 8 à 15)
TIMSK0TIMSK1TIMSK2Interrupt Mask
TIFR0TIFR1TIFR2Interrupt Flag

El registro TCNTx contiene el valor del temporizador/contador, los registros TCCRxA y TCCRxB son los registros de control. OCRxA y OCRxB contienen los valores de los registros a comparar. TIMSKx contiene la máscara de interrupción y TIFRx contiene las banderas de habilitación.

Código que utiliza timer2

Para este ejemplo, utilizamos el temporizador2 que está codificado en 8bits (256). Así que tenemos que introducir un contador adicional.

unsigned long elapsedTime, previousTime;

void onTimer() {
  static boolean state = HIGH;
  elapsedTime=millis()-previousTime;
  Serial.print(F("Set LED 13 : "));
  if(state){
    Serial.print(F("ON"));
  }else{
    Serial.print(F("OFF"));
  }
  Serial.print(F(" - "));Serial.print(elapsedTime);Serial.println(F("ms"));
  digitalWrite(13, state);
  state = !state;

  previousTime=millis();
}

void setup(){
  Serial.begin(9600);
  pinMode(13, OUTPUT);

  cli();           // disable all interrupts
  TCCR2A = (1<<WGM21)|(0<<WGM20); // Mode CTC
  TIMSK2 = (1<<OCIE2A); // Local interruption OCIE2A
  TCCR2B = (0<<WGM22)|(1<<CS22)|(1<<CS21); // Frequency 16Mhz/ 256 = 62500
  OCR2A = 250;       //250*125 = 31250 = 16Mhz/256/2
  sei();             // enable all interrupts

}
ISR(TIMER2_COMPA_vect){         // timer compare interrupt service routine
  static int counter=0;
  if (++counter >= 125) { // 125 * 4 ms = 500 ms
    counter = 0;
    onTimer();
  }
}

void loop(){
}

Código que utiliza el temporizador1

Para este ejemplo, utilizaremos el temporizador1

unsigned long elapsedTime, previousTime;

void onTimer() {
  static boolean state = HIGH;
  elapsedTime=millis()-previousTime;
  Serial.print(F("Set LED 13 : "));
  if(state){
    Serial.print(F("ON"));
  }else{
    Serial.print(F("OFF"));
  }
  Serial.print(F(" - "));Serial.print(elapsedTime);Serial.println(F("ms"));
  digitalWrite(13, state);
  state = !state;

  previousTime=millis();
}

void setup(){
  Serial.begin(9600);
  pinMode(13, OUTPUT);

  cli();           // disable all interrupts
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A = 31250;            // compare match register 16MHz/256/2 = 31250
  TCCR1B = (1 << WGM12);   // CTC mode
  TCCR1B = (1 << CS12);    // // Frequency 16Mhz/ 256 = 62500 
  TIMSK1 = (1 << OCIE1A);  // Local interruption OCIE1A
  sei();             // enable all interrupts
}

ISR(TIMER1_COMPA_vect){          // timer compare interrupt service routine
  onTimer();
}

void loop(){
}

N.B.: Hemos añadido una medida de tiempo transcurrido con fines ilustrativos, pero hay que tener cuidado al utilizar funciones basadas en interrupciones en funciones invocables por interrupción. Puede haber interferencias.

Resultado

Una vez iniciado el programa, el LED de la placa se enciende y se apaga cada 500ms

Fuentes

Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie

¿De cuánta utilidad te ha parecido este contenido?

¡Haz clic en una estrella para puntuarlo!

Promedio de puntuación 4.5 / 5. Recuento de votos: 2

Hasta ahora, ¡no hay votos!. Sé el primero en puntuar este contenido.

Ya que has encontrado útil este contenido...

¡Sígueme en los medios sociales!

¡Siento que este contenido no te haya sido útil!

¡Déjame mejorar este contenido!

Dime, ¿cómo puedo mejorar este contenido?