Tabla de contenido:

Microcontrolador AVR. Intermitente de LED con temporizador. Interrupciones de temporizadores. Modo CTC del temporizador: 6 pasos
Microcontrolador AVR. Intermitente de LED con temporizador. Interrupciones de temporizadores. Modo CTC del temporizador: 6 pasos

Video: Microcontrolador AVR. Intermitente de LED con temporizador. Interrupciones de temporizadores. Modo CTC del temporizador: 6 pasos

Video: Microcontrolador AVR. Intermitente de LED con temporizador. Interrupciones de temporizadores. Modo CTC del temporizador: 6 pasos
Video: 07 ATmega328 AVR-C Ejemplos con temporizadores (timers) 2024, Mes de julio
Anonim
Image
Image

¡Hola, todos!

Los temporizadores son un concepto importante en el campo de la electrónica. Cada componente electrónico funciona en una base de tiempo. Esta base de tiempo ayuda a mantener todo el trabajo sincronizado. Todos los microcontroladores funcionan a una frecuencia de reloj predefinida, todos tienen una provisión para configurar temporizadores. AVR se jacta de tener un temporizador que es muy preciso, preciso y confiable. Ofrece un montón de funciones, por lo que es un tema muy amplio. La mejor parte es que el temporizador es totalmente independiente de la CPU. Por lo tanto, se ejecuta en paralelo a la CPU y no hay intervención de la CPU, lo que hace que el temporizador sea bastante preciso. En esta sección explico los conceptos básicos de los temporizadores AVR. Estoy escribiendo un programa simple en código C para controlar el intermitente LED, usando temporizadores.

Paso 1: descripción

Enunciado del problema 1: Primero parpadeemos el LED (verde) cada 50 ms
Enunciado del problema 1: Primero parpadeemos el LED (verde) cada 50 ms

En ATMega328 hay tres tipos de temporizadores:

Timer / Counter0 (TC0): es un módulo de temporizador / contador de 8 bits de uso general, con dos unidades OutputCompare independientes y compatibilidad con PWM;

Temporizador / Contador1 (TC1): la unidad Temporizador / Contador de 16 bits permite una sincronización precisa de la ejecución del programa (gestión de eventos), generación de ondas y medición de la sincronización de la señal;

Timer / Counter2 (TC2): es un módulo de temporizador / contador de 8 bits de canal de uso general con PWM y operación asincrónica;

Paso 2: Enunciado del problema 1: Primero parpadeemos el LED (verde) cada 50 ms

Enunciado del problema 1: Primero parpadeemos el LED (verde) cada 50 ms
Enunciado del problema 1: Primero parpadeemos el LED (verde) cada 50 ms
Enunciado del problema 1: Primero parpadeemos el LED (verde) cada 50 ms
Enunciado del problema 1: Primero parpadeemos el LED (verde) cada 50 ms

Metodología:

- usar un preescalador Timer0 para reducir una señal eléctrica de alta frecuencia a una frecuencia más baja por división de enteros;

- usando una interrupción cada vez que el Timer0 se desborda;

Timer0 (8 bit) cuenta de 0 a 255 después de eso, se desbordan, este valor cambia en cada pulso del reloj.

F_CPU = 16MHz: período de tiempo del reloj = 1000ms / 16000000Hz = 0.0000625ms

Conteo del temporizador = (Retardo requerido / Período de tiempo del reloj) -1 = (50ms / 0.0000625ms) = 799999

¡El reloj ya ha marcado 799999 veces para dar un retraso de solo 50 ms!

Podemos usar la técnica de división de frecuencia que se llama preescalado para disminuir el conteo del temporizador. El AVR nos ofrece los siguientes valores de preescalador para elegir: 8, 64, 256 y 1024. Consulte la tabla que resume los resultados de usar diferentes preescaladores.

El valor del contador siempre debe ser un número entero. ¡Elija un prescaler 256!

En la mayoría de los microcontroladores, hay algo llamado Interrupción. Esta interrupción puede dispararse siempre que se cumplan determinadas condiciones. Ahora, cada vez que se dispara una interrupción, el AVR se detiene y guarda su ejecución de la rutina principal, atiende la llamada de interrupción (ejecutando una rutina especial, llamada Rutina de servicio de interrupción, ISR) y una vez que termina con ella, vuelve a la rutina principal y continúa ejecutándola.

