Timer1 AVR temporizador contador


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

timer1 avr atmega88En este caso se verá el uso del timer1 AVR como contador, temporizador y en modo comparador, el uso del timer1 AVR en modo PWM se verá en otro apartado, en lo que sigue se comentará para el caso del ATmega88 por lo que es muy importante que se tenga a mano la hoja  de datos del atmega88, para el caso de utilizar algún otro microcontrolador AVR el procedimiento será muy similar a lo aquí comentado, la programación se realizará con atmel studio.

El timer1 AVR es un temporizador contador de 16 bits, el registro donde se guardan los valores del timer1 AVR es el registro temporizador contador representado por TCNT1, cuando es utilizado como temporizador, sus valores aumentaran de uno en uno entre 0 y 65535 con cada ciclo de reloj, por ejemplo si el oscilador con el que está funcionando el microcontrolador AVR es de 1MHz, entonces el registro TCNT1 aumentará una unidad en 1 us, si el registro TCNT1 se incrementa en 100 unidades habrán transcurrido 100us; cuando es utilizado como contador el temporizador timer1 AVR ya no aumenta su valor de uno en uno en cada ciclo de reloj, sino que lo hará mediante el flanco de subida o el flanco de bajada de alguna señal que llegue a un pin especial del AVR conectado al timer1 AVR, este pin es identificado como T1 que en el ATmega88 es el pin11 o PD5, esto puede variar de acuerdo al microcontrolador avr utilizado, pero siempre se llamará T1.

El registro TCNT1 del timer1 AVR puede ser leído y escrito, puede ser prescalado para que el tiempo en su incremento de valor en una unidad sea mayor, el timer1 AVR cuando alcanza su valor máximo de 65535 se reinicia, volviendo a incrementar sus valores de 0 a 65535, además cuando llega a su valor máximo y se reinicia puede producir una interrupción, lo cual se decide por programa.

Timer1 AVR como contador

Para el ATmega88 el registro TCNT1 del timer1 AVR está formado por 16 bits por lo que se puede contar desde 0 hasta 65535, al utilizar timer1 AVR como contador este no aumentará sus valores o su cuenta con cada ciclo de programa, en este caso el timer1 estará conectado al pin T1 por donde se le hará llegar una señal, la cual al cambiar de estado hará que el timer1 AVR se incremente en una unidad, estos incrementos en su cuenta pueden ser por cada flanco de subida o cada por flanco de bajada de la señal, el flanco a utilizar se elige por programa; por ejemplo su se elige el flanco de subida quiere decir que cada vez que la señal que llega al pin T1 pase de un bajo a un alto o de 0 a 1, el registro  TCNT1 aumentará en una unidad, de esta manera se le puede utilizar como contador, cuando la señal pase de un alto  a un bajo o de 1 a 0 el registro TCNT1 no aumentará su valor o no se incrementará.

Para programar el timer1 AVR como contador será necesario colocar todos los bits del registro TCCR1A a cero, esto es TCCR1A=0, en realidad esto no es necesario ya que el registro se inicializa automáticamente a 0, este registro será útil cuando se utilice el timer1 AVR en modo comparación y para la modulación de ancho de pulso PWM.

timer1 avr tccr1a

El registro TCCR1B es el que permitirá utilizar el timer1 avr como contador:

temporizador contador avr tccr1b

Según se ve en la hoja de datos del ATmega88 para utilizar el timer1 AVR como contador, del registro TCCR1B hay que manipular sus bits 0, 1 y 2 (CS10, CS11 y CS12) los demás bits se pondrán a 0, se tienen dos posibilidades, para que el conteo se realice cuando la señal que llega al pin T0 pase de 0 a 1 o por flanco de subida estos 3 bits se pondrán a 1 esto es CS00=1, CS01=1 y CS02=1; y si el conteo será cuando la señal que llega al pin T0 pase de 1 a 0 o por flanco de bajada solo se pondrán a 1 los bits 1 y 2, mientras el bit0 se deja a 0 esto es CS00=0, CS01=1 y CS02=1.

temporizador contador avr prescaler

Al elegir alguna de las 2 posibilidades, cada vez que la señal digital que llegue al pin T1 pase de un alto a un bajo o de un bajo a un alto, según se haya elegido, el valor del contador, esto es el valor del registro TCNT1, aumentará en una unidad hasta un máximo de 65535, luego se pondrá nuevamente a 0 y otra vez comenzará el conteo.

Ejemplo

