Interrupción timer0 AVR


Compartir: Share on Facebook0Tweet about this on TwitterShare on Google+0Share on Tumblr0Share on LinkedIn0

Interrupción timer0 AVR, mediante la interrupción timer0 AVR se puede detener el programa  principal con el cual este trabajando el microcontrolador AVR, para indicarle al microcontrolador que se dedique a realizar otras tareas, al finalizar la interrupción timer0 AVR, se seguirá con el programa principal desde donde fue interrumpido.

En esta sección que es una secuencia del tema tratado en este enlace se tratará sobre los eventos que hacen que el timer0 produzca una interrupción, por lo que es muy importante que se sepa utilizar el timer0 AVR, sobre la utilización del timer0 AVR ya se ha tratado y se puede ver aquí, para lo que se va a comentar a continuación se utilizará como base el microcontrolador AVR ATmega88.

La programación de la interrupción timer0 AVR se hará en C/C++ con el ATMEL STUDIO, se utilizará la librería interrupt.h de la cual se puede hallar una descripción detallada aquí.

La interrupción timer0 AVR puede ocurrir por los siguientes motivos en el ATmega88, los cuales son:

  • Por desbordamiento del timer0, esto ocurre cuando el timer0 alcanza su máximo valor que es 255, cuando alcanza este valor se dice que se desborda  porque ya no puede tomar otro valor mayor, y se reinicia a 0 o a algún otro valor, justo en ese momento se le puede programar si así se desea para que el timer0 cause una interrupción por desbordamiento.
  • Por la igualdad entre el registro TCNT0 y el registro OCR0A cuando se utiliza timer0 en modo CTC, esto quiere decir que justo en el momento que el registro TCNT0 se iguale al valor almacenado en el registro OCR0A, se puede programar el timer0 para que produzca una interrupción timer0 AVR y se ejecute un evento en el pin OC0A.
  • Por la igualdad entre el registro TCNT0 y el registro OCR0A cuando se utiliza timer0 en modo CTC, esto quiere decir que justo en el momento que el registro TCNT0 se iguale al valor almacenado en el registro OCR0A, se puede programar el timer0 para que produzca una interrupción timer0 AVR y se ejecute un evento en el pin OC0B.

Para habilitar el uso de la interrupción timer0 AVR se utiliza el registro llamado registro de mascara de interrupciones, que para el timer0 es el TIMSK0, además deben estar habilitadas las interrupciones globales, lo cual en el ATMEL STUDIO se hará con la instrucción sei(), tal como se comentó aquí.

interrupción timer0 avr timsk0

Los bits 7 al 3 de este registro no son utilizados por lo que se les suele poner a 0.

Al poner a 1 el bit2 se habilita que el evento que cause la interrupción timer0 AVR sea cuando se iguale el registro TCNT0 al registro OCR0A en modo CTC y se produzca un evento en el pin OC0B.

Al poner a 1 el bit1 se habilita que el evento que cause la interrupción timer0 AVR sea cuando se iguale el registro TCNT0 al registro OCR0A en modo CTC y se produzca un evento en el pin OC0A.

Al poner a 1 el bit0 se habilita que el evento que cause la interrupción timer0 AVR sea cuando el registro TCNT0 alcance su máximo valor de 255 o lo que es lo mismo se desborde.

Para detectar cuando se ha producido la interrupción timer0 AVR se cuenta con el registro TIFR0.

interrupción timer0 avr tifr0

Los bits 7 a 3 no se utilizan por lo cual se les suele poner a 0.

Para detectar si se ha producido una interrupción timer0 avr en modo CTC entre el registro TCNT0 y el registro OCR0A utilizando el pin OC0B, el bit2 se tendrá que poner a 0, cuando se produzca la interrupción este bit se pondrá automáticamente a 1, si se quiere seguir produciendo mas interrupciones por comparación entre el registro TCNT0 y el registro OCR0A este bits habrá que ponerlo nuevamente a 0 dentro de la rutina de interrupciones, cuando se utiliza la rutina de interrupciones de C/C++ con el ATMEL STUDIO, este bit se pone a 0 automáticamente.