Dado que el retardo requerido (50ms) es mayor que el retardo máximo posible: 4, 096ms = 1000ms / 62500Hz * 256, obviamente el temporizador se desbordará. Y cada vez que el temporizador se desborda, se dispara una interrupción.

¿Cuántas veces se debe disparar la interrupción?

50ms / 4.096ms = 3125/256 = 12.207 Si el temporizador se ha desbordado 12 veces, habrían pasado 12 * 4.096ms = 49.152ms. En la decimotercera iteración, necesitamos un retraso de 50 ms - 49,152 ms = 0,848 ms.

A una frecuencia de 62500Hz (preescaler = 256), cada tick tarda 0.016ms. Por lo tanto, para lograr un retraso de 0,848 ms, se necesitarían 0,848 ms / 0,016 ms = 53 tics. Por lo tanto, en la decimotercera iteración, solo permitimos que el temporizador cuente hasta 53 y luego lo restablecemos.

Inicializar Timer0 / Contador (ver foto):

TCCR0B | = (1 << CS02) // configurar temporizador con prescaler = 256 TCNT0 = 0 // inicializar contador TIMSK0 | = (1 << TOIE0) // habilitar interrupción de desbordamiento sei () // habilitar interrupciones globales tot_overflow = 0 // inicializar la variable del contador de desbordamiento

Paso 3: Enunciado del problema 2: Hagamos parpadear el segundo LED (azul) cada 1 s

Enunciado del problema 2: Hagamos parpadear el segundo LED (azul) cada 1 s
Enunciado del problema 2: Hagamos parpadear el segundo LED (azul) cada 1 s
Enunciado del problema 2: Hagamos parpadear el segundo LED (azul) cada 1 s
Enunciado del problema 2: Hagamos parpadear el segundo LED (azul) cada 1 s
Enunciado del problema 2: Hagamos parpadear el segundo LED (azul) cada 1 s
Enunciado del problema 2: Hagamos parpadear el segundo LED (azul) cada 1 s

Metodología:

- usar un preescalador Timer1 para reducir una señal eléctrica de alta frecuencia a una frecuencia más baja por división de enteros;

- usando el modo Clear Timer on Compare (CTC);

- uso de interrupciones con modo CTC;

Timer1 (16 bits) cuenta de 0 a 65534 después de eso, se desbordan. Este valor cambia con cada pulso de reloj.

F_CPU = 16MHz: Período de tiempo del reloj = 1000ms / 16000000Hz = 0.0000625ms Conteo del temporizador = (Retardo requerido / Período de tiempo del reloj) -1 = (1000ms / 0.0000625ms) = 15999999

¡El reloj ya ha marcado 15999999 veces para dar un retraso de 1 s!

Podemos usar la técnica de división de frecuencia que se llama preescalado para disminuir el conteo del temporizador. El AVR nos ofrece los siguientes valores de preescalador para elegir: 8, 64, 256 y 1024. Consulte la tabla que resume los resultados de usar diferentes preescaladores. El valor del contador siempre debe ser un número entero. ¡Elija un prescaler 256!

En el modo Clear timer on Compare (CTC), el registro OCR1A o ICR1 se utiliza para manipular la resolución del contador. En el modo CTC, el contador se pone a cero cuando el valor del contador (TCNT1) coincide con el OCR1A o el ICR1. El OCR1A o ICR1 definen el valor superior para el contador, de ahí también su resolución. Este modo permite un mayor control de la frecuencia de salida de la comparación. También simplifica la operación de contar eventos externos. Debemos decirle al AVR que resetee el Timer1 / Contador tan pronto como su valor alcance el valor 62500, para así lograr un retardo de 1s.

Inicializar Timer1 / Contador (ver foto):

TCCR1B | = (1 << WGM12) | (1 << CS12) // configurar temporizador con prescaler = 256 y modo CTC TCNT1 = 0 // inicializar contador TIMSK1 | = (1 << OCIE1A) // habilitar interrupción de comparación OCR1A = 62500 // inicializar el valor de comparación

Paso 4: Enunciado del problema 3: Hagamos parpadear el tercer LED (rojo) cada 16 ms

