Estoy tratando de crear una interrupción de retardo de tiempo con Arduino. Me gustaría usar la función interrupts(), porque es una interrupción interna.
Ejemplo: Digamos que me gustaría hacer que una luz parpadee y se apague, con solo el tiempo de la interrupción.
Hay un código de muestra, pero usa interrupciones externas (attachInterrupt()). Me gustaría seguir usando las interrupciones internas.
El blog de Noah Stahl tiene un ejemplo de parpadeo de un LED con Timer2 . Con eso y la hoja de datos, debería poder adaptarlo a cualquier interrupción que desee usar, es decir, la interrupción cuya función normal puede darse el lujo de renunciar o está dispuesto a modificar. Timer2 se usa generalmente para algunas funciones PWM.
Su ejemplo cita el ATmega2560; Puedo confirmar que también funciona con un ATmega328p. Busque en su sitio más ejemplos útiles de interrupción de Arduino.
Editar:
Aquí está mi versión ligeramente editada, principalmente en los comentarios, del código de Noah. Llame a Timer2init() desde la función de configuración() de Arduino después de inicializar cualquier estructura de datos o hardware relacionado, porque el tiempo y la interrupción comenzarán una vez que lo haga.
F/ex, lo usé para multiplexar una pantalla de 7 segmentos de 3 dígitos, 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 ocupa de crear un código de entrada y salida de interrupción para una 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 de código para restablecer el temporizador para la próxima interrupción.
Tal como está escrito, esto debería caer en un boceto .pde o .ino (o un archivo .cpp, si usa eclipse, f/ex). El boceto debe #definir LEDPIN y setup() 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
};
La función attachInterrupt() en realidad está adjuntando una interrupción a un cambio de estado externo en un pin, no tiene otras opciones.
En la misma página , las opciones de modo se enumeran como:
El modo define cuándo debe activarse la interrupción. Cuatro constantes están predefinidas como valores válidos:
- BAJO para activar la interrupción siempre que el pin esté bajo,
- CAMBIAR para activar la interrupción cada vez que el pin cambie de valor
- RISING para disparar cuando el pin va de bajo a alto,
- FALLING para cuando el pin va de mayor a menor.
Lamento ser el portador de malas noticias, esa es una de las primeras cosas que busqué también.
Este artículo sobre PWM aclarará muchas de sus dudas sobre el uso de temporizadores Arduino. Hay dos temporizadores de 8 bits y un temporizador de 16 bits en Arduino. No hay una API de alto nivel para conectar la función ISR directamente a los temporizadores, que se envía con el SDK de Arduino (es decir, como una biblioteca estándar), sino un método de nivel algo más bajo para configurar registros de funciones especiales y aritmética de bits. operaciones sobre ellos. Sin embargo, hay una biblioteca aportada por el usuario llamada Timer one .
Arduino está usando los tres temporizadores en ATMega328. Timer1
(16 bits) se usa para funciones como delay()
y millis()
para la salida PWM en los pines 5 y 6. Los otros dos temporizadores Timer0
se Timer2
usan para la salida PWM en los pines 3, 9, 10, 11.
Entonces, no hay una función 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 probarlo, así que es posible que haya cometido un error. En ese caso, consulte la 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 de 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!
Timer0
y Timer2
son de 8 bits y solo Timer1
son de 16 bits.
clabacchio
Seth arquero marrón