En esta sección aprenderás a realizar diferentes aplicaciones utilizando el Timer2 del microcontrolador PIC, se realizara un generador de señal de reloj y un generador señal PWM, utilizando dos métodos para generar la señal de salida, por software y hardware.
¿Qué es un timer?
Un temporizador (timer, en inglés) es un componente de hardware en un microcontrolador que puede ser utilizado para medir el tiempo, para generar señales de reloj, para contar de pulsos de reloj, etc. Los timers son comunes en muchos microcontroladores y son útiles en una amplia variedad de aplicaciones.
En términos generales, un temporizador en un microcontrolador consiste en un contador que se puede configurar para contar pulsos externos o pulsos internos de reloj. El temporizador también puede estar conectado a un preescalador, que permite ajustar la velocidad de conteo del temporizador. El temporizador se puede configurar para generar una interrupción cuando se alcanza un valor específico, lo que permite al microcontrolador realizar acciones en función del tiempo transcurrido.
Por ejemplo, un temporizador puede ser utilizado para medir la duración de un pulso de entrada, para controlar la velocidad de un motor mediante señales PWM, para medir la frecuencia de una señal de entrada, o para generar interrupciones en intervalos regulares.
Los microcontroladores modernos suelen tener varios temporizadores integrados, cada uno con características y funcionalidades específicas. La elección del temporizador adecuado dependerá de la aplicación en la que se utilice y de las necesidades del usuario.
El microcontrolador PIC18F4550 tiene tres temporizadores/interrupciones de hardware (Timers), llamados Timer0, Timer1 y Timer2. Cada temporizador tiene sus propias características y funcionalidades específicas.
Timer 2
El Timer2 es un temporizador de 8 bits con un prescaler de 1,4 y 16 y un postcaler de 1 a 16. Generalmente es utilizado para generar señales de modulación por ancho de pulso (PWM).
Ejemplo 1: Generador de señal por software
El objetivo es generar una señal de salida a una frecuencia deseada, utilizando interrupciones para generar los cambios en un pin de salida.
Formulas
Fosc: La frecuencia del oscilador (clock) del microcontrolador.
Preescaler: Divide la frecuencia del oscilador para disminuir el PR2.
Postcaler: Divide la frecuencia del oscilador después del prescaler para disminuir el PR2.
PR2: El valor correspondiente al periodo de la señal.
Circuito de conexión
Procedimiento
Para el siguiente ejemplo, se calculan los valores necesarios para generar una señal de salida con una frecuencia de 60Hz.
Inicialmente se calculan los valores para establecer el preescaler, postcaler, la frecuencia del oscilador y el valor correspondiente al periodo de la señal.
Inicialmente se habilita el timer2 con el prescaler, PR2 y postcaler calculado.
setup_timer_2(T2_DIV_BY_16,235,11);
Se habilitan las interrupciones para detectar el desbordamiento del timer2.
Cuando el timer2 genera el desbordamiento se habilita la interrupción. La interrupción baja a la subrutina donde se cambia el estado del pin de salida.
#INT_TIMER2 //interrupcion por desbordamiento del timer2
void salida_timer()
{
output_toggle(salida); //cambia el estado del pin_d0 (1/0)
}
Archivo .h
En el archivo .h se coloca el oscilador calculado.
#use delay(crystal=20000000)
Código completo generador de señal por software
#FUSES NOMCLR
#define salida pin_d0
#INT_TIMER2 //interrupcion por desbordamiento del timer2
void salida_timer()
{
output_toggle(salida); //cambia el estado del pin_d0 (1/0)
}
void main()
{
setup_timer_2(T2_DIV_BY_16,235,11);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER2);
while(TRUE)
{
}
}
Ejemplo 2: Generador de señal PWM por software
En el ejemplo siguiente se realizan las las ecuaciones para obtener una señal de salida de una frecuencia deseada y controlar el ancho de pulso de la señal.
Circuito de conexión
Procedimiento
Para el siguiente ejemplo, se calculan los valores necesarios para generar una señal PWM de salida con una frecuencia de 60Hz.
Véase el ejemplo 1 para generar la señal de salida.
Inicialmente se habilita la conversión analógica digital.
setup_adc(ADC_CLOCK_INTERNAL);
Se colocan las instrucciones para realizar la lectura del pin analógico AN0, y se guarda el valor en la variable «POT»
set_adc_channel (0);//Lectura Vout del potenciometro en PIN AN0
POT = read_adc();// lectura del valor
Se realiza una regla de 3 para generar un «delay» para controlar el ancho de pulso de la señal, multiplicando el valor del «POT» por el «ancho de pulso» en microsegundos y el resultado se divide entre el valor del ADC (10 bits).
tiempo = ((int32)POT*8333)/1023;
Nota: Si la señal se invierte al girar el potenciometro al valor máximo, se debe reducir el ancho de pulso de la formula (algunos microsegundos), esto se debe a que la señal de salida no es precisa.
El valor del «tiempo» genera un «delay_us()» en el pulso negativo para controlar el ancho de pulso positivo de la señal de salida.
if (input(salida) == 0)
{
delay_us((int16)tiempo);//controla el ancho de pulso positivo
}
Código completo generador de señal PWM por software
#FUSES NOMCLR
#define salida pin_d0
int16 POT;
float tiempo;
#INT_TIMER2 //interrupcion por desbordamiento del timer2
void salida_timer()
{
if (input(salida) == 0)
{
delay_us((int16)tiempo);//controla el ancho de pulso positivo
}
output_toggle(salida); //cambia el estado del pin_d0 (1/0)
}
void main()
{
setup_timer_2(T2_DIV_BY_16,235,11);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER2);
setup_adc(ADC_CLOCK_INTERNAL);
while(TRUE)
{
set_adc_channel (0);//Lectura Vout del potenciometro en PIN AN0
POT = read_adc();// lectura del valor
tiempo = ((int32)POT*8333)/1023;
}
}
Ejemplo 3: Generador de señal por hardware
El objetivo es generar una señal de salida a una frecuencia deseada, utilizando un pin especifico (CCP1) para generar señales PWM.
Formulas
Fosc: La frecuencia del oscilador (clock) del microcontrolador.
Preescaler: Divide la frecuencia del oscilador para disminuir el overflow.
Registro 8 Bits: Determina el valor del tiempo máximo que puede registrar el Timer2.
Overflow: El tiempo máximo que puede generar el registro del timer2.
TMR2: Establece valor del timer2 para generar la señal de salida a una frecuencia especifica.
Duty cicle: Establece el ciclo de trabajo de la señal y controla el ancho de pulso.
Existes dos pines PWM, ccp1 y ccp2, los cuales se pueden habilitar para obtener la misma señal de salida a la frecuencia calculada, pero se puede modificar el ciclo de trabajo de forma independiente.
setup_ccp1(CCP_PWM);//habilita el pin ccp1 salida PWM
setup_ccp2(CCP_PWM);//habilita el pin ccp2 salida PWM
set_pwm1_duty((int16)valor);
set_pwm2_duty((int16)valor);
Circuito de conexión
Procedimiento
Para el siguiente ejemplo, se calculan los valores necesarios para generar una señal de salida con una frecuencia de 60Hz.
Inicialmente se calculan los valores para establecer el preescaler, la frecuencia del oscilador y el TMR2 para establecer la señal de salida.
Inicialmente se habilita el timer2 con el prescaler y el TMR2 calculado.
setup_timer_2(T2_DIV_BY_16,129,1);
Se habilita el pin CCP1 como salida de la señal.
setup_ccp1(CCP_PWM);//habilita el pin ccp1 salida PWM
Se establece el ciclo de trabajo de la señal.
set_pwm1_duty((int16)260);
Archivo .h
En el archivo .h se coloca el oscilador calculado.
En el ejemplo siguiente se realizan las las ecuaciones para obtener una señal de salida de una frecuencia deseada y controlar el ancho de pulso de la señal.
Formulas
Valor: Corresponde al valor máximo del ciclo de trabajo (100%) para la señal generada.
TMR2: Establece valor del timer2 para generar la señal de salida a una frecuencia especifica.
Circuito de conexión
Procedimiento
Para el siguiente ejemplo, se calculan los valores necesarios para generar una señal PWM de salida con una frecuencia de 60Hz.
Véase el ejemplo 3 para generar la señal de salida.
Inicialmente se habilita la conversión analógica digital.
setup_adc(ADC_CLOCK_INTERNAL);
Se colocan las instrucciones para realizar la lectura del pin analógico AN0, y se guarda el valor en la variable «POT»
set_adc_channel (0);//Lectura Vout del potenciometro en PIN AN0
POT = read_adc();// lectura del valor
Se realiza una regla de 3 para calcular el ciclo de trabajo de la señal, multiplicando el valor del «POT» por el «valor» calculado, correspondiente al 100% del ciclo de trabajo y el resultado se divide entre el valor del ADC (10 bits).
duty_cicle = ((int32)POT*520)/1023;
Se establece el ciclo de trabajo de la señal.
set_pwm1_duty((int16)duty_cicle);
Código completo generador de señal PWM por hardware
#FUSES NOMCLR
int16 POT;
float duty_cicle;
void main()
{
setup_timer_2(T2_DIV_BY_16,129,1);
setup_ccp1(CCP_PWM);//habilita el pin ccp1 salida PWM
setup_adc(ADC_CLOCK_INTERNAL);
while(TRUE)
{
set_adc_channel (0);//Lectura Vout del potenciometro en PIN AN0
POT = read_adc();// lectura del valor
duty_cicle = ((int32)POT*520)/1023;
set_pwm1_duty((int16)duty_cicle);
}
}