Se utilizará el timer1 AVR como contador,  para ello se ha preparado el circuito tal como se muestra en la imagen, la señal digital será generada una onda cuadrada de 5Khz con la ayuda de un generador de funciones conectado al pin T1, se hará que le registro TCNT1 aumente su cuenta por cada flanco de bajada, en 5Khz en cada segundo habrán 5000 flancos de subida, por lo que en cada segundo el registro TCNT1 aumentará su valor 5000 veces, que es lo mismo que decir que realizará 5000 conteos, como el TCNT1 puede contar de 0 a 65535, si esto se divide entre 8 se tiene poco mas de 8191, para poder ver indirectamente los conteos se hará que cada vez que el registro TCNT1 aumente su valor en 8200 unidades se encienda en forma ordenada un led conectado en el puerto B, de la siguiente forma:

Cuando el valor del timer1 AVR sea menor que 8200 solo se encenderá el led conectado al pin PB0.

Cuando el valor del timer1 AVR sea menor que 16400 solo se encenderá el led conectado al pin PB1.

Cuando el valor del timer1 AVR sea menor que 24600 solo se encenderá el led conectado al pin PB2.

Cuando el valor del timer1 AVR sea menor que 32800 solo se encenderá el led conectado al pin PB3.

Cuando el valor del timer1 AVR sea menor que 41000 solo se encenderá el led conectado al pin PB4.

Cuando el valor del timer1 AVR sea menor que 49200 solo se encenderá el led conectado al pin PB5.

Cuando el valor del timer1 AVR sea menor que 57400 solo se encenderá el led conectado al pin PB6.

Cuando el valor del timer1 AVR sea menor que 65535 solo se encenderá el led conectado al pin PB7.

timer1 avr ejemplo contador

 

El programa realizado en el atmel studio para el uso del temporizador contador timer1 AVR como contador es el siguiente:

timer1 avr ejemplo código

Timer1 AVR como temporizador

Para el ATmega88 el registro TCNT1 del timer1 AVR está formado por 16 bits por lo que se sus valores pueden ser desde 0 hasta 65535, al utilizar timer1 AVR como temporizador este aumentará sus valores o su cuenta con cada ciclo de reloj,  sus valores aumentaran de uno en uno entre 0 y 65535, por ejemplo si el oscilador con el que está funcionando el microcontrolador AVR es de 1MHz, entonces el registro TCNT1 aumentará una unidad en 1 us, si el registro TCNT1 se incrementa en 2700 unidades habrán transcurrido 2700us.

Normalmente el registro del timer1 TCNT1 irá aumentando su conteo con cada ciclo de reloj del microcontrolador, si se usa por ejemplo una frecuencia de trabajo (lo que se conoce como FCPU) de 1Mhz entonces el registro TCNT1 aumentará en una unidad cada microsegundo, y como este registro es de 8 bits este aumentará desde 0, o desde algún valor que se le ponga como valor inicial al registro TCNT1, hasta un máximo de 65535, por ejemplo si va desde 0 hasta 65535 habrán transcurrido 65535us luego volverá a 0 pero en esa vuelta a 0 transcurre 1us mas, por lo cual en ir de 0 y volver a 0 transcurren 65536us; no siempre se utiliza una FCPU de 1Mhz esto puede variar, por lo que como consecuencia variará el tiempo que trascurre para que el registro TCNT1 aumente su valor.

Para programar el timer1 AVR como temporizador será necesario colocar todos los bits del registro TCCR1A a cero, esto es TCCR1A=0, en realidad esto no es necesario ya que el registro se inicializa automáticamente a 0, este registro será útil cuando se utilice el timer1 AVR en modo comparación y para la modulación de ancho de pulso PWM.

timer1 avr tccr1a

El registro TCCR1B es el que permitirá utilizar el timer1 avr como temporizador:

El timer1 AVR cuenta con lo que se conoce como el prescaler esto hace que la frecuencia de trabajo FCPU se divida por este prescaler, con lo que se logra que el timer1 AVR tarde un poco mas en aumentar su valor en una unidad; el prescaler puede tomar el valor de 1, 8, 64, 256 o 1024; estos valores se eligen programando los bits 0, 1 y 2 del registro TCCR1B, los bits 7 a 3 en este caso se pondrán a 0.

temporizador contador avr tccr1b

En la siguiente tabla se ve los valores que hay que dar a estos bits para obtener los diferentes valores de los prescaler para el temporizador timer1 AVR, observar que cuando estos bits son todos iguales a 0 el timer1 AVR está deshabilitado.