Para detectar si se ha producido una interrupción timer0 avr en modo CTC entre el registro TCNT0 y el registro OCR0A utilizando el pin OC0A, el bit1 se tendrá que poner a 0, cuando se produzca la interrupción este bit se pondrá automáticamente a 1, si se quiere seguir produciendo mas interrupciones por comparación entre el registro TCNT0 y el registro OCR0A este bits habrá que ponerlo nuevamente a 0 dentro de la rutina de interrupciones, cuando se utiliza la rutina de interrupciones de C/C++ con el ATMEL STUDIO, este bit se pone a 0 automáticamente.

Para detectar si se ha producido una interrupción timer0 avr por desborde, el bit0 se tendrá que poner a 0, cuando se produzca la interrupción este bit se pondrá automáticamente a 1, si se quiere seguir produciendo mas interrupciones por desborde este bits habrá que ponerlo nuevamente a 0 dentro de la rutina de interrupciones, cuando se utiliza la rutina de interrupciones de C/C++ con el ATMEL STUDIO, este bits se pone a 0 automáticamente.

Rutinas de interrupción timer0 avr en C/C++ en el ATMEL STUDIO

Si se utiliza la interrupción timer0 AVR por desborde, la rutina de interrupción se realizará dentro de la siguiente función:

ISR(TIMER0_OVF_vect){

//tareas a realizar dentro de la rutina de interrupción tmr0 AVR por desborde

}

Si se utiliza la interrupción timer0 AVR por comparación entre el registro TCNT0 y el registro OCR0A, siendo el pin OC0A aquel en el cual ocurrirá algún evento, la rutina de interrupción se realizará dentro de la siguiente función:

ISR(TIMER0_COMPA_vect){

//tareas a realizar dentro de la rutina de interrupción tmr0 AVR por comparación entre el registro TCNT0 y el registro OCR0A, utilizando el pin OC0A

}

Si se utiliza la interrupción timer0 AVR por comparación entre el registro TCNT0 y el registro OCR0A, siendo el pin OC0B aquel en el cual ocurrirá algún evento, la rutina de interrupción se realizará dentro de la siguiente función:

ISR(TIMER0_COMPB_vect){

//tareas a realizar dentro de la rutina de interrupción tmr0 AVR por comparación entre el registro TCNT0 y el registro OCR0A, utilizando el pin OC0B

}

Interrupción timer0 AVR por desbordamiento

La intensión del siguiente ejemplo es comprender como utilizar la interrupción timer0 AVR por desborde, no se busca complicar el ejemplo, se provocará una interrupción timer0 AVR por desborde del ATmega88, el cual estará trabajando a una frecuencia de reloj de 1Mhz, se utilizará el  timer0 como temporizador para obtener un tiempo de 100ms de temporización, tras lo cual se producirá la interrupción y en la rutina de atención a la interrupción se hará que el pin PD7 cambie de estado, lo cual será visible por medio de un led conectado a este pin.

Hay que calcular cual será el valor a cargar en el registro TCNT0 para obtener los 100ms, para ello se utiliza la siguiente ecuación que se vio  aquí.

TCNT0=28-Tretardo*(FCPU/prescaler)

Se utilizará un prescaler de 1024, luego

TCNT0=256-(100ms)*(1Mhz/1024)

De donde TCNT0=158,3438 este valor está entre 0 y 255 por lo que es correcto, pero como en el registro TCNT0 solo se pueden cargar números enteros, se cargará con un valor cercano a este, se hará para TCNT0=159, no será exactamente 100ms lo que se obtenga pero si muy cercano y aceptable en este caso.

Como el prescaler será de 1024, el registro TCCR0B se cargará con TCCR0B=0b00000101;

Como se utilizara la interrupción timer0 AVR por desborde, el bit0 del registro TIMSK0 se pondrá a 1 por lo que TIMSK0=0b00000001;

El registro TCNT0 se cargará con 159 al utilizar el prescaler de 1024 para temporizar 100ms, cuando el registro TCNT0 llegue a su máximo valor de 255 habrán transcurrido 100ms, momento en el que se desbordará provocando una interrupción timer0 AVR, deteniendo el programa principal del atmega88, y realizando lo indicado dentro de la rutina de interrupción que será cargar nuevamente el registro TCNT0 con 159 y cambiar el estado del pin PD7, luego se saldrá de la rutina de interrupción para volver al programa principal, el cambio a 0 del bit0 del registro TIFR0 que es el que detecta cuando se ha producido la interrupción no es necesario realizarlo ya que el ATMEL STUDIO lo hace automáticamente.

