Interrupciones del temporizador Arduino

Las interrupciones del temporizador le permiten realizar una tarea a intervalos de tiempo muy específicos, independientemente de lo que esté sucediendo en su código. En este instructable explicaré cómo configurar y ejecutar una interrupción en Clear Timer en Comparar partido o modo CTC. Vaya directamente al paso 2 si está buscando un código de muestra.

Normalmente, cuando escribe un boceto de Arduino, Arduino ejecuta todos los comandos encapsulados en la función loop () {} en el orden en que se escriben, sin embargo, es difícil cronometrar eventos en el loop (). Algunos comandos tardan más que otros en ejecutarse, algunos dependen de sentencias condicionales (if, while ...) y algunas funciones de la biblioteca Arduino (como digitalWrite o analogRead) están formadas por muchos comandos. Las interrupciones del temporizador Arduino le permiten pausar momentáneamente la secuencia normal de eventos que tienen lugar en la función loop () a intervalos de tiempo precisos, mientras ejecuta un conjunto separado de comandos. Una vez que se realizan estos comandos, el Arduino retoma nuevamente donde estaba en el bucle ().

Las interrupciones son útiles para:

Medición de una señal entrante a intervalos igualmente espaciados (frecuencia de muestreo constante)

Calcular el tiempo entre dos eventos

Enviar una señal de una frecuencia específica

Comprobación periódica de datos en serie entrantes

mucho más...

Hay algunas maneras de hacer interrupciones, por ahora me enfocaré en el tipo que considero más útil / flexible, llamado Clear Timer en Comparar partido o Modo CTC. Además, en este instructable escribiré específicamente sobre los temporizadores para el Arduino Uno (y cualquier otro Arduino con ATMEL 328/168 ... Lilypad, Duemilanove, Diecimila, Nano ...). Las ideas principales presentadas aquí se aplican también a las placas Mega y anteriores, pero la configuración es un poco diferente y la tabla a continuación es específica para ATMEL 328/168.

Paso 1: preescaladores y el registro de comparación de coincidencias

El Uno tiene tres temporizadores llamados timer0, timer1 y timer2. Cada uno de los temporizadores tiene un contador que se incrementa en cada tic del reloj del temporizador. Las interrupciones del temporizador CTC se activan cuando el contador alcanza un valor específico, almacenado en el registro de comparación de coincidencias. Una vez que un contador de temporizador alcanza este valor, se borrará (restablecerá a cero) en el siguiente tic del reloj del temporizador, luego continuará contando hasta el valor de comparación de nuevo. Al elegir el valor de comparación de comparación y establecer la velocidad a la que el temporizador incrementa el contador, puede controlar la frecuencia de las interrupciones del temporizador.

El primer parámetro que analizaré es la velocidad a la que el temporizador incrementa el contador. El reloj Arduino funciona a 16MHz, esta es la velocidad más rápida que los temporizadores pueden incrementar sus contadores. A 16MHz, cada tic del contador representa 1 / 16, 000, 000 de segundo (~ 63ns), por lo que un contador tardará 10 / 16, 000, 000 segundos en alcanzar un valor de 9 (los contadores son 0 indexados), y 100 / 16, 000, 000 segundos en alcanzar un valor de 99.

En muchas situaciones, encontrará que ajustar la velocidad del contador a 16MHz es demasiado rápido. Timer0 y timer2 son temporizadores de 8 bits, lo que significa que pueden almacenar un valor de contador máximo de 255. Timer1 es un temporizador de 16 bits, lo que significa que puede almacenar un valor de contador máximo de 65535. Una vez que un contador alcanza su máximo, volverá a cero. (Esto se llama desbordamiento). Esto significa que a 16MHz, incluso si configuramos el registro de comparación de comparación con el valor máximo del contador, se producirán interrupciones cada 256 / 16, 000, 000 segundos (~ 16us) para los contadores de 8 bits, y cada 65, 536 / 16, 000, 000 (~ 4 ms) segundos para el Contador de 16 bits. Claramente, esto no es muy útil si solo desea interrumpir una vez por segundo.