temporizador contador avr prescaler

Si el prescaler elegido es por ejemplo de 64 y la FCPU=1Mhz, entonces la frecuencia de trabajo del timer1 AVR Ftemp será de Ftemp=FCPU/prescaler, el tiempo  que tardará ahora el temporizador en aumentar una unidad será la inversa de este valor lo cual se conoce como periodo Ttemp=prescaler/FCPU por lo que en este caso Ttemp=(64)/(1Mz) de donde Ttemp=64us, esto quiere decir que ahora el timer1 AVR aumentará en una unidad cada 65us y en este caso entonces el registro TCNT1 para ir de 0 a 65535 tardará 65535*Ttemp=65535*64us=4194240us=4,194240s; la misma idea es para los demás prescaler.

Al utilizar los prescaler se tiene la ventaja de lograr tiempos mas largos para cada incremento en una unidad del registro TCNT1 del timer1 AVR, y por lo tanto realizar temporizaciones mas largas mientras el timer1 AVR incrementa sus valores.

De acuerdo a los tiempos que se quieran obtener al utilizar el timer1 AVR, habrá que utilizar el prescaler adecuado así como inicializar el registro TCNT1 también con un valor adecuado, no olvidar que este registro es de 16 bits y por lo tanto solo puede contener valores enteros entre 0 y 65535.

Utilizando una regla de 3 simple se llega a la siguiente ecuación que ayudará a encontrar el valor inicial adecuado a cargar en el registro TCNT1 para obtener el tiempo buscado.

TCNT1=216-Tretardo*(FCPU/prescaler)

Donde TCNT1 es el valor inicial a cargar en este registro para obtener el  tiempo buscado, 216 porque el timer1 es de 16 bits, Tretardo es el tiempo que se quiere obtener con el timer1 AVR, FCPU es la frecuencia de trabajo del microcontrolador o del cristal utilizado, y prescaler será el prescaler elegido según la tabla anterior.

Por ejemplo si se quiere temporizar 500ms, en este caso 500ms sería el tiempo de retardo, y si el microcontrolador AVR trabaja con una FCPU de 1Mhz, habrá que elegir entre los posibles prescaler que se tienen, reemplazar en la ecuación anterior y ver si el número obtenido esta entre 0 y 65535, de ser así la elección del prescaler es correcta, de lo contrario habrá que utilizar otro, por ejemplo si se elige un prescaler de 8 se tendría:

TCNT1=65535-(500ms)(1Mhz)/8

TCNT1=3036

El valor obtenido está entre 0 y 65535 por lo que 3036 sería el valor inicial a cargar en el registro TCNT1 para obtener una temporización de 500ms con el timer1 AVR, esto quiere decir que si se inicia el timer1 AVR con 3036 y un prescaler de 8, cuando aumente su valor de 3036 a 65535 habrán transcurrido 500ms.

Este proceso será el que se seguirá cuando se utilice el timer1 AVR como temporizador.

Ejemplo

Se utilizará el timer1 AVR como temporizador,  para ello se ha preparado el circuito tal como se muestra en la imagen, se hará parpadear un led conectado en el pin PD7 cada 500ms, este tiempo será obtenido mediante la temporización con el timer1 AVR aprovechando lo calculado hace un momento, la frecuencia de trabajo será de 1Mhz, el prescaler será de 8 y habrá que cargar el registro TCNT1 con un valor inicial de 3036.

timer1 avr circuito

El programa realizado en el atmel studio para el uso del temporizar contador timer1 avr como temporizador es el siguiente:

 timer1 avr temporizador código

Timer1 AVR en modo comparador modo CTC

timer1 avr atmega88

Al utilizar el timer1 AVR en modo comparador ocurre que el registro TCNT1, que en este caso es de 16 bits, irá aumentando su valor de uno en uno desde 0 hasta que este se haga igual a un valor almacenado en el registro OCR1A (no en el registro OCR1B) o en el registro ICR1, en el momento que se hacen iguales los valores de los registros TCNT1 y OCR1A o TCNT1 y ICR1, el registro TCNT1 se pone automáticamente a cero o también se dice se borra, para nuevamente comenzar a aumentar su valor desde 0 hasta que se vuelva hacer igual al valor almacenado en el registro OCR1A o en el registro ICR1, mas adelante se  verá como elegir para la comparación el registro OCR1A o el registro ICR1.

