ATmega328P: Módulo Timer/Counter

Contenido:

Módulo Timer/Counter del ATmega328P

El ATmega328P cuenta con tres módulo Timer/Counter (TC), que proporcionan varias funciones como temporización, conteo de eventos externos y generación de señales PWM. A continuación, se describen brevemente las características de cada uno de ellos:

  • Timer/Counter0 (TC0): Este módulo tiene dos modos de operación. En el modo temporizador, se puede configurar para generar una interrupción en un valor preestablecido de tiempo o para contar eventos externos. En el modo PWM, se puede generar una señal PWM en cualquiera de los pines OC0A o OC0B.
  • Timer/Counter1 (TC1): Este módulo es más complejo que el TC0 y puede funcionar en cuatro modos diferentes. En el modo temporizador, se puede configurar para generar una interrupción en un valor preestablecido de tiempo o para contar eventos externos.
    En los modos de captura de entrada, se pueden medir pulsos externos. En el modo comparador, se puede generar una señal de salida en cualquiera de los pines OC1A o OC1B. En el modo PWM, se puede generar una señal PWM en cualquiera de los pines OC1A o OC1B.
  • Timer/Counter2 (TC2): Este módulo es similar al TC0, pero solo tiene modo temporizador y PWM. Se puede configurar para generar una interrupción en un valor preestablecido de tiempo o para contar eventos externos en el modo temporizador. En el modo PWM, se puede generar una señal PWM en cualquiera de los pines OC2A o OC2B.

En general, los módulos Timer/Counter son muy útiles para aplicaciones que requieren temporización precisa, conteo de eventos externos y generación de señales PWM.

✅ Si quieres conocer la descripción de cada uno de los registros, además de varios ejemplos adicionales de los que encontrarás en este post, te invito a que adquieras la 🔥 Guía de Programación mediante registros del Microcontrolador ATmega328P 🔥 dando clic ⭐ aquí ⭐. Adicionalmente recibirás los sketch de Arduino IDE y de Microchip Studio, incluyendo los archivos de simulación en Proteus Profesional v8.10.

Video Tutorial

Ejemplo 1: Usar el Timer/Counter0 como contador de eventos externos (pulsos generados por el botón) y mostrar el resultado en el Puerto C y D.

Arduino:

at328p timer ejm1 1
Figura 1: Circuito con Arduino para el Ejemplo 1 del Módulo Timer/Counter.
uint8_t salida; // Declaracion de Variable

void setup() {
  DDRC = 0b11111111; // Puerto C: [5:0] Salidas
  DDRD = 0b00001100; // Puerto D: [3:2] Salidas
  PORTC = 0b00000000; // Salidas en LOW
  PORTD = 0b00000000; // Salidas en LOW
  TCCR0A = 0b00000000; // [7:6] OC0A Desabilitado, [5:4] OC0B Desabilitado, [1:0] Operacion normal
  TCCR0B = 0b00000111; // [2:0] Fuente de reloj ascendente externa en el Pin TO
  TCNT0 = 0b00000000; // Contador del timer comienza en 0
  _delay_ms(10);
}

void loop() {
  salida = TCNT0; // Coloco el valor del registro en la variable
  PORTC = (salida & 0b00111111); // Escribo los 6 primeros bits en el Puerto C
  PORTD = (salida & 0b11000000) >> 4; // Escribo los 2 bits restantes en el Puerto D
  _delay_ms(200); // Retardo 200ms
}

Lenguaje C:

at328p timer ejm1 2
Figura 2: Circuito con ATmega328P para el Ejemplo 1 del Módulo Timer/Counter.
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

uint8_t salida; // Declaracion de Variable

int main(void){
	DDRC = 0b11111111; // Puerto C: [5:0] Salidas
	DDRD = 0b00001100; // Puerto D: [3:2] Salidas
	PORTC = 0b00000000; // Salidas en LOW
	PORTD = 0b00000000; // Salidas en LOW
	TCCR0A = 0b00000000; // [7:6] OC0A Desabilitado, [5:4] OC0B Desabilitado, [1:0] Operacion normal
	TCCR0B = 0b00000111; // [2:0] Fuente de reloj ascendente externa en el Pin TO
	TCNT0 = 0b00000000; // Contador del timer comienza en 0
	_delay_ms(10);
	while (1){
		salida = TCNT0; // Coloco el valor del registro en la variable
		PORTC = (salida & 0b00111111); // Escribo los 6 primeros bits en el Puerto C
		PORTD = (salida & 0b11000000) >> 4; // Escribo los 2 bits restantes en el Puerto D
		_delay_ms(200); // Retardo 200ms
	}
}