En su lugar, puede controlar la velocidad del incremento del contador del temporizador utilizando algo llamado preescalador. Un preescalador dicta la velocidad de su temporizador de acuerdo con la siguiente ecuación:

(velocidad del temporizador (Hz)) = (velocidad del reloj Arduino (16MHz)) / preescaler

Entonces, un preescalador 1 incrementará el contador a 16MHz, un preescalador 8 lo incrementará a 2MHz, un preescalador 64 = 250kHz, y así sucesivamente. Como se indica en las tablas anteriores, el preescalador puede ser igual a 1, 8, 64, 256 y 1024. (Explicaré el significado de CS12, CS11 y CS10 en el siguiente paso).

Ahora puede calcular la frecuencia de interrupción con la siguiente ecuación:

frecuencia de interrupción (Hz) = (velocidad de reloj Arduino 16, 000, 000Hz) / (preescaler * (comparar registro de coincidencias + 1))
el +1 está allí porque el registro de comparación de comparación está indexado a cero

Al reorganizar la ecuación anterior, puede resolver el valor de registro de comparación de comparación que le dará la frecuencia de interrupción deseada:

comparar registro de coincidencia = [16, 000, 000Hz / (preescalador * frecuencia de interrupción deseada)] - 1
recuerde que cuando usa los temporizadores 0 y 2, este número debe ser menor que 256 y menor que 65536 para el temporizador1

así que si quisieras una interrupción cada segundo (frecuencia de 1Hz):
comparar registro de coincidencias = [16, 000, 000 / (preescaler * 1)] -1
con un preescaler de 1024 obtienes:
comparar registro de coincidencias = [16, 000, 000 / (1024 * 1)] -1
= 15, 624
desde 256 <15, 624 <65, 536, debe usar el temporizador1 para esta interrupción.

Paso 2: estructurando interrupciones del temporizador


El código de configuración del temporizador se realiza dentro de la función setup () {} en un boceto de Arduino.

El código involucrado para configurar las interrupciones del temporizador es un poco desalentador de ver, pero en realidad no es tan difícil. Prácticamente solo copie el mismo fragmento de código principal y cambio el preescalador y comparo el registro de coincidencias para establecer la frecuencia de interrupción correcta.

La estructura principal de la configuración de interrupción se ve así:
 ////www.instructables.com/id/Arduino-Timer-Interrupts/ void setup () cli (); // detener interrupciones // establecer temporizador0 interrupción a 2 kHz TCCR0A = 0; // establecer todo el registro TCCR0A a 0 TCCR0B = 0; // lo mismo para TCCR0B TCNT0 = 0; // inicializa el valor del contador a 0 // establece el registro de comparación para incrementos de 2khz OCR0A = 124; // = (16 * 10 ^ 6) / (2000 * 64) - 1 (debe ser <256) // activar el modo CTC TCCR0A // finalizar la configuración 
Observe cómo cambia el valor de OCR # A (el valor de comparación de comparación) para cada una de estas configuraciones de temporizador. Como se explicó en el último paso, esto se calculó de acuerdo con la siguiente ecuación:

comparar registro de coincidencia = [16, 000, 000Hz / (preescalador * frecuencia de interrupción deseada)] - 1
recuerde que cuando usa los temporizadores 0 y 2, este número debe ser menor que 256 y menor que 65536 para el temporizador1

Observe también cómo las configuraciones entre los tres temporizadores difieren ligeramente en la línea que activa el modo CTC:
TCCR0A | = (1 << WGM01); // para timer0
TCCR1B | = (1 << WGM12); // para timer1
TCCR2A | = (1 << WGM21); // para timer2
Esto se deduce directamente de la hoja de datos del ATMEL 328/168.