Enunciado del problema 3: Hagamos parpadear el tercer LED (rojo) cada 16 ms
Enunciado del problema 3: Hagamos parpadear el tercer LED (rojo) cada 16 ms
Enunciado del problema 3: Hagamos parpadear el tercer LED (rojo) cada 16 ms
Enunciado del problema 3: Hagamos parpadear el tercer LED (rojo) cada 16 ms
Enunciado del problema 3: Hagamos parpadear el tercer LED (rojo) cada 16 ms
Enunciado del problema 3: Hagamos parpadear el tercer LED (rojo) cada 16 ms
Enunciado del problema 3: Hagamos parpadear el tercer LED (rojo) cada 16 ms
Enunciado del problema 3: Hagamos parpadear el tercer LED (rojo) cada 16 ms

Metodología:

- usar un preescalador Timer2 para reducir una señal eléctrica de alta frecuencia a una frecuencia más baja por división de enteros;

- usando el modo Clear Timer on Compare (CTC);

- uso del modo CTC de hardware sin interrupciones;

Timer2 (8 bits) cuenta de 0 a 255 después de eso, se desbordan. Este valor cambia con cada pulso de reloj.

F_CPU = 16MHz: Período de tiempo del reloj = 1000ms / 16000000Hz = 0.0000625ms

Conteo del temporizador = (Retardo requerido / Período de tiempo del reloj) -1 = (16ms / 0.0000625ms) = 255999

¡El reloj ya ha marcado 255999 veces para dar un retraso de 16 ms!

Consulte la tabla que resume los resultados del uso de diferentes preescaladores. El valor del contador siempre debe ser un número entero. ¡Elija un prescaler 1024!

En el modo CTC, el contador se pone a cero cuando el valor del contador (TCNT2) coincide con el OCR2A o el ICR2. El pin PB3 es también el pin de comparación de salida de TIMER2 - OC2A (ver diagrama).

Temporizador / Contador2 Registro de control A - TCCR2A Bit 7: 6 - COM2A1: 0 - Modo de salida de comparación para la unidad de comparación A. Dado que necesitamos alternar el LED, elegimos la opción: Alternar OC2A en comparación de coincidencias Siempre que ocurra una comparación de coincidencias, la El pin OC2A se alterna automáticamente. No es necesario comprobar ningún bit de bandera, no es necesario atender a las interrupciones.

Inicializar Timer2 / Contador

TCCR2A | = (1 << COM2A0) | (1 << WGM21) // configura el pin OC2A del temporizador en modo de alternancia y modo CTC TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20) // configurar el temporizador con prescaler = 1024 TCNT2 = 0 // inicializar el contador OCR2A = 250 // inicializar el valor de comparación

Paso 5: Escribir código para un programa en C. Cargar archivo HEX en la memoria flash del microcontrolador

Escribir código para un programa en C. Cargar archivo HEX en la memoria flash del microcontrolador
Escribir código para un programa en C. Cargar archivo HEX en la memoria flash del microcontrolador
Escribir código para un programa en C. Cargar archivo HEX en la memoria flash del microcontrolador
Escribir código para un programa en C. Cargar archivo HEX en la memoria flash del microcontrolador

Escribiendo y construyendo la aplicación del microcontrolador AVR en Código C usando la Plataforma de Desarrollo Integrada - Atmel Studio.

F_CPU define la frecuencia de reloj en hercios y es común en programas que usan la biblioteca avr-libc. En este caso, las rutinas de retardo lo utilizan para determinar cómo calcular los retardos de tiempo.

#ifndef F_CPU

#define F_CPU 16000000UL // indicando la frecuencia del cristal del controlador (16 MHz AVR ATMega328P) #endif

#include // encabezado para permitir el control del flujo de datos sobre los pines. Define pines, puertos, etc.

El primer archivo de inclusión es parte de avr-libc y se utilizará en prácticamente cualquier proyecto AVR en el que trabaje. io.h determinará la CPU que estás usando (por eso especificas la parte al compilar) y, a su vez, incluirá el encabezado de definición de E / S apropiado para el chip que estamos usando. Simplemente define las constantes para todos sus pines, puertos, registros especiales, etc.

#include // encabezado para habilitar la interrupción

volátil uint8_t tot_overflow; // variable global para contar el número de desbordamientos

Metodología del planteamiento del problema: primer LED parpadeante (verde) cada 50 ms

- usar un preescalador Timer0 para reducir una señal eléctrica de alta frecuencia a una frecuencia más baja por división de enteros;

- usando una interrupción cada vez que el Timer0 se desborda;

void timer0_init () // inicializa timer0, interrupción y variable