Ejemplo 2: Mediante el Timer/Counter0 hacer parpadear un led cada 50ms.

Siendo la frecuencia del dispositivo de 16MHz, utilizando el preescaler de 1024 se obtiene un periodo de 64us, al contabilizar 157 periodos se obtiene un tiempo de 10ms, utilizando un contador, el cual incrementa su valor cada 10ms, al llegar a 5 conteos habrá transcurrido 50ms, con ello el led parpadea según el tiempo requerido.

timercounter ejemplo2 calculo
Figura 3: Cálculo de condiciones.

Arduino:

at328p timer ejm2 1
Figura 4: Circuito con Arduino para el Ejemplo 2 del Módulo Timer/Counter.
uint8_t contador = 0;

void setup() {
  DDRD = 0b10000000; // Puerto D: [7] Salida
  PORTD = 0b00000000; // Salida en Bajo
  TCCR0A = 0b00000000; // [7:6] OC0A Desabilitado, [5:4] OC0B Desabilitado, [1:0] Operacion normal
  TCCR0B = 0b00000101; // [2:0] Preescaler 1024
  TCNT0 = 0b00000000; // Contador del timer comienza en 0
  _delay_ms(10);
}

void loop() {
  if (TCNT0 == 157) { // Si el valor del Timer es 157
    contador++; // Incrementa la variable
    TCNT0 = 0b00000000; // Contador del timer se reinicia
  }
  if (contador == 5) { // Si la variable es 5
    contador = 0; // La variable se reinicia
    PORTD ^= 0b10000000; // La salida cambia de estado
  }
}

Lenguaje C:

at328p timer ejm2 2
Figura 5: Circuito con ATmega328P para el Ejemplo 2 del Módulo Timer/Counter.
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

uint8_t contador = 0; // Declaracion de Variable

int main(void){
	DDRD = 0b10000000; // Puerto D: [7] Salida
	PORTD = 0b00000000; // Salida en Bajo
	TCCR0A = 0b00000000; // [7:6] OC0A Desabilitado, [5:4] OC0B Desabilitado, [1:0] Operacion normal
	TCCR0B = 0b00000101; // [2:0] Preescaler 1024
	TCNT0 = 0b00000000; // Contador del timer comienza en 0
	_delay_ms(10);
	while (1){
		if (TCNT0 == 157) { // Si el valor del Timer es 157
			contador++; // Incrementa la variable
			TCNT0 = 0b00000000; // Contador del timer se reinicia
		}
		if (contador == 5) { // Si la variable es 5
			contador = 0; // La variable se reinicia
			PORTD ^= 0b10000000; // La salida cambia de estado
		}
	}
}

Ejemplo 3: Mediante el Timer/Counter0 configurado en Modo Output-Compare hacer parpadear un led a una frecuencia de 1kHz.

Este ejemplo solo está disponible en la 🔥 Guía de Programación mediante registros del Microcontrolador ATmega328P 🔥 adquiérela hoy dando clic ⭐ aquí ⭐.

Ejemplo 4: Generar una Señal Fast PWM Invertida por el Pin OC0B con un ancho de pulso del 15%.

Este ejemplo solo está disponible en la 🔥 Guía de Programación mediante registros del Microcontrolador ATmega328P 🔥 adquiérela hoy dando clic ⭐ aquí ⭐.

Ejemplo 5: Generar una Señal Fast PWM con un ancho de pulso variable desde el 0% hasta el 100% por el Pin OC0B en forma no invertida.

Este ejemplo solo está disponible en la 🔥 Guía de Programación mediante registros del Microcontrolador ATmega328P 🔥 adquiérela hoy dando clic ⭐ aquí ⭐.

Ejemplo 6: Generar una Señal PWM de Fase Correcta con un ancho de pulso de 25% por el pin OC0B en forma no invertida.

Este ejemplo solo está disponible en la 🔥 Guía de Programación mediante registros del Microcontrolador ATmega328P 🔥 adquiérela hoy dando clic ⭐ aquí ⭐.

Ejemplo 7: Usar el Módulo PWM para crear una Señal Senoidal.

Este ejemplo solo está disponible en la 🔥 Guía de Programación mediante registros del Microcontrolador ATmega328P 🔥 adquiérela hoy dando clic ⭐ aquí ⭐.

Deja un comentario