Finalmente, observe cómo la configuración para los preescaladores sigue las tablas en el último paso (la tabla para el temporizador 0 se repite anteriormente),
TCCR2B | = (1 << CS22); // Establecer el bit CS # 2 para 64 preescalador para el temporizador 2
TCCR1B | = (1 << CS11); // Establecer el bit CS # 1 para 8 preescaler para el temporizador 1
TCCR0B | = (1 << CS02) | (1 << CS00); // Establezca los bits CS # 2 y CS # 0 para 1024 preescaler para el temporizador 0

Observe en el último paso que hay diferentes opciones de preescalado para los diferentes temporizadores. Por ejemplo, timer2 no tiene la opción de 1024 preescaler.

Los comandos que desea ejecutar durante estas interrupciones del temporizador se encuentran en el boceto de Arduino encapsulado en lo siguiente:
ISR (TIMER0_COMPA_vect) {// cambia el 0 a 1 para el temporizador1 y 2 para el temporizador2
// interrumpir comandos aquí
}
Este bit de código debe ubicarse fuera de las funciones setup () y loop (). Además, trate de mantener la rutina de interrupción lo más corta posible, especialmente si está interrumpiendo a una frecuencia alta. Incluso puede valer la pena abordar los puertos / pines del chip ATMEL directamente en lugar de usar las funciones digitalWrite () y digitalRead (). Puedes encontrar más información sobre eso aquí.

Ejemplo: el siguiente boceto configura y ejecuta 3 interrupciones de temporizador:

 // interrupciones del temporizador // por Amanda Ghassaei // junio de 2012 ////www.instructables.com/id/Arduino-Timer-Interrupts/ / * * Este programa es software libre; puede redistribuirlo y / o modificarlo * bajo los términos de la Licencia Pública General GNU publicada por * la Free Software Foundation; ya sea la versión 3 de la Licencia, o * (a su elección) cualquier versión posterior. * * / // configuración del temporizador para timer0, timer1 y timer2. // Para arduino uno o cualquier placa con ATMEL 328/168 .. diecimila, duemilanove, lilypad, nano, mini ... // este código habilitará las tres interrupciones del temporizador arduino. // timer0 interrumpirá a 2kHz // timer1 interrumpirá a 1Hz // timer2 interrumpirá a 8kHz // variables de almacenamiento boolean toggle0 = 0; alternar booleano1 = 0; alternar booleano2 = 0; void setup () // establece los pines como salidas pinMode (8, OUTPUT); pinMode (9, SALIDA); pinMode (13, SALIDA); cli (); // detener interrupciones // establecer temporizador0 interrupción a 2 kHz TCCR0A = 0; // establecer todo el registro TCCR2A en 0 TCCR0B = 0; // lo mismo para TCCR2B TCNT0 = 0; // inicializar el valor del contador en 0 // establecer compare el registro de coincidencias para incrementos de 2 kHz OCR0A = 124; // = (16 * 10 ^ 6) / (2000 * 64) - 1 (debe ser <256) // active el modo CTC TCCR0A // finalice la configuración ISR (TIMER0_COMPA_vect) { // timer0 interrupt 2kHz alterna el pin 8 // genera una onda de pulso de frecuencia 2kHz / 2 = 1kHz (toma dos ciclos para la onda completa: alternar alto y alternar bajo) if (alternar0) {digitalWrite (8, HIGH); alternar0 = 0; } else {digitalWrite (8, BAJO); alternar0 = 1; }} ISR (TIMER1_COMPA_vect) {// timer1 interrupt 1Hz alterna el pin 13 (LED) // genera una onda de pulso de frecuencia 1Hz / 2 = 0.5kHz (toma dos ciclos para la onda completa, alternar alto y alternar bajo) if (alternar1) { digitalWrite (13, ALTO); alternar1 = 0; } else {digitalWrite (13, BAJO); alternar1 = 1; }} ISR (TIMER2_COMPA_vect) {// timer1 interrupt 8kHz alterna el pin 9 // genera una onda de pulso de frecuencia 8kHz / 2 = 4kHz (toma dos ciclos para la onda completa, alternar alto y alternar bajo) if (alternar2) {digitalWrite (9, ALTO); alternar2 = 0; } else {digitalWrite (9, BAJO); alternar2 = 1; }} void loop () {// haz otras cosas aquí} 

