¿Cómo creo una interrupción de temporizador con Arduino?

9

Estoy intentando crear una interrupción de retraso de tiempo con Arduino. Me gustaría usar la función interrupts (), porque es una interrupción interna.

Ejemplo: Digamos, me gustaría hacer que la luz parpadee de forma intermitente, solo con el tiempo de la interrupción.

Hay un código de ejemplo, pero usa interrupciones externas (attachInterrupt ()). Me gustaría seguir utilizando las interrupciones internas.

    
pregunta Aleatory

4 respuestas

10
El blog de

Noah Stahl tiene un ejemplo de parpadeando un LED con Timer2 . Con eso y la hoja de datos, debería poder adaptarlo a la interrupción que quiera usar, es decir, la interrupción cuya función normal puede abandonar o está dispuesto a modificar. Timer2 se usa generalmente para algunas funciones PWM.

Su ejemplo cita el ATmega2560; Puedo confirmar que funciona con un ATmega328p también. Busque en su sitio ejemplos de interrupción Arduino más útiles.

Editar:

Aquí está mi versión ligeramente editada, principalmente en los comentarios, del código de Noah. Llame a Timer2init () desde la función setup () de Arduino después de inicializar cualquier estructura de datos o hardware relacionado, porque la sincronización (y la interrupción) comenzarán una vez que lo haga.

F / ex, lo usé para multiplexar una pantalla de 3 dígitos de 7 segmentos, así que antes de inicializar el temporizador, inicialicé los registros de E / S de la pantalla y borré los datos de la pantalla en el lugar donde el ISR los buscará .

Hay una tabla en los comentarios de algunos datos de tiempo útiles de la hoja de datos y mis propios cálculos como referencia para configurar otro esquema de tiempo.

La macro ISR () se encarga de crear el código de entrada y salida de interrupción para un ISR en lugar de la entrada y salida de una función normal, y de vincularlo con el vector de interrupción adecuado. El resto de esa función es 1) el código que se ejecutará en cada interrupción y 2) el código para restablecer el temporizador para la siguiente interrupción.

Tal como está escrito, esto debería incluirse en un boceto .pde o .ino (o un archivo .cpp, si usa eclipse, f / ex). El bosquejo debe #definar LEDPIN, y la configuración () debe llamar a Timer2init (). La función de bucle puede estar vacía o no; el LED debería comenzar a parpadear en la descarga (bueno, literalmente, después de llamar a Timer2init ()).

/*
 * From sample interrupt code published by Noah Stahl on his blog, at:
 * http://arduinomega.blogspot.com/p/arduino-code.html
 * 
 */


/*** FUNC

Name:           Timer2init

Function:       Init timer 2 to interrupt periodically. Call this from 
                the Arduino setup() function.

Description:    The pre-scaler and the timer count divide the timer-counter
                clock frequency to give a timer overflow interrupt rate:

                Interrupt rate =  16MHz / (prescaler * (255 - TCNT2))

        TCCR2B[b2:0]   Prescaler    Freq [KHz], Period [usec] after prescale
          0x0            (TC stopped)     0         0
          0x1                1        16000.        0.0625
          0x2                8         2000.        0.500
          0x3               32          500.        2.000
          0x4               64          250.        4.000
          0x5              128          125.        8.000
          0x6              256           62.5      16.000
          0x7             1024           15.625    64.000


Parameters: void

Returns:    void

FUNC ***/

void Timer2init() {

    // Setup Timer2 overflow to fire every 8ms (125Hz)
    //   period [sec] = (1 / f_clock [sec]) * prescale * (255-count)
    //                  (1/16000000)  * 1024 * (255-130) = .008 sec


    TCCR2B = 0x00;        // Disable Timer2 while we set it up

    TCNT2  = 130;         // Reset Timer Count  (255-130) = execute ev 125-th T/C clock
    TIFR2  = 0x00;        // Timer2 INT Flag Reg: Clear Timer Overflow Flag
    TIMSK2 = 0x01;        // Timer2 INT Reg: Timer2 Overflow Interrupt Enable
    TCCR2A = 0x00;        // Timer2 Control Reg A: Wave Gen Mode normal
    TCCR2B = 0x07;        // Timer2 Control Reg B: Timer Prescaler set to 1024
}



/*** FUNC

Name:       Timer2 ISR

Function:   Handles the Timer2-overflow interrupt

Description:    Maintains the 7-segment display

Parameters: void

Returns:    void

FUNC ***/

ISR(TIMER2_OVF_vect) {
    static unsigned int led_state = 0; // LED state

    led_state = !led_state;         // toggles the LED state
    digitalWrite(TOGGLE_PIN, led_state);

    TCNT2 = 130;     // reset timer ct to 130 out of 255
    TIFR2 = 0x00;    // timer2 int flag reg: clear timer overflow flag
};
    
respondido por el JRobert
5

La función attachInterrupt () en realidad está adjuntando una interrupción a un cambio de estado externo en un pin, no tiene Cualquier otra opción.

En la misma página las opciones de modo se enumeran como:

  El modo

define cuándo debe activarse la interrupción. Cuatro contstants   están predefinidos como valores válidos:

     
  • LOW para desencadenar la interrupción siempre que el pin esté bajo,
  •   
  • CAMBIAR para desencadenar la interrupción siempre que el pin cambie de valor
  •   
  • LEVANTANDO para activarse cuando el pin pasa de bajo a alto,
  •   
  • FALLING para cuando el pin pase de alto a bajo.
  •   

Lamento ser el portador de malas noticias, esa es una de las primeras cosas que busqué también.

    
respondido por el Kortuk
2

Este artículo sobre PWM despejará muchas dudas con respecto al uso de los temporizadores Arduino. Hay dos temporizadores de 8 bits y un temporizador de 16 bits en Arduino. No hay una API de alto nivel para enlazar la función ISR directamente a los temporizadores, que se incluye con el SDK de Arduino (es decir, como una biblioteca estándar), sino un método de configuración de registros de funciones especiales y aritmética de bits de nivel algo inferior. operaciones en ellos. Sin embargo, hay una biblioteca contribuida por el usuario llamada Timer one .

    
respondido por el icarus74
1

Arduino está utilizando los tres temporizadores en ATMega328. Timer1 (16 bits) se usa para funciones como delay() y millis() y para la salida PWM en los pines 5 y 6. Los otros dos temporizadores - Timer0 y Timer2 se usan para la salida PWM en los pines 3, 9, 10, 11.

Entonces, no hay una función de Arduino para la interrupción del temporizador. Pero, hay una manera. Puede usar este código para habilitar la interrupción del temporizador en Timer2 :

ISR(TIMER2_OVF_vect) {
  // Interrupt routine.
}

void setup() {
  // Enable Timer2 interrupt.
  TIMSK2 = (0<<OCIE2A) | (1<<TOIE2);
}

void loop() {
  // Your main loop.
}

Escribí este código sin probar, por lo que es posible que haya cometido un error. En ese caso, consulte hoja de datos, p.156 .

Si desea cambiar la frecuencia del temporizador (prescaler), simplemente cambie el registro TCCR2A . Para obtener más información, consulte la hoja de datos en la página 153. Pero si cambia la frecuencia del temporizador, también cambia la frecuencia de la señal PWM en dos pines de salida.

    
respondido por el vasco

Lea otras preguntas en las etiquetas