A esto se lo conoce como el modo de trabajo CTC, que quiere decir borrado del timer por comparación.

Si se utiliza el modo CTC y se tiene almacenado un valor en el registro OCR1A o en el registro ICR1, eso quiere decir que por el pin OC1A o el pin OC1B, mas adelante se verá como elegir el pin a utilizar, cuando el valor del registro TCNT1 se haga igual al valor almacenado en el registro OCR1A o en el registro ICR1, ocurrirá algún evento en alguno de estos pines, como por ejemplo que si el  pin está a uno se pondrá a cero, o si está a cero se pondrá a uno; es necesario ademas configurar el pin a utilizar como una salida mediante el registro DDRx dependiendo en que puerto este el pin, que para el atmega88 está en el puerto B.

En el modo de trabajo CTC del timer1 se utilizarán los registros TCCR1A y  TCCR1B

El registro TCCR1A con este registro se elige si el evento a ocurrir como respuesta por comparación a la igualdad entre el registro TCNT1 y el registro OCR1A o el registro ICR1, será por el pin OC1A u OC1B, en la siguiente imagen se tiene el registro TCCR1A, en el se pueden ver los nombres dados a sus bits.

timer1 avr tccr1a

Los bits 7 y 6 son para elegir que el evento cuando ocurra la comparación sea por el pin OC1A, para elegir el tipo de evento que ocurrirá cuando se iguale el registro TCNT1 con el registro OCR1A o el registro ICR1, en el caso de utilizar el pin OC1A para las combinaciones de los bits 7 y 6 se tiene la siguiente tabla, si ambos bits son 0 la opción OC1A del pin no está disponible trabajando el pin como una entrada salida digital normal.

temporizador contador avr tabla

Si por ejemplo los bits 6 y 7 se ponen a 0 el pin OC1A no se verá afectado por la comparación pudiendo utilizarse como una entrada salida digital, si por ejemplo el el bit7 se pone a 0 y el bit6 a 1 entonces el estado del pin OC1A alternará cada vez que la comparación ocurra, si el bit7 y el bt6 se ponen a 1 ocurrirá que si el pin OC1A estaba a 0 este se pondrá a 1, pero si estaba a 1 este no se verá afectado.

Los bits 5 y 4 son para elegir que el evento cuando ocurra la comparación sea por el pin OC1B, para elegir el tipo de evento que ocurrirá cuando se iguale el registro TCNT1 con el registro OCR1A o el registro ICR1, en el caso de utilizar el pin OC1B para las combinaciones de los bits 5 y 4 se tiene la siguiente tabla, si ambos bits son 0 la opción OC1A del pin no está disponible trabajando el pin como una entrada salida digital normal.

temporizador contador avr tabla

Si por ejemplo los bits 5 y 4 se ponen a 0 el pin OC1B no se verá afectado por la comparación pudiendo utilizarse como una entrada salida digital, si por ejemplo el el bit5 se pone a 0 y el bit4 a 1 entonces el estado del pin OC1B alternará cada vez que la comparación ocurra, si el bit5 y el bt4 se ponen a 1 ocurrirá que si el pin OC1B estaba a 0 este se pondrá a 1, pero si estaba a 1 este no se verá afectado.

Los bits 3 y 2 no se utilizan por lo que se les suele pones a 0.

Los bits 1 y 0 en el modo comparación se ponen a 0, será utilizado en el modo PWM.

El registro TCCR1B con este registro se elige el prescaler a utilizar, para obtener en cuanto tiempo se quiere que el registro TCNT1 se iguale al registro OCR1A o al registro ICR1, en la siguiente imagen se tiene el registro TCCR1B, en el se pueden ver los nombres dados a sus bits.

temporizador contador avr tccr1b

Los bits 7 y 6 son utilizados en el modo captura por lo que en el modo CTC se les pone a 0.

El bit5 no se utilizan por lo que se les suele poner a 0.

Los bits 4 y 3 con estos bits se elige cual será el registro utilizado en la comparación con el registro TCNT1.

  • Si el bit4 es puesto a 0 y el bit3 es puesto a 1 el registro a utilizar en el modo CTC será el registro OCR1A.
  • Si el bit4 es puesto a 1 y el bit3 es puesto a 1 el registro a utilizar en el modo CTC será el registro ICR1.

Los bits 2, 1, y 0 son utilizados para elegir el prescaler de acuerdo a las combinaciones de estos bits, según la siguiente tabla.