Las imágenes de arriba muestran las salidas de estas interrupciones del temporizador. La figura 1 muestra una onda cuadrada que oscila entre 0 y 5 V a 1 kHz (interrupción del temporizador 0), la figura 2 muestra el LED conectado al pin 13 que se enciende durante un segundo y luego se apaga durante un segundo (interrupción del temporizador 1), la figura 3 muestra una onda de pulso oscilante entre 0 y 5V a una frecuencia de 4khz (interrupción timer2).

Paso 3: Ejemplo 1: Velocímetro de bicicleta

En este ejemplo, hice un velocímetro de bicicleta con motor arduino. Funciona uniendo un imán a la rueda y midiendo la cantidad de tiempo que tarda en pasar por un interruptor magnético montado en el marco, el tiempo para una rotación completa de la rueda.

Configuré el temporizador 1 para interrumpir cada ms (frecuencia de 1kHz) para medir el interruptor magnético. Si el imán pasa por el interruptor, la señal del interruptor es alta y la variable "tiempo" se pone a cero. Si el imán no está cerca del interruptor, el "tiempo" se incrementa en 1. De esta manera, el "tiempo" en realidad es solo una medida de la cantidad de tiempo en milisegundos que ha pasado desde la última vez que el imán pasó por el interruptor magnético. Esta información se usa más adelante en el código para calcular las rpm y las mph de la bicicleta.

Aquí está el bit de código que configura el temporizador1 para interrupciones de 1 kHz

cli (); // detener interrupciones
// establece la interrupción del temporizador 1 a 1 kHz
TCCR1A = 0; // establece el registro TCCR1A completo en 0
TCCR1B = 0; // igual para TCCR1B
TCNT1 = 0; // inicializa el valor del contador a 0
// establece el conteo del temporizador para incrementos de 1khz
OCR1A = 1999; // = (16 * 10 ^ 6) / (1000 * 8) - 1
// tuvo que usar 16 bit timer1 para este bc 1999> 255, pero podría cambiar a los temporizadores 0 o 2 con un prescaler más grande
// activa el modo CTC
TCCR1B | = (1 << WGM12);
// Establecer bit CS11 para 8 preescaler
TCCR1B | = (1 << CS11);
// habilitar temporizador comparar interrupción
TIMSK1 | = (1 << OCIE1A);
sei (); // permitir interrupciones