{TCCR0B | = (1 << CS02); // configurar el temporizador con prescaler = 256 TCNT0 = 0; // inicializar el contador TIMSK0 | = (1 << TOIE0); // habilita el desbordamiento nterrupt sei (); // habilitar interrupciones globales tot_overflow = 0; // inicializar la variable del contador de desbordamiento}

Metodología del planteamiento del problema: segundo LED parpadeante (azul) cada 1 s

- usar un preescalador Timer1 para reducir una señal eléctrica de alta frecuencia a una frecuencia más baja por división de enteros;

- usando el modo Clear Timer on Compare (CTC);

- uso de interrupciones con modo CTC;

void timer1_init () // inicializa timer1, interrupción y variable {TCCR1B | = (1 << WGM12) | (1 << CS12); // configurar el temporizador con prescaler = 256 y modo CTC TCNT1 = 0; // inicializar el contador OCR1A = 62500; // inicializar el valor de comparación TIMSK1 | = (1 << OCIE1A); // habilitar la interrupción de comparación}

Metodología del planteamiento del problema: parpadea el tercer LED (rojo) cada 16 ms

- usar un preescalador Timer2 para reducir una señal eléctrica de alta frecuencia a una frecuencia más baja por división de enteros;

- usando el modo Clear Timer on Compare (CTC);

- usando el modo CTC de hardware sin interrupciones;

void timer2_init () // inicializar timer2 {TCCR2A | = (1 << COM2A0) | (1 << WGM21); // configura el pin OC2A del temporizador en modo alternar y modo CTC TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20); // configurar el temporizador con prescaler = 1024 TCNT2 = 0; // inicializar el contador OCR2A = 250; // inicializar el valor de comparación}

Se llama a la rutina de servicio de interrupción de desbordamiento TIMER0 siempre que TCNT0 se desborda:

ISR (TIMER0_OVF_vect)

{tot_overflow ++; // realiza un seguimiento del número de desbordamientos}

Este ISR se activa cada vez que se produce una coincidencia, por lo tanto, alternar el led aquí mismo:

ISR (TIMER1_COMPA_vect) {PORTC ^ = (1 << 1); // alternar led aquí}

int main (vacío)

{DDRB | = (1 << 0); // conecta 1 (verde) led al pin PB0 DDRC | = (1 << 1); // conecta el led 2 (azul) al pin PC1 DDRB | = (1 << 3); // conecta el led 3 (rojo) al pin PB3 (OC2A) timer0_init (); // inicializar timer0 timer1_init (); // inicializar timer1 timer2_init (); // inicializar timer2 while (1) // bucle para siempre {

Si el Timer0 se ha desbordado 12 veces, habrían pasado 12 * 4.096ms = 49.152ms. En la decimotercera iteración, necesitamos un retraso de 50 ms - 49,152 ms = 0,848 ms. Por lo tanto, en la decimotercera iteración, solo permitimos que el temporizador cuente hasta 53 y luego lo restablecemos.

if (tot_overflow> = 12) // comprobar si no. of overflows = 12 NOTA: se utiliza '> ='

{if (TCNT0> = 53) // comprobar si el contador de tiempo llega a 53 {PORTB ^ = (1 << 0); // alterna el led TCNT0 = 0; // poner a cero el contador tot_overflow = 0; // restablecer el contador de desbordamiento}}}}

Carga del archivo HEX en la memoria flash del microcontrolador:

escriba en la ventana del símbolo del sistema de DOS el comando:

avrdude –c [nombre del programador] –p m328p –u –U flash: w: [nombre de su archivo hexadecimal] En mi caso es: avrdude –c ISPProgv1 –p m328p –u –U flash: w: Timers.hex

Este comando escribe un archivo hexadecimal en la memoria del microcontrolador. Vea el video con una descripción detallada de la grabación de la memoria flash del microcontrolador:

Grabación de memoria flash del microcontrolador …

¡OK! Ahora, el microcontrolador funciona de acuerdo con las instrucciones de nuestro programa. ¡Vamos a ver!

Paso 6: Hacer el circuito eléctrico

Haciendo el circuito eléctrico
Haciendo el circuito eléctrico
Haciendo el circuito eléctrico
Haciendo el circuito eléctrico
Haciendo el circuito eléctrico
Haciendo el circuito eléctrico

Conecte los componentes de acuerdo con el diagrama esquemático.

Recomendado: