Está en la página 1de 3

Lenguaje C orientado a Controladores

Programacin PWM
El PWM (Pulse Witdh Modulation) en una seal muy utilizada para el control de motores de corriente
continua. El PWM consiste en una seal cuadrada que forma un tren de pulsos, cuyo ancho puede ser
variado por el usuario manteniendo el periodo original. El concepto radica en que el ancho de pulso permite
variar el valor medio de la seal generado (tambin llamado valor de corriente continua).
Este tipo de seales puede ser generada usando los temporizadores en conjunto con las interrupciones
disponibles del C o usando el modulo CCP (Capture/Compare/PWM). Este modulo funciona en conjunto
con el timer2, el proceso de interrupcin involucrado es transparente para el usuario.

Duty Cycle

Periodo

Fig. 14. Generacin de PWM.

Generacin de un PWM
El concepto es el siguiente, se requiere una variable que almacene la duracin del periodo, una variable que
almacene el ciclo de trabajo y un terminal de salida que permite visualizar la seal. Esto en conjunto con un
contador que cuenta ciclos de reloj producido por un temporizador. Dicha cuenta se realiza en una RSI.
De esta forma, se pone el terminal de salida en 1, la base de tiempo generada por cada canto de reloj
interrumpe, cada interrupcin incrementa en uno el contador, si la cuenta es menor al ciclo de trabajo, el
terminal de salida se mantiene en 1, sino baja a 0. El contador se sigue incrementando por cada
interrupcin, pero ahora se pregunta si la cuenta es menor o igual al largo del periodo, es decir, si la cuenta
es menor que el largo del periodo, se mantiene el bit de salida en el estado actual, sino, significa que se
cumpli el periodo y por lo tanto el contador se hace cero, el bit de salida se hace 1 y se repite el proceso. El
ancho del pulso se maneja cambiando el valor de la variable correspondiente. Lo mismo para el periodo.
Dependiendo de la frecuencia y la resolucin que se requiera del PWM, puede usar algunos de los
temporizadores disponibles, ya sea el Timer 0 o el Timer 1.
Generando PWM con el TMR0
Esto se hace va interrupcin, necesitar una base de tiempo la cual ser proporcionada por el TMR0. La
seal de PWM saldr por el terminal de salida PORTB.7.
Primero se debe implementar una seal de reloj cuya frecuencia se lo ms grande posible, esto generar
una base de tiempo muy pequea. As se tiene:
PS2,PS1,PS0 con el divisor 1:2
TMR0=254
Esta base de tiempo ser el reloj principal para el PWM. El Duty Cycle ms pequeo del PWM generado ser
un periodo de esta seal.

Preparado por jhuircan. Ver preliminar 1.0

33

Lenguaje C orientado a Controladores

Se definen tres variables, el periodo del PWM, llamado TPWM, el Duty Cycle llamado DUTY y un CONTADOR
que establece cuando se cumple el DUTY y cuando se cumple el periodo TPWM.
Filosofa
Se configura la interrupcin TMR0
Se inicializa contador=0
Se inicializa TPWM y DUTY
Se inicializa TMR0=254
Se define un bit de salida con el valor 1, por ejemplo PORTB.7=1
Cada vez que interrumpe el TMR0, se ejecuta la RSI
Cuando entra a la RSI verifica el estado del T0IF y se realizan las siguientes tareas
o
o
o
o
o

Se incrementa el CONTADOR
Si el CONTADOR =DUTY, se hace el PORTB.7=0
Si el CONTADOR=TPWM, se hace el PORTB.7=1 y contador=0
Se resetea T0IF=0
Se inicializa TMR0=254

Por ejemplo si se define TPWM=100 y DUTY=20, durante las primeras 20 interrupciones del TMR0, PORTB.7
ser 1 y luego se har 0 durante las 80 interrupciones siguientes. Al llegar el CONTADOR a 100 se hace un
reset al CONTADOR y parte todo de nuevo. Para modificar el ancho del pulso se debe cambiar el valor del
DUTY.
El siguiente cdigo fuente sera una implementacin, la que puede simplificarse programando los registros
en forma completa y no por bits.
#include "int16CXX.H"
#pragma origin 4
char contador, TPWM,DUTY;
interrupt servidor_de_int( void)
{
int_save_registers
// W, STATUS (and PCLATH)
if(T0IF) {
contador++;
if(contador==DUTY) PORTB.7=0;
if(contador==TPWM)
{
PORTB.7=1;
contador=0;
}
TMR0=254;
T0IF=0; // reset flag de int TMR0
}
int_restore_registers // W, STATUS (and PCLATH)
}
void main()
{
TPWM=100;
DUTY=20;
TRISB.7=0; // PORTB.0 de salida
PORTB.7=1; // Manda un 1
//Programacin del TMR0
OPTION.5=0;
OPTION.4=0;
OPTION.3=0;
OPTION.2=0;
OPTION.1=0;

//
//
//
//
//

T0CK=0, fuente clock interno


T0SE, Incremento con Canto de subida
PSA=0 Pre escalar asignado al TMR0
PS2=0 // Pre escalar 1:2
PS1=0

Preparado por jhuircan. Ver preliminar 1.0

34

Lenguaje C orientado a Controladores

OPTION.0=0; // PS0=0
TMR0=254;
// Carga con el valor inicial 254
INTCON.5=1; // habilita la int por TMR0 TMR0IE=1
GIE=1;
// Habilita todas las int
while(1) // Loop forever
{
}
}

Programando el mdulo CCP


El C tiene dos mdulos, el CCP1 o CCP2 cuya salida son la 13 y 12 respectivamente. Estos mdulos
interactan con el timer2. Para la configuracin CCP1 se utilizan los registros TRISC, CCP1CON, CCPR1L
(registros del modulo CCP1), PR2 y T2CON (registros del modulo Timer2). El PWM tiene una resolucin de
1024 cuentas. Las condiciones iniciales sern el periodo del PWM y el clock del sistema.
Se configura el modulo CCP para trabajar en modo PWM programando el registro CCP1CON.
Se ingresa el valor codificado en 10 bits del ciclo de trabajo (Duty Cycle) en el registro CCPR1L (que
es de 8 bits) y los dos bits restantes en el registro CCP1CON.4 y CCP1CON.5.
Se configura el Timer2, a travs de los registros T2CON y PR2. Esto permite definir los pre-escalares
respectivos y la duracin del periodo en base a la siguiente expresin lo que permite realizar los
ajustes para la frecuencia requerida.
Los siguientes diagramas permiten ilustrar la programacin
Para CCP1, se configura la palabra de control
CCPCON1
CCPxX

CCPxY

CCPxM3

Modo PWM

CCPxM2

CCPxM1

CCPxM0

PR2
T2CON
TM2ON

Habilita T2

Deshabilita T2

Pre-Escalar 1
Pre-Escalar 4
Pre-Escalar 16

Preparado por jhuircan. Ver preliminar 1.0

T2CKPS1

0
0
1

T2CKPS0

1
1
X

35

También podría gustarte