El circuito utilizado es el siguiente:

interrupción tmr0 avr por desborde

El programa realizado en el atmel studio para provocar la interrupción timer0 avr y obtener una temporización de 100ms tras lo cual cambiara el estado del pin PD7 es el siguiente:

interrupción timer0 por desborde código

Interrupción timer0 AVR por Comparación

La intensión del siguiente ejemplo es comprender como utilizar la interrupción timer0 AVR por comparación, no se busca complicar el ejemplo, se provocará una interrupción timer0 AVR por comparación del ATmega88, el cual estará trabajando a una frecuencia de reloj de 1Mhz, se buscará que el registro  TCNT0 y el registro OCR0A se igualen cada 100ms, tras lo cual se hará que un led conectado al pin PD7 cambie de estado por interrupción. En el pin OC0A también se conectará un led pero este parpadeará por el evento de cambio de estado en el pin OC0A que produce la propia comparación no por interrupción.

Hay que calcular cual será el valor a almacenar en el registro OCR0A para obtener los 100ms, para ello se utiliza la siguiente ecuación que se vio  aquí.

OCR0A= Tretardo*(FCPU/prescaler)

Se utilizará un prescaler de 1024, luego

OCR0A=(100ms)*(1Mhz/1024)

De donde OCR0A=97,6563 este valor está entre 0 y 255 por lo que es correcto, pero como en el registro OCR0A solo se pueden almacenar números enteros, se almacenará un valor cercano a este, se hará para OCR0A=97, la comparación no ocurrirá exactamente a los 100ms pero si a un tiempo muy cercano y aceptable en este caso, no olvidar que tras la comparación el registro TCNT0 se reinicia a 0; ahora ademas se hará que produzca una interrupción tmr0 AVR.

Como el prescaler será de 1024, el registro TCCR0B se cargará con TCCR0B=0b00000101;

Como se utilizara la interrupción timer0 AVR por comparación, el bit1 del registro TIMSK0 se pondrá a 1 por lo que TIMSK0=0b00000010;

En el registro OCR0A se almacenará 97 al utilizar el prescaler de 1024 para que la comparación ocurra cada 100ms, cuando el registro TCNT0 se iguale al valor almacenado en el registro OCR0A habrán transcurrido 100ms, momento en el que por comparación se provocará una interrupción timer0 AVR, deteniendo el programa principal del atmega88, y realizando lo indicado dentro de la rutina de interrupción que será cambiar el estado del pin PD7, no es necesario volver a cargar el registro OCR0A con 97 ya que este valor ya está almacenado en OCR0A, luego se saldrá de la rutina de interrupción para volver al programa principal, el cambio a 0 del bit1 del registro TIFR0 que es el que detecta cuando se ha producido la interrupción no es necesario realizarlo ya que el ATMEL STUDIO lo hace automáticamente.

El circuito utilizado es el siguiente:

interrupción timer0 avr por comparación ejemplo

El programa realizado en el atmel studio para provocar la interrupción timer0 avr por comparación entre el registro  TCNT0 y el registro OCR0A, y hacer que la comparación ocurra cada 100ms produciendo una interrupción tras lo cual cambiara el estado del pin PD7 es el siguiente:

interrupción timer0 avr modo CTC código

En el ejemplo se ha utilizado la interrupción timer0 por comparación entre el registro  TCNT0 y el registro OCR0A, utilizando el pin OC0A, es la misma idea si se utiliza el pin OC0B, solo habrá que hacer el cambio en el registro TCCR0A y en el DDRx correspondiente al pin OC0A.

Si he logrado ayudarte en cuanto a la utilización de la interrupción timer0 AVR comparte este enlace para poder ayudar a muchas personas mas. Muchas Gracias.

Atte: MrElberni.

Compartir: Share on Facebook0Tweet about this on TwitterShare on Google+0Share on Tumblr0Share on LinkedIn0