Aquí está el código completo si quieres echar un vistazo:
 // velocímetro de bicicleta // por Amanda Ghassaei 2012 ////www.instructables.com/id/Arduino-Timer-Interrupts/ ////www.instructables.com/id/Arduino-Timer-Interrupts/ / * * This el programa es software libre; puede redistribuirlo y / o modificarlo * bajo los términos de la Licencia Pública General GNU publicada por * la Free Software Foundation; ya sea la versión 3 de la Licencia, o * (a su elección) cualquier versión posterior. * * / // ejemplos de cálculos // radio del neumático ~ 13.5 pulgadas // circunferencia = pi * 2 * r = ~ 85 pulgadas // velocidad máxima de 35 mph = ~ 616 pulgadas / segundo // max rps = ~ 7.25 #define reed A0 / / pin conectado al interruptor de lectura // variables de almacenamiento flotante radio = 13.5; // radio del neumático (en pulgadas) - CAMBIE ESTO PARA SU PROPIA BICICLETA int reedVal; tiempo largo = 0; // tiempo entre una rotación completa (en ms) flotación mph = 0.00; circunferencia de flotación; luz de fondo booleana; int maxReedCounter = 100; // tiempo min (en ms) de una rotación (para eliminar rebotes) int reedCounter; configuración vacía () {reedCounter = maxReedCounter; circunferencia = 2 * 3.14 * radio; pinMode (1, OUTPUT); // tx pinMode (2, OUTPUT); // interruptor de luz de fondo pinMode (reed, INPUT); // interruptor de redd checkBacklight (); Serial.write (12); // borrar // CONFIGURACIÓN DEL TEMPORIZADOR: la interrupción del temporizador permite mediciones temporizadas previas del interruptor de láminas // para obtener más información sobre la configuración de los temporizadores arduino, consulte //arduino.cc/playground/Code/Timer1 cli ( ); // detiene las interrupciones // establece la interrupción del temporizador 1 a 1 kHz TCCR1A = 0; // establece todo el registro TCCR1A en 0 TCCR1B = 0; // lo mismo para TCCR1B TCNT1 = 0; // inicializa el valor del contador en 0; // establece el conteo del temporizador para incrementos de 1 kHz OCR1A = 1999; // = (16 * 10 ^ 6) / (1000 * 8) - 1 // activa el modo CTC TCCR1B | = (1 << WGM12); // Establecer el bit CS11 para 8 preescaler TCCR1B | = (1 << CS11); // habilitar temporizador comparar interrupción TIMSK1 | = (1 <0) {// no permita que reedCounter se vuelva negativo reedCounter - = 1; // decrement reedCounter}}} else {// si el interruptor de láminas está abierto si (reedCounter> 0 ) {// no permita que reedCounter se vuelva negativo reedCounter - = 1; // disminuya reedCounter}} if (time> 2000) {mph = 0; // si no hay pulsos nuevos del interruptor de láminas todavía, ajuste mph a 0} else {time + = 1; // increment timer}} void displayMPH () {Serial.write (12); // clear Serial.write ("Speed ​​="); Serial.write (13); // comienza una nueva línea Serial.print (mph); Serial.write ("MPH"); //Serial.write("0.00 MPH "); } void loop () {// imprime mph una vez por segundo displayMPH (); retraso (1000); checkBacklight (); } 

Paso 4: Ejemplo 2: Comunicación en serie

Este proyecto es un botón con retroiluminación 4x4. El proyecto se conecta a mi computadora a través de USB, envía información sobre los botones a la computadora y recibe información sobre cómo encender los LED. Aquí hay un video:



Para este proyecto, utilicé las interrupciones del temporizador 2 para verificar periódicamente si había datos seriales entrantes, leerlos y almacenarlos en la matriz "ledData []". Si observa el código, verá que el bucle principal del boceto es el responsable de usar la información en ledData para iluminar los LED correctos y verificar el estado de los botones (una función llamada "shift ( ) "). La rutina de interrupción es lo más breve posible, solo verificando los bytes entrantes y almacenándolos adecuadamente.

Aquí está la configuración para timer2:

cli (); // detener interrupciones
// establecer temporizador2 interrupción cada 128us
TCCR2A = 0; // establece el registro TCCR2A completo en 0
TCCR2B = 0; // igual para TCCR2B
TCNT2 = 0; // inicializa el valor del contador a 0
// establece el registro de comparación de coincidencias para incrementos de 7.8khz
OCR2A = 255; // = (16 * 10 ^ 6) / (7812.5 * 8) - 1 (debe ser <256)
// activa el modo CTC
TCCR2A | = (1 << WGM21);
// Establecer bit CS21 para 8 preescaler
TCCR2B | = (1 << CS21);
// habilitar temporizador comparar interrupción
TIMSK2 | = (1 << OCIE2A);
sei (); // permitir interrupciones