temporizador contador avr prescaler

Timer1 AVR en modo CTC los registro OCR1A e ICR1

En el registro OCR1A o en el registro ICR1 según el que se elija con el el registro TCCR1B, se cargará el valor hasta el cual se quiere que llegue el registro TCNT1 en el modo CTC, por lo que hay que ver como se puede encontrar el valor adecuado a cargar en el registro OCR1A o en el registro ICR1, en lo que sigue se verá el procedimiento para el registro OCR1A pero el lo mismo para el registro ICR1.

Se ha visto que para utilizar el timer1 AVR como temporizador hay que cargar el registro TCNT1 con un valor obtenido de la siguiente ecuación:

TCNT1=216-Tretardo*(FCPU/prescaler)-1

Para el caso de utilizar el timer1 AVR en modo de comparación o CTC hay que cargar en el registro OCR1A, la cantidad de veces que tiene que contar el registro TCNT1, lo que viene a ser el máximo valor al que el registro TCNT1 puede llegar que es 65535 menos lo que sería necesario cargar en el registro TCNT1 para obtener el tiempo buscado, entonces de la ecuación anterior se tendría que cargar el registro OCR1A:

OCR1A  = 216-TCNT0-1 = Tretardo*(FCPU/prescaler)

entonces:

OCR1A= Tretardo*(FCPU/prescaler)

El registros OCR1A es de 16 bits por lo que el valor obtenido mediante la ecuación anterior tendrá que ser un número entero comprendido entre 0 y 65535, de no ser así el valor no será válido.

Por ejemplo, para lograr que la comparación ocurra cada 500ms, utilizando un prescaler de 8 será necesario cargar el registro OCR1A con el valor de

OCR1A=(500ms)(1Mhz)/8

De donde OCR1A=62500

El valor obtenido está entre 0 y 65536, por lo que 62500 será el valor a cargar en el registro OCR1A, si se elige el registro ICR1 este sería el valor a cargar en este registro.

Para el registro TCNT1 del timer1 AVR, si se carga el registro OCR1A con 62500 y se utiliza un prescaler de 8, entonces cuando aumente el valor del registro TCNT1 de 0 a 62500 habrán transcurrido 500ms.

62500 sería el valor a cargar en el registro OCR1A para que cada 500ms el valor del registro TCNT1 llegue a 62500 y por comparación se produzca un evento en el pin OC1A u OC1B, tras lo cual el registro TCNT1  se pondrá automáticamente a 0 para volver a aumentar su valor nuevamente hasta 62500 en un lapso de 500ms y se vuelva ha repetir el proceso.

Con los valores obtenidos se hará el siguiente ejemplo.

Ejemplo:

Para el ejemplo del uso del temporizador contador timer1 avr en modo CTC, se utilizará el pin 16 o pin OC1B del ATmega88 como el pin en el que ocurrirá un evento, que será que cada vez que ocurra la la igualdad entre el registro TCNT1 y el registro OCR1A el estado de este pin OC1B cambie, este pin hay que configurar como una salida digital mediante el DDRB correspondiente, se hará que el pin OC1B cambie de estado cada 500ms, esto será observado mediante un led conectado a este pin.

Será necesario entonces utilizando los cálculos anteriores cargar el registro OCR1A=62500, del registro TCCR1A hay que poner a 1 su bit4 para que el evento por cambio de estado sea por el pin OC1B, sus demás bits se ponen a 0.

TCCR1A=0b00010000;//cambio estado en el pin OC1B

Del registro TCCR1B poner a 1 su bit3 para que el registro a utilizar en el modo CTC sea el registro OCR1A, su bit1 hay que ponerlo a 1 para tener el prescaler de 8, para hacer que un led conectado al pin OC1B cambie de estado cada 500ms, todos sus demás bits se pondrán a 0.

TCCR1B=00001010;//prescaler de 8 modo CTC con registro OCR1A

El circuito utilizado para ver el uso del temporizador contador timer1 avr en modo CTC es el siguiente:

timer1 avr modo comparación circuito

El programa realizado en el atmel studio para el uso del temporizador contador timer1 AVR en modo CTC es el siguiente:

timer1 AVR en modo CTC código

Si he logrado ayudarte en cuanto a la utilización del timer1 AVR como contador, temporizador y comparador, comparte este enlace para poder ayudar a muchas personas mas, el uso del timer1 AVR en modo PWM se verá en otra sección. Muchas Gracias.

Atte MrElberni

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