Subido por Luis Enrique Lopez Hernandez

Periféricos AVRs ATMega328

Anuncio
ORGANIZACIÓN INTERNA DE LOS
MICROCONTROLADORES
Microcontroladores
Periféricos:
Temporizador/Contador
PWM
Junio / 2021
ASPECTO
EXTERNO
ATMEGA328
Incluye 3 Timers,
TMP0
TMP1
TPM2
5
AVR CPU CORE
6
INTERIOR DEL MICROCONTROLADOR (ATMEGA328P
7
Vector de interrupciones en el ATMega328
Vect.
Dir.
Fuente
Descripción
1
0x0000
RESET
Reset del sistema (diferentes condiciones)
2
0x0002
INT0
Interrupción Externa 0
3
0x0004
INT1
Interrupción Externa 1
4
0x0006
PCINT0
Int. por cambio de pines 0
5
0x0008
PCINT1
Int. por cambio de pines 1
6
0x000A
PCINT2
Int. por cambio de pines 2
7
0x000C
WDT
Reset por Watchdog Timer
8
0x000E
TIMER2_COMPA
El timer 2 coincide con su comparador A
9
0x0010
TIMER2_COMPB
El timer 2 coincide con su comparador B
10
0x0012
TIMER2_OVF
11
0x0014
TIMER1_CAPT
12
0x0016
TIMER1_COMPA
El timer 1 coincide con su comparador A
13
0x0018
TIMER1_COMPB
El timer 1 coincide con su comparador B
14
0x001A
TIMER1_OVF
Desbordamiento del timer 2
Captura de entrada con el timer 1
Desbordamiento del timer 1
15
Vect. Dir.

Fuente
Descripción
15
0x001C
TIMER0_COMPA
El timer 0 coincide con su comparador A
16
0x001E
TIMER0_COMPB
El timer 0 coincide con su comparador B
17
0x0020
TIMER0_OVF
18
0x0022
SPI_STC
19
0x0024
USART_RX
20
0x0026
USART_UDRE
Registro de Datos de la USART vacío
21
0x0028
USART_TX
Transmisión completa por la USART
22
0x002A
ADC
23
0x002C
EE_READY
24
0x002E
ANALOG_COMP
25
0x0030
TWI
26
0x0032
SPM_READY
Desbordamiento del timer 0
Transferencia completa por SPI
Recepción completa por la USART
Conversión del ADC completa
EEPROM lista
Comparador analógico
Interfaz serial a dos hilos (2-wire)
Almacenamiento en memoria de
programa
La ubicación de los vectores de interrupción puede modificarse
para que el MCU inicie ejecutando instrucciones desde la sección
de arranque.
16
Registro de ESTADO (SREG: 0x3F)
Bit
Read/Write
Valor inicial
– I: Habilitador global de Interrupciones,
con un 1 lógico, las interrupciones son habilitadas.
– T: Para respaldo de un bit, es usado con la instrucción BLD para
Carga y BST para Almacenamiento.
– H: Bandera de acarreo de los 4 bits inferiores (Half)
– S: Bit de signo (Mantiene una XOR entre N y V)
– V: Bandera de Sobreflujo, en operaciones de complemento a dos.
– N: Bandera de Negativo
– Z: Bandera de Cero
– C: Bandera de Acarreo
Se generan con operaciones
Aritméticas y lógicas
22
Modos de bajo consumo
SM2
SM1
SM0
Modo de bajo consumo
0
0
0
Modo ocioso (Idle)
0
0
1
Modo de reducción de ruido en el
ADC
0
1
0
Modo de baja potencia
0
1
1
Modo de ahorro de potencia
1
0
0
Reservado
1
0
1
Reservado
1
1
0
Modo de espera (Standby)
1
1
1
Modo de espera extendido
Notas: Para el modo de espera (Standby) se recomienda usar cristales o resonadores externos.
70
Administración de la Potencia y modos SLEEP
• Modo ocioso: Todos los recursos trabajan, la CPU no ejecuta
instrucciones (no tienen señal de reloj). El reloj principal y del
temporizador están activos. Cualquier evento de los diferentes
recursos provoque una salida del modo de reposo.
• Modo de reducción de ruido en el ADC: Únicamente trabaja
el ADC y el oscilador asíncrono para el temporizador 2.
Adecuado para aplicaciones que requieren el monitoreo de
parámetros analógicos en periodos preestablecidos de tiempo.
• Modo de baja potencia: No hay reloj, es el modo con el menor
consumo de energía. El MCU puede ser reactivado por eventos
en la interfaz de dos hilos o por las interrupciones externas.
71
Administración de la Potencia y modos SLEEP
• Modo de ahorro de potencia: Sólo está activo el oscilador
asíncrono, se mantiene activo el temporizador 2, sincronizado
con una fuente de reloj externa. Ideal para aplicaciones que
involucren un reloj de tiempo real.
• Modo de espera: Este modo es muy similar al modo de baja
potencia, la única diferencia es que en este modo se mantiene
activo el suministro del reloj principal.
• Modo de espera extendido: Este modo es muy similar al
modo de ahorro de potencia, la única diferencia es que en este
modo también está activo el suministro del reloj principal.
72
Administración de la Potencia y
modos SLEEP
Reloj Principal
Oscilador del
temporizador
INT0, INT1 y
cambio en pines
Interfaz de dos
hilos (TWI)
Temporizador 2
EEPROM, Memoria
de programa lista
ADC
WDT
Otros I/O
Reducción de ruido en el
ADC
clkASY
Modo ocioso (idle)
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
Baja potencia
Ahorro de potencia
X
Modo de espera (standby)
Modo de espera extendido
Eventos que despiertan al MCU
clkFLASH clkIO clkADC
Modo de Bajo Consumo
de Energía
Osciladores
clkCPU
Reloj Activo
X
X
X
X
X
X
X
X
X
X
X
73
Timer/Contador.
En esencia.
Los temporizadores son útiles cuando desea establecer un intervalo de tiempo como
su alarma. Esto puede ser muy preciso en unos pocos microsegundos.
Los temporizadores son el corazón del control. Los temporizadores nos brindan un
nivel adicional de control al brindarnos no solo control sobre lo que sucede, sino
también sobre cuándo sucede. Podemos poner un retraso de tiempo, podemos
controlar la velocidad de destello o que una batería completamente se haya cargado.
Timer/Contador (cont.).
Los temporizadores/contadores son una parte esencial de cualquier MCU moderno. El
Timer/Contador es un módulo que esta dentro del MCU que se utiliza como
temporizadores o contadores. Básicamente, se ejecutan independientemente de la
tarea que esté realizando la CPU. Por lo tanto, son muy útiles y se utilizan
principalmente para lo siguiente:
• Temporizador interno: como temporizador interno, la unidad marca la frecuencia
del oscilador. La frecuencia del oscilador se puede alimentar directamente al
temporizador o se puede (dividir) preescalar. En este modo se utiliza generar
retrasos precisos.
• Contador externo (CTC: clear timer on compare match): en este modo, la
unidad se usa para contar eventos a partir de una terminal externo específico en
una MCU.
• Generador de modulación de ancho de pulso (PWM) : PWM se utiliza en el
control de velocidad de motores y varias otras aplicaciones.
En Arduino así como en TODOS los microcontroladores, los timers funcionan de forma
independiente al procesador. Por lo tanto podemos hacer otros procesos mientras
esperamos a que el modulo nos avise que ha terminado su cuenta. Esto nos permite
usar, de forma más eficiente, el tiempo del microprocesaror de Arduino.
En el Arduino UNO R3, existen 3 Timers internos. El primer timer, el timer-0 es de 8
bits, el Timer-1 es de 16 bits y el Timer-2 es de 8 bits. Es decir, que pueden contar de 0
a 255 (8-bit) o de 0 a 65535 (16 bits).
Timer/Contador (cont.).
Se muestran los modos que pueden ser configurados en los registros del
microcontrolador para configurar el Timer (TM0, TM1 y TM2) en Arduino. Por otro
lado, hay librerías para la configuración de estos timers que pueden ser mucho más
fácil de programar.
Timer/Contador (cont.).
Se muestran los modos que pueden ser configurados en los registros del
microcontrolador para configurar el Timer (TM0, TM1 y TM2) en Arduino. Por otro
lado, hay librerías para la configuración de estos timers que pueden ser mucho más
fácil de programar.
Timer/Contador (cont.).
Tipos de Timers
Dado que el timer es un recurso (módulo) del microcontrolador de la tarjeta de Arduino
podremos realizar el conteo de tiempo sin la necesidad de ningún hardware externo. O
sea controlaremos el Timer en Arduino (Tiempo en Arduino).
Cada tarjeta de Arduino posee un cristal de cuarzo como elemento para generar una
señal de Reloj, por ejemplo, para el caso del Arduino UNO, MEGA, Pro Mini tenemos un
cristal de cuarzo de 16MHz. Ese cristal es el encargado de darle los tiempos de
ejecución (ticks) del programa interno del Arduino.
Timer/Contador (cont.).
El Timer se vale de ese cristal, donde teóricamente podríamos ejecutar una interrupción
cada 1/16.000.000 segundos o lo que se conoce como 1 ciclo de reloj. Cada
instrucción consume “x” ciclos de reloj, entonces tenemos que dividir este ciclo por la
frecuencia de dicho reloj. La mayoría de las instrucciones consumen un ciclo; por eso
se considera que la arquitectura AVR da (casi) 1MIPS por Mhz.
Sólo los saltos y algunas instrucciones de 16 bits necesitan más ciclos; eso es algo que
pasa en todas las arquitecturas. Sin embargo, para ejecutar las instrucciones propias
del Arduino, muchas veces consumimos más de 1 ciclo de reloj. Los Timers
disponibles en Arduino poseen un registro el cual nos dice cuántos ticks son necesarios
para disparar el timer.
Dependiendo de la placa de Arduino que poseas, tendrás disponible para tus proyectos
los siguientes Timers.
Timer 0 Arduino: Es de 8bits. Usado para las funciones delay(), millis(), micros(). Es
conveniente NO modificar este TIMER para evitar alterar estas funciones que son muy
comunes en nuestros códigos.
Timer 1 Arduino: Es de 16 bits. Usado por la librería Servo en Arduino Uno (Timer5
para Arduino Mega). Se usa principalmente para el control de Servos, sin embargo, si
no estas controlado servos, puedes usar este timer 1 Arduino libremente.
Timer 2 Arduino: Es de 8 bits. Usado en la función tone(). Si no usas este módulo,
puedes emplear el timer 2 Arduino libremente para temporizar otra aplicación.
Timer/Contador (cont.).
El Timer con Arduino está fuertemente relacionado con las Interrupciones (timer
arduino interrupt), y esto es dado a los timers 0, 1 y 2, ejecutados por medio de una
interrupción para atender alguna tarea en especifica.
La instrucción delay del Arduino dicha instrucción nos permite temporizar, sin embargo,
el problema de esa función es que BLOQUEA a la tarjeta de Arduino y debemos
esperar hasta que el tiempo del delay transcurra para poder continuar con el programa
y esto en muchos casos es INVIABLE.
La ventaja del timer en Arduino es justamente que podremos temporizar el tiempo,
cuando simultáneamente estamos realizando otra tarea con la placa de desarrollo.
En resumen, el Timer del Arduino es un Temporizador que se programa en la tarjeta de
Arduino, que se dispara en un tiempo predeterminado. Y en cada momento que este
temporizador se dispara, la tarjeta de Arduino ejecuta una función de Interrupción. Por
ejemplo, se puede programar un timer que se dispare a cada segundo, o a cada 3
segundos y así sucesivamente, para que el Arduino cumpla una tarea específica.
Timer/Contador (cont.).
Teoría común del Temporizador/Contador (cont.).
Introducción:
Los microcontroladores AVR tienen un circuito de conteo. Este circuito tiene 2 entradas y
una salida. Si se conecta la terminal Tn, contará los pulsos en sobre la terminal (esto se
conoce como contador de datos binarios). Si se le conecta al reloj interno (o externo) del
AVR, ahora tiene un temporizador. Si vincula al contador a su salida, obtendrá una señal
de modulador de ancho de pulso en el pin OCnx.
Timer/Contador (cont.).
Teoría común del Temporizador/Contador (cont.).
Cuando el componente Control Logic recibe un pulso del prescaler incrementa (o
disminuye) el registro TCNTn. El registro TCNTn se compara con el registro
OCRn. Cuando el registro TCNTn alcanza el mismo valor que el valor OCRn o el valor
SUPERIOR/INFERIOR (0xFF para registros de 8 bits y 0xFFFF para contadores de 16
bits) la lógica de control borra el registro TCNT y activa el bit TOVn (desbordamiento del
temporizador) que permanece establecido hasta es reiniciado por el usuario. La Figura 2
muestra esto en forma de gráfico.
Timer/Contador (cont.).
Teoría común del Temporizador/Contador (cont.).
La figura 2 es un poco confusa, para entenderlo se explica.
El primer gráfico (en rojo) muestra los pulsos generados por el reloj del sistema (clk).
El segundo gráfico (en azul) nos muestra los pulsos que salen del prescaler (clk_tn o clk/8). Como ejemplo, el prescaler
está configurado en 8, por lo que divide el clk (rojo) entre 8.
La tercera línea muestra el TCNTn (básicamente el recuento). El TCNTn se actualiza en el flanco descendente del
pulso que sale del preescalador. El primer pulso de preescalador (en azul), se tiene TCNTn es TOP-1 (o 254). En el
segundo pulso de prescaler (en azul) se tiene el siguiente TCNTn va a TOP (o 255). Ahora, en el tercer pulso de
preescalador (en azul), el registro TCNTn se desborda de nuevo a la PARTE INFERIOR (o 0) porque estaba en su valor
SUPERIOR en el pulso anterior. En nuestro cuarto pulso de preescalador (en azul), el registro TCNTn se incrementa
nuevamente esta vez a BOTTOM + 1 (o 1).
La cuarta línea muestra nuevamente el registro TCNTn. La única diferencia es que muestra el registro TCNTn en un
patrón PWM con corrección de fase, lo que significa que cuenta hacia arriba hasta que llega a la PARTE SUPERIOR y
luego comienza la cuenta regresiva hasta que llega a la PARTE INFERIOR. Mas detalles en el tema PWM.
La quinta línea (en verde) nos muestra el TOVn (bit de desbordamiento del temporizador). Este bit se establece la
primera vez que se desborda un temporizador. O en otras palabras, la primera vez que el temporizador pasa de su
estado SUPERIOR al siguiente estado (INFERIOR en la tercera línea o SUPERIOR -1 en la cuarta línea).
La sexta línea muestra el registro OCRnx. Este registro se ocupa del PWM. Lo único que muestra es que el registro
OCRnx solo se puede actualizar cuando ocurre una condición TOVn (desbordamiento del temporizador).
Timer/Contador (cont.).
Teoría común del Temporizador/Contador (cont.).
Prescaler:
Divide el número de pulsos de entrada. En otras palabras, el preescalador cuenta el número de pulsos
de entrada (del reloj interno o de fuentes externas) y cuando el número alcanza el número
preestablecido (0, 8, 32, 64, 128, 256 o 1024) genera un pulso propio. Esto se puede ver en la Figura
2 (arriba) que divide la entrada entre 8. Esto es necesario porque el AVR solo tiene un registro de 8
bits y uno de 16 bits y el AVR puede funcionar tan rápido como 20 Mhz. Esto significa que el
temporizador de 16 bits más grande pulsaría cada 3 ms. Pero, ¿y si queremos un temporizador de 1
segundo?, tendríamos que dividir el número de pulsos entrantes por 1024 y luego podríamos generar
un pulso de contador cada 3 segundos.
Timer/Contador (cont.).
Teoría común del Temporizador/Contador (cont.).
Pre-esscaler:
Pre-escaler para lo temporizadores 0 (2 de 8 bits) y 1 (16 bits)
Timer/Contador (cont.).
Teoría común del Temporizador/Contador (cont.).
La matemática es bastante simple:
Prescaler_output_freq = Prescaler_input_frequency / Prescaler
Y
Prescaler_output_time = Prescaler_input_time * Prescaler
Y no olvides lo viejo
Frecuencia = Periodo / Tiempo
Si un AVR opera a su velocidad máxima (20Mhz) solo podría generar un pulso cada 0.003 segundos sin
un preescalador. Voy a este número por:
Frecuencia = Período / Período de tiempo
/ Frecuencia = Tiempo
Tiempo = Período / Frecuencia
Tiempo = 16bit_register_size / System_clock_speed
Time = 0xFFFF / 20Mhz
Time = 0.00327675 s
Time = 3.27675 ms ....
Timer/Contador (cont.).
Teoría común del Temporizador/Contador (cont.).
Con el prescaler podemos generar un temporizador de hasta 3 segundos. Usando el tiempo máximo
desde arriba y la configuración máxima del preescalador de 1024.
Prescaler_output_time = Prescaler_input_time * Prescaler
Prescaler_output_time = 0.00327675 * 1024
Prescaler_output_time = 3.355392 s ... Se redondea para la contar con un tiempo aproximado
Buscando en la hoja de datos, si se encuentra y es un hecho interesante. Se recomienda que todas las
fuentes externas estén limitadas al reloj del sistema/2.5, por lo tanto, si está funcionando a la
velocidad máxima de 20Mhz, solo podrá medir de manera confiable una señal de hasta 8Mhz. El
Arduino funciona a 16Mhz, por lo tanto, estamos limitados a 6.4Mhz o menos.
Finalmente, al iniciar el preescalador, se iniciará el temporizador, por lo que recomiendo configurar los
bits del preescalador al final cuando configure su temporizador en su programa.
Timer/Contador (cont.).
Temporización
Externa
Los temporizadores 0 y 1 pueden ser manejados por señales externas, T0 y T1,
respectivamente. En estos casos se les conoce como contadores de eventos. Se
muestran detalles de cómo se realiza la sincronización y la detección del flanco (subida o
bajada), la etapa de sincronización asegura una señal estable a la etapa de detección de
flanco, la cual se encarga de generar un pulso limpio cuando ocurre el flanco
seleccionado. La presencia de estos módulos hace necesario que la frecuencia de los
eventos externos esté limitada por fclk_I/O/2.5.
Acondicionamiento de las señales externas, para los temporizadores 0 y 1
Timer/Contador (cont.).
Temporización
Externa
El temporizador 2 también puede ser manejado por una señal externa, pero en este caso,
se utiliza un oscilador externo que no se sincroniza con el oscilador interno (es asíncrono).
El hardware se ha optimizado para ser manejado con un cristal de 32.768 KHz, esta
frecuencia es adecuada para que, en combinación con el pre-escalador, se puedan
generar fracciones o múltiplos de segundos. En la figura 4.9 se muestra cómo es posible
seleccionar entre un oscilador externo o la señal de reloj interna.
Uso de un Oscilador externo para el temporizador 2
La ventaja principal de un oscilador asíncrono para el temporizador 2 es que trabaja con una frecuencia
independiente al resto del sistema, la cual es adecuada para manejar un reloj de tiempo real. Sin
mucho esfuerzo, se puede realizar un reloj con displays de 7 segmentos y botones de configuración, de
manera qué, mientras el temporizador 2 lleva el conteo de segundos, el resto del sistema está
manejando a los elementos de visualización o sondeando los botones a una frecuencia mucho más
Timer/Contador (cont.).
Teoría común del Temporizador/Contador (cont.).
TEORÍA DE OPERACIÓN:
Una revisión rápida del tutorial anterior ( TEMPORIZADOR COMÚN / TEORÍA DEL
CONTADOR ). La fuente de reloj (desde el reloj interno o una fuente externa) envía
pulsos al pre-escalador que divide los pulsos por una cantidad determinada. Esta
entrada se envía al circuito de control que incrementa el registro TCNTn. Cuando el
registro alcanza su valor TOP, se restablece a 0 y envía una
señal
TOVn (desbordamiento del temporizador) que podría usarse para activar una
interrupción.
El temporizador AVR procesa el tiempo en horas, minutos o segundos (a lo que
estamos acostumbrados). Sin embargo, siendo los autores intelectuales malvados
tenemos la solución, solo requiere un poco de matemáticas y nuestro viejo amigo, el
pre-escalador.
OCRn =
[(clock_speed / Prescaler_value) * Desired_time_in_Seconds] – 1
En los registros, OCRn tiene que ser un número entero. Si termina con un número
decimal, significa que su temporizador deseado no será exacto. La otra cosa es que
su número debe poder caber en el registro. Entonces 255 para un temporizador de 8
bits y 65535 para el temporizador de 16 bits.
Timer/Contador (cont.).
Teoría común del Temporizador/Contador (cont.).
TEORÍA DE OPERACIÓN: (cont.).
Modo normal:
Cuando el preescalador recibe un pulso de un ciclo de reloj y lo pasa a la lógica de
control. La lógica de control incrementa el registro TCNTn en 1. Cuando TCNTn llega a
TOP (0xFF en los temporizadores de 8 bits y 0xFFFF en el temporizador de 16 bits) se
desborda a 0 y establece el bit TOVn en el registro TIFR.
El problema con el modo normal es que es muy difícil de usar para un intervalo
exacto, debido a que este modo normal solo es útil si necesita un intervalo de tiempo
no específico (digamos que no le importa si ocurre cada 1 o 2 ms siempre que suceda
a la misma hora cada vez) es una opción agradable y fácil. Debido a esta limitación,
muchos programadores optan por utilizar el modo CTC para sus temporizadores.
Modo CTC:
CTC significa "Clear Timer on Compare" y hace lo siguiente. Cuando el preescalador
recibe un pulso de un ciclo de reloj y lo pasa a la lógica de control. La lógica de control
incrementa el registro TCNTn en 1. El registro TCNTn se compara con el registro
OCRn, cuando se produce una coincidencia de comparación, el bit TOVn se establece
en el registro TIFR.
Timer/Contador (cont.).
Teoría común del Temporizador/Contador (cont.).
TEORÍA DE OPERACIÓN: (cont.).
Modo Fast PWM: Este modo permite generar una onda PWM de alta frecuencia. El
timer cuenta desde 0 a 255 y reinicia la cuenta. Con cada cuenta el valor del timer0 se
compara con un valor determinado que cuando coinciden cambia el estado de uno de
los pines de salida PWM, y cuando se reinicia el timer este pin vuelve a cambiar su
estado
Modo Phase Correct PWM: Este modo ofrece una onda PWM de alta resolución a
diferencia del modo Fast PWM. El timer cuenta hacia adelante y hacia atrás antes de
hacer el cambio de estado del pin PWM, es decir cuenta de 0 a 255 al llegar a 255
cuenta de 255 a 0, obteniendo una salida PWM más limpia pero de menor frecuencia.
Timer/Contador (cont.).
Teoría común del Temporizador/Contador (cont.).
TEORÍA DE OPERACIÓN: (cont.).
TEMPORIZADOR 0 (8BIT PWM):
Figura 1: Timer0 en el ATmega328
Timer/Contador (cont.).
Teoría común del Temporizador/Contador (cont.).
TEORÍA DE OPERACIÓN: (cont.).
A diferencia del ATmega8, el Timer0 del ATmega168 / 328 tiene un registro OCR0, por lo que es
capaz de funcionar en modo normal y CTC.
TOV0 puede generar una interrupción de desbordamiento del temporizador. Para activar las
interrupciones del timer0 es necesario FIJAR (1) el bit TOIE0 dentro del registro TIMSK.
Timer/Contador (cont.).
Teoría común del Temporizador/Contador (cont.).
TEORÍA DE OPERACIÓN: (cont.).
Timer/Contador (cont.).
Teoría común del Temporizador/Contador (cont.).
TEORÍA DE OPERACIÓN: (cont.).
Registro de configuración de interrupción. En nuestro caso lo usaremos con todos los
bits en 0 menos el bit OCIEnA que deberá estar en 1 para indicarle a nuestro timer
que usaremos el registro OCRnA para comparar.
Timer/Contador (cont.).
Teoría común del Temporizador/Contador (cont.).
TEORÍA DE OPERACIÓN: (cont.).
Timer/Contador (cont.).
Teoría común del Temporizador/Contador (cont.).
TEORÍA DE OPERACIÓN: (cont.).
Timer/Contador (cont.).
Timer/Contador (cont.).
Fuentes de Reloj Externa
Fuentes de Reloj para temporizador/Contador.
Timer/Contador (cont.).
Temporizador 0 Conceptos básicos
El temporizador 0 es un temporizador de 8 bits. Básicamente significa que
puede contar de 0 a 28=255. El funcionamiento del temporizador 0 es
sencillo. El registro TCNT0 retiene la cuenta del temporizador y se
incrementa en cada ciclo de reloj del temporizador. Si el temporizador
está encendido, cuenta de 0 a 255 y se desborda. Si lo hace, se establece
un indicador de desbordamiento del temporizador a la bandera de
sobreflujo (TOV) que indica un requerimiento de interrupción.
Timer/Contador (cont.).
También puede cargar un valor de recuento en TCNT0 e iniciar el temporizador desde
un recuento específico. Otra característica interesante es que se puede establecer un
valor en el registro de comparación de salida (OCR0: OCR0A y OCR0B), y siempre que
TCNT0 alcanza ese valor, se establece el indicador de comparación de salida (OCF0).
La configuración del temporizador se puede establecer utilizando el registro TCCR0B
que se muestra a continuación. Con esto, básicamente puedes seleccionar dos cosas:
1. La frecuencia de la fuente de reloj con bits CS02, CS01, CS00.
2. El modo del temporizador. Para el primer ejemplo lo usaremos en modo normal
donde marca de cero al valor más alto (255)
B
Timer/Contador (cont.).
Descripción de los Bits de selección de fuente de reloj para el temporizador/contador 0.
Timer/Contador (cont.).
El Registro de indicadores de interrupción del temporizador / contador (TIFR)
contiene los dos indicadores básicos que necesitamos: TOV y OVF. Otros bits
corresponden a las interrupciones del temporizador, que veremos en otro tutorial.
Timer/Contador (cont.).
Timer/Contador (cont.).
Ejemplo de temporizador 0
Alternar LED conectado a PD4 cada 100 ms usando Timer Zero con 1024 preescalar en modo normal.
¿Qué es el desbordamiento del temporizador de retardo máximo 0 que genera?
La placa de desarrollo Explore Ultra AVR viene con un cristal a bordo de 16MHz y los bits de los
fusibles están configurados apropiadamente. Si usamos el preescalar más alto de 1024, el cálculo
muestra que puede generar un retraso de 16 mili segundos cada vez que el temporizador cero se
desborda.
$$ Ftimer = Frecuencia de CPU / Prescalar $$ $$ Ftimer = 16MHz / 1024 = 15.625KHz $$ $$ Ttick
= 1 / 15.625K = 64 \ mu segundos $$ $$ Ttotal = 64 \ mu s X 255 = 16ms $ PS
Por supuesto, 16 ms no es suficiente, por lo que la siguiente pregunta obvia es:
¿cuántas veces debería desbordarse el temporizador para generar un retraso de
aproximadamente 100 ms?
$$ OverFlowCount = 100ms / 16ms = 6.25 ≈ 6 $$
Timer/Contador (cont.).
Ahora escribamos un programa simple que alternará un pin de puerto (PD4) después de
que el temporizador 0 se desborde 6 veces.
1. Cargar TCNT0 con 0x00
2. Configure los bits CS00 y CS02 en el registro TCCR0. Esto iniciará el tiempo.
Calcularemos el tiempo de tick en solo un momento. R a una velocidad de Clk /
1024.
3. Monitoree la bandera TOV0 en el registro TIFR0 para verificar si el temporizador se
ha desbordado, mantenga un timerOverFlowCount.
4. Si timerOverFlowCount> = 6, alternar el LED en PD4 y restablecer el conteo
# incluye < avr / io.h >
# definir LED PD4
int main ()
{
uint8_t timerOverflowCount = 0 ;
DDRD = 0xff ; // configurar PORTD como salida
TCNT0 = 0x00 ;
TCCR0 = ( 1 << CS00) | ( 1 << CS02);
mientras ( 1 )
{
while ((TIFR & 0x01 ) == 0 );
TCNT0 = 0x00 ;
TIFR = 0x01 ; // borra el indicador de desbordamiento del temporizador1
timerOverflowCount ++;
si (timerOverflowCount> = 6 )
{
PORTD ^ = ( 0x01 << LED);
timerOverflowCount = 0 ;
}
}
}
Timer/Contador (cont.).
Conceptos básicos del temporizador 1
El temporizador 1 es de 16 bits, lo que significa que puede contar de 0 a $$ 2 ^ {16} =
65536 $$.
Por lo tanto, el temporizador / contador 1 es un registro de 16 bits formado por TCNT1H
y TCNT1L, como se muestra a continuación.
El temporizador 3 también dispone de 2 registros de control que nos permiten
configurarlo y utilizarlo en cualquier modo que deseemos.
Timer/Contador (cont.).
Timer/Contador (cont.).
Sí, y de hecho tenemos un registro de bandera que nos dirá el estado del temporizador
1 como se muestra a continuación.
Ejemplo del temporizador 1
Repitamos el ejemplo del temporizador 0 de alternar PD4 cada 100 ms. Esta vez, dado que es
un temporizador de 16 bits, veamos cuál es el retraso máximo que genera con un preescalar
de 1024.
$$ Ftimer = Frecuencia de CPU / Prescalar $$ $$ Ftimer = 16MHz / 1024 = 15.625KHz $$ $$ Ttick =
1 / 15.625K = 64 \ mu segundos $$ $$ Ttotal = 64 \ mu s X 65536 = 4 segundos $$
Eso es 4 segundos! Solo necesitamos 100 mseg, entonces $$ 100ms / 64 \ mu s = 1562 = 0x061A
$$
Timer/Contador (cont.).
Esta vez, en lugar de usar el indicador de desbordamiento, se usa el Registro de comparación de
salida (OCR) y el indicador relacionado.
Entonces, con los siguientes pasos deberíamos poder generar el retraso requerido.
1. Cargue OCR1H con 0x3d y OCR1L con 0x09
2. Ejecute el temporizador con preescalar de 1024 configurando los bits CS12 y CS10.
3. Monitorear la bandera OCF y si está configurada, alternar el led
4. Restablezca los valores TCNT1L y TCNT1H a cero y repita los pasos 1 a 3.
/
*
| Parte de ejemplo de la serie de tutoriales AVR @ Explore Embedded
| Para leer el tutorial detallado, visite:
| http://exploreembedded.com/wiki/5.AVR_Timer_programming
*/
# incluye < avr / io.h >
# incluye < util / delay.h >
# definir LED PD4
int main ()
{
DDRD | = ( 1 << LED); // configurar led como salida
TCCR1B = ( 1 << CS10) | ( 1 << CS12); // establece el pre-escalar como
1024
OCR1A = 1562 ; // Retraso de 100 ms
TCNT1 = 0 ;
mientras ( 1 )
{
// Si la bandera está configurada, alternar el led
while ((TIFR & ( 1 << OCF1A)) == 0 ); // espere hasta que la bandera de
desbordamiento del temporizador esté SET
PORTD ^ = ( 1 << LED);
TCNT1 = 0 ;
TIFR | = ( 1 << OCF1A); // borra el indicador de desbordamiento del
temporizador1
Timer/Contador (cont.).
Temporizador 2
Bueno, el temporizador 2 es bastante similar a los temporizadores mencionados
anteriormente. Pruébelo, si tiene alguna pregunta, comente a continuación.
Los temporizadores son unidades independientes de la CPU. Por lo tanto, si usamos
temporizadores con interrupciones, puede hacer que la CPU no tenga que sondear las
banderas cada vez. Esta es la forma en que se utilizan normalmente. Consulte
el tutorial de interrupciones del temporizador de AVR, donde cubriremos todo eso.
La función Arduino timer no esta implementada en el lenguaje de forma estándar. Un
Timer genera interrupciones para ejecutar funciones sin involucrar al procesador. Por
lo general se utilizan librerías externas para poder implementar en Arduino timer y no
existe una librería oficial. Esto se debe a las funciones: millis(), micros(), delay(),
Servo y Tone que usan a los timers del microcontrolador.
Timer/Contador (cont.).
Timer/Contador (cont.).
Descargar
Colecciones de estudio