Aquí está el boceto completo de Arduino:
 // PRUEBA DE BOTONES con 74HC595 y 74HC165 y comunicación serial // por Amanda Ghassaei // junio de 2012 ////www.instructables.com/id/Arduino-Timer-Interrupts/ / * * Este programa es software libre; puede redistribuirlo y / o modificarlo * bajo los términos de la Licencia Pública General GNU publicada por * la Free Software Foundation; ya sea la versión 2 de la Licencia, o * (a su elección) cualquier versión posterior. * * / // este firmware enviará datos de un lado a otro con el parche maxmsp "beat slicer" // conexiones de pines #define ledLatchPin A1 #define ledClockPin A0 #define ledDataPin A2 #define buttonLatchPin 9 #define buttonClockPin 10 #define buttonDataPin A3 / / variables de bucle byte i; byte j; byte k; byte ledByte; // almacenamiento para estados led, byte de 4 bytes ledData [] = {0, 0, 0, 0}; // almacenamiento para botones, byte de 4 bytes buttonCurrent [] = {0, 0, 0, 0}; byte buttonLast [] = {0, 0, 0, 0}; byte buttonEvent [] = {0, 0, 0, 0}; byte buttonState [] = {0, 0, 0, 0}; // botón rebote contador- 16 bytes byte buttonDebounceCounter [4] [4]; configuración vacía () = (1 << WGM21); // Establezca el bit CS21 para 8 preescaler TCCR2B // buttonCheck - verifica el estado de un botón dado. // esta función de comprobación de botones se copia en gran parte del firmware monome 40h por brian crabtree y joe lake void buttonCheck (byte row, byte index) {if (((buttonCurrent [row] ^ buttonLast [row]) & (1 << index) ) && // si el estado del botón físico actual es diferente del ((buttonCurrent [fila] ^ buttonState [fila]) & (1 << index))) {// último estado del botón físico Y el estado actual sin rebote if (buttonCurrent [fila] & (1 << índice)) // si el estado actual del botón físico es deprimido buttonEvent [fila] = 1 << índice; // poner en cola un nuevo evento de botón inmediatamente buttonState [fila] más {buttonDebounceCounter [fila] [índice] = 12; } // de lo contrario, el botón se presionó anteriormente y ahora // se ha liberado, por lo que configuramos nuestro contador de rebote. } else if (((buttonCurrent [fila] ^ buttonLast [fila]) & (1 << index)) == 0 && // si el estado actual del botón físico es el mismo que (buttonCurrent [fila] ^ buttonState [fila] ) & (1 <0 && --buttonDebounceCounter [fila] [índice] == 0) {// si el contador de rebote // se ha decrementado a 0 (lo que significa que // el botón ha estado activado // kButtonUpDefaultDebounceCount / / iterations /// buttonEvent [row] = 1 << index; // pone en cola un evento de cambio de estado del botón if (buttonCurrent [row] & (1 << index)) = (1 << index); else {buttonState [ fila] & = ~ (1 << índice);}}}} void shift () {for (i = 0; i <4; i ++) {buttonLast [i] = buttonCurrent [i]; byte dataToSend = (1 < > 3; // latchpin low digitalWrite (buttonLatchPin, LOW); for (k = 0; k <4; k ++) {buttonCheck (i, k); if (buttonEvent [i] <  1) & 3; byte ledx = (ledByte >> 3) & 3; if (ledstate) = 8 >> ledx; else {ledData [ledy] & = ~ (8 >> ledx); }} // finaliza si el serial está disponible} // end do while (Serial.available ()> 8); } void loop () {shift (); // actualiza leds y recibe datos de los botones} 

descargue el parche MaxMSP a continuación (también se ejecutará en Max Runtime).

Archivos adjuntos

  • beat slicer.zip Descargar

Paso 5: Ejemplo 3: DAC

En este proyecto utilicé una interrupción de temporizador para emitir una onda sinusoidal de una frecuencia específica desde el Arduino. Solde un simple R2R DAC de 8 bits a los pines digitales 0-7. Este DAC se construyó a partir de resistencias de 10k y 20k dispuestas en un divisor de voltaje de varios niveles. Publicaré más sobre la construcción del DAC en otro instructable, por ahora he incluido las fotos de arriba.
Conecté la salida del DAC a un osciloscopio. Si necesita ayuda para comprender cómo usar / leer el osciloscopio, consulte este tutorial. Cargué el siguiente código en el Arduino:
 // onda sinusoidal de 63Hz // por Amanda Ghassaei 2012 ////www.instructables.com/id/Arduino-Timer-Interrupts/ / * * Este programa es software libre; puede redistribuirlo y / o modificarlo * bajo los términos de la Licencia Pública General GNU publicada por * la Free Software Foundation; ya sea la versión 3 de la Licencia, o * (a su elección) cualquier versión posterior. * * / // envía una onda sinusoidal de 63Hz a arduino PORTD DAC float t = 0; configuración vacía () = (1 << CS21); // habilitar temporizador comparar interrupción TIMSK2 ISR (TIMER2_COMPA_vect) {// incremento t t + = 1; if (t == 628) {// 40kHz / 628 = ~ 63Hz t = 0; }} void loop () {// onda sinusoidal de frecuencia ~ 63Hz // envía valores sinusoidales a PORTD entre 0 y 255 PORTD = byte (127 + 127 * sin (t / 100)); } 
Configuré una interrupción del temporizador que incrementa la variable t a una frecuencia de 40kHz. Una vez que t alcanza 627, se restablece a cero (esto sucede con una frecuencia de 40, 000 / 628 = 63Hz). Mientras tanto, en el bucle principal, el Arduino envía un valor entre 0 (00000000 en binario) y 255 (11111111 en binario) a los pines digitales del 0 al 7 (PORTD). Calcula este valor con la siguiente ecuación:

PORTD = byte (127 + 127 * sin (t / 100));

Entonces, a medida que t aumenta de 0 a 627, la función seno se mueve a través de un ciclo completo. El valor enviado a PORTD es una onda sinusoidal con una frecuencia de 63Hz y una amplitud de 127, que oscila alrededor de 127. Cuando se envía a través de la escalera de resistencia de 8 bits DAC, emite una señal oscilante de alrededor de 2.5V con una amplitud de 2.5V y una frecuencia de 63Hz.

La frecuencia de la onda sinusoidal se puede duplicar multiplicando el término (t / 100) por 2, cuadruplicando multiplicando por 4, y así sucesivamente ...
Observe también que si aumenta la frecuencia del temporizador, interrumpa demasiado disminuyendo el preescalador o el OCR2A, la onda sinusoidal no se emitirá correctamente. Esto se debe a que la función sin () es computacionalmente costosa y a altas frecuencias de interrupción no tiene suficiente tiempo para ejecutarse. Si está utilizando interrupciones de alta frecuencia, en lugar de realizar un cálculo durante la rutina de interrupción, considere almacenar valores en una matriz y simplemente invocar estos valores utilizando algún tipo de índice. Puede encontrar un ejemplo de eso en mi generador de formas de onda arduino: al almacenar 20, 000 valores de sin en una matriz, pude generar ondas sinusoidales con una frecuencia de muestreo de 100kHz.

Paso 6: Funciones del temporizador y Arduino

Una última cosa a tener en cuenta: ciertas configuraciones de temporizador en realidad deshabilitarán algunas de las funciones de la biblioteca Arduino. Timer0 es utilizado por las funciones millis () y delay (), si configura manualmente timer0, estas funciones no funcionarán correctamente.
Además, los tres temporizadores suscriben la función analogWrite (). La configuración manual de un temporizador detendrá el funcionamiento de analogWrite ().

Si hay alguna parte de su código que no desea interrumpir, considere usar cli () y sei () para deshabilitar y habilitar globalmente las interrupciones.

Puede leer más sobre esto en el sitio web de Arduino.

Artículos Relacionados