Está en la página 1de 8

Clculo del PWM

Para variar el periodo (T) de trabajo de un PWM se utiliza la siguiente frmula:


T = (PR2 + 1) * 4 * Tosc * PRESCALERtimer

T => Periodo del PWM

PR2 => Valor que introduce en la funcin setup_ccpX();.

Tosc => Tiempo de instruccin del PIC (1/fosc=1/20MHz=50nanosegundos)

PRESCALER => Este valor permite obtener frecuencias ms elevadas a


cambio de perder bits de resolucin. Concretamente lo que hace este nmero es
definir el nmero de overflows (veces que se llega al final de la cuenta en el
timer) necesarios para genererar la interrupcin.

En la siguiente imagen (se usa una frecuencia de reloj de 20MHz) hay un ejemplo en el
que T vale 45s (es decir, una frecuencia de 22,22kHz para el PWM). Habiendo
utilizado las 2 ecuaciones:
Tpwm = (PR2 + 1) * 4 * Tosc * PRESCALERtimer ===> 45 = (PR2 + 1) * 4 * 1/20M
===> PR2=224
TiempoTimer = [(256-carga) * PS + 2] * Tinst ===> 20 = [(256-carga)*1+2]*4/20M
===> carga=158

El cdigo para configurar el PWM es sencillo, pues slo hay que configurar el Timer
asociado a los PWM e indicar mediante setup_ccpX que se va a utilizar el PWM.
1 setup_timer_2(T2_DIV_BY_1,158,1);
//CCP1 y CCP2 sern utilizados y
2 setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM); //sus puertos son salidas PWM

3
Desde este momento tan slo hay que utilizar la
funcin set_pwmX_duty(ValorDelPWM); y opcionalmente en el robot de los talleres
2012 la funcin Motores(); los dos siguientes bloques de programacin son
equivalentes y hacen lo mismo.
Forma genrica:
1 set_pwm1_duty(pwm);
M1In1=1; //Para que avance
2
M1In2=0;
//son estos valores
3
Forma particular del robot de los talleres 2012:
1
2

int16 pwm;
Motores(pwm,1,'A');

En ambos casos la variable pwm se habr declarado como un entero de 16 bits mediante
la siguiente instruccin:
1

int16 pwm;

Y se le habr dado un valor entre 0 y 1023 antes de utilizarla.


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
Pues vamos viendo......

Supongamos que se desea una frecuencia de 1KHz a un ciclo de trabajo de


50% con una frecuencia del oscilador de 4MHz.

Lo primero es revisar la hoja de datos (en mi caso el 16F887 o cualquiera


que tenga CCP).
Establece una frmula
PWM Period = [(PR2)+ 1]4TOSC (TMR2 Prescale Value)
Pero es menos complicado si se contempla en funcin de la frecuencia
(recordar que f=1/t):
Fpwm= [(Fosc)/(PR2+1)*(TMR2 Prescale Value)*(4)]
Lo que interesa es el PR2 ya que es el registro del periodo para la frecuencia
(revisar frmula de hoja de datos):
PR2= [(Fosc)/(Fpwm)*(TMR2 Prescale Value)*(4)]-1

PR2 debemos recordar que es de 8 bits, por lo que el valor mximo no debe
exceder 255 (muy importante).

Si se desea 1KHz tenemos bsicamente dos opciones:


1.- Se cambia de frecuencia de oscilacin (no recomendable, ya que todo el
programa se altera)2.- Se cambia de preescalador para el Timer2
Si tomamos la segunda entonces tenemos tres opciones: 1, 4 y 16.
Con 1:
PR2= [(4MHz)/(1KHz)*(1)*(4)]-1
PR2=1000-1 <---bien importante no olvidarse del -1
PR2=999
Con 1 no sirve, ya que se pasa de los 8 bits.
Con 4:
PR2= [(4MHz)/(1KHz)*(4)*(4)]-1
PR2=249
Con 4 sirve.
Con 16:
PR2= [(4MHz)/(1KHz)*(16)*(4)]-1
PR2=62.5
Con 16 podra servir pero..... el registro no almacena decimales, solo
enteros; lo anterior nos proporciona dos posibles caminos:
PR2=62PR2=63
Si PR2=62, entonces la Fpwm ser:
Fpwm= [(Fosc)/(PR2+1)*(TMR2 Prescale Value)*(4)]
Fpwm= [(4MHz)/(62+1)*(16)*(4)]
Fpwm= 992.0634 Hz
Lo anterior entrega un error de 0.8% aproximadamente.
Si PR2=63, entonces la Fpwm ser:
Fpwm= [(Fosc)/(PR2+1)*(TMR2 Prescale Value)*(4)]
Fpwm= [(4MHz)/(63+1)*(16)*(4)]
Fpwm= 976.5625 Hz
Lo anterior entrega un error de 2.4% aproximadamente.

La ideal es PR2=249 con preescalador a 4; cabe sealar que solo estamos


en la frecuencia.

Para el PWM es algo similar pero, el CCS utiliza funciones donde el


comportamiento no es tan transparente como se deseara.

Recordar que
Pulse Width =(CCPRxL:CCPxCON<5:4>) TOSC (TMR2 Prescale Value)
y que
Duty Cycle Ratio= (CCPRxL:CCPxCON<5:4>)
-------------------------------4(PR2 + 1)
El ciclo de trabajo ya se conoce (es el deseado), por lo que interesa es el
valor de CCPRxL:CCPxCON<5:4>. En C o en BASIC es relativamente sencillo
colocar ese valor, en ensamblador no tanto. Lo anterior debido a que los bits
5 y 4 de CCPxCON son los de menor peso y se debe realizar un corrimiento
con todo CCPRxL.
Aqu es donde se torna algo confuso (para la mayora):
suponiendo un ciclo de trabajo de 50%, significa que el valor donde se
repite el periodo (PR2+1) es 250, el valor medio sera 125, por lo que
CCPRxL deber tomar ese valor.
CCPRxL toma el valor ya que es el registro de mayor peso para el ciclo de
trabajo, los otros dos bits no afectan.
Lo anterior es si deseas utilizar el PWM en "modo de 8 bits" (no existe tal
modo, pero trabaja asi). Si deseas utilizar los 10 bits de resolucin, debers
utilizar esos dos bits de menor peso.
Esos dos bits de menor peso siempre producirn 4 combinaciones
adicionales (00,01,10,11) a las 256 del CCPRxL y, como sabemos
10bits=1024. El mximo valor que tendrs ser 1023.
Si PR2 es 249, y PR2+1 =250, entonces el valor para el ciclo de trabajo
crece de 250 a 1000, dando 4 veces el original (debido a esos dos bits).
Aqui est la situacin:

para utilizar los 10 bits de resolucin el CCS debe saber que el parmetro de
set_pwm_duty() es un entero de 16 bits (INT16 o LONG), de otra manera lo
tomar como 8 bits (solo tomar el CCPRxL).

Coloca esto:
setup_ccp1(ccp_PWM);
setup_timer_2(t2_div_By_4,249,1);
set_pwm_duty(125);
Coloca esto:
setup_ccp1(ccp_PWM);
setup_timer_2(t2_div_By_4,249,1);
set_pwm_duty(500L);

El mdulo(s) PWM de un PIC


El parmetro fundamental de una modulacin PWM es la frecuencia (o su
inverso el periodo) de modulacin. En los PIC dicha frecuencia es
programable (con ciertas limitaciones) en base a varias variables:

La frecuencia del oscilador principal Fosc


El pre-scaler (PRE) o divisor previo del timer TMR2 que puede tomar los
valores 1:1, 1:4 o 1:16
El registro PR2 (0-255) asociado al timer TMR2

La frecuencia PWM responde a la frmula:

F_pwm = F_osc / [4 x PRE x (PR2+1)]

o lo que es lo mismo, el periodo del PWM ser el inverso de dicha


frecuencia:
T_pwm = [ (PR2+1) x 4 x PRE ] x Tosc
El valor mximo del divisor previo PRE es 16 y el de (PR2+1) es 256. Por lo
tanto la frecuencia PWM ms baja posible ser Fosc/16384. Para un
oscilador de 20 MHz tenemos una Fpwm mnima de 1.22 KHz
(20000/16384).

Notad que el mdulo PWM usa el timer TMR2, por lo que ste no podr
usarse como temporizador de propsito general mientras se est usando
PWM. Si que es posible usarlo (y ahorrarnos gastar otro timer) si queremos
hacer saltar una interrupcin cada cierto tiempo. El postscaler del TMR2 no
tiene efecto sobre la frecuencia PWM, pero si influye sobre cuando salta (si
est habilitada) la correspondiente interrupcin (TMR2_flag). Si por ejemplo
el post-scaler es 1:16 entonces la interrupcin del TMR2 saltar cada 16
periodos del PWM.

Lo primero que tenemos que hacer para usar el mdulo PWM es habilitarlo
indicando que va a usarse como generador de una onda PWM, ya que dicho
mdulo es compartido con otras funciones (Capture/Compare). La forma de
hacerlo es poner a 11XX los 4 bits menos significativos del registro
CCP1CON. Los PIC18 suelen tener 2 mdulos PWM por lo que existe un
segundo registro CCP2CON.

Podemos habilitar uno o los dos mdulos independientemente. Sin embargo,


como ambos usan el registro PR2 y el timer TMR0 como base de tiempos, la
frecuencia programada ser la misma en ambos mdulos.

Lo que si es posible variar por separado es el ciclo de trabajo (duty cicle o


DC) de cada mdulo. El ciclo de trabajo se codifica con un nmero de hasta
10 bits (0-1023) almacenado de la siguiente forma:

CCPR1L : 8 bits ms significativos del ciclo de trabajo.

CCP1CON.DC1B0 y DC1B1 (bits 5 y 6 de CCP1CON): Guardan los 2 bits


menos significativos.

La programacin del % ON del segundo mdulo es similar pero usando los


registros CCP2CON y CCPR2L.

Con los 10 bits dados el ciclo de trabajo se podr especificar en principio


con 1024 niveles (0 corresponde a 0% y 1023 al 100%). Sin embargo, los
valores vlidos pueden ser menores que los 1024 posibles.

La razn es que el valor de DC (duty_cicle) determina el tiempo que la seal


se mantiene alta (ON) de la forma:

T_on

= [ DC x PRE] x Tosc

Recordando que el tiempo total del periodo es:

T_pwm = [ (PR2+1) x 4 x PRE ] x Tosc

Comparando ambas frmulas y siendo obvio que el tiempo total ON no


puede exceder el tiempo total del periodo tenemos que el valor mximo de
DC es (PR2+1) x 4. Por lo tanto, aunque podemos dar a DC cualquier valor
entre 0 y 1023 est claro que en realidad debemos limitarnos al rango [ 0,
(PR2+1)x4 ]. Valores ms altos van a hacer que Ton > Tpwm, o lo que es lo
mismo, la seal PWM se mantiene alta todo el rato (100%).

En resumen, para mantener la mxima resolucin (10 bits) a la hora de


especificar DC es preciso usar PR2=255. Para una cierta frecuencia del
oscilador Fosc podemos optar por tres frecuencias con la mxima
resolucin:

Registro
PR2

PRE (divisor previo


de TMR2)

F_pwm

Para Fosc = 20
MHz

255

Fosc /
1024

19.75 KHz

255

Fosc /
4096

4.88 KHz

255

16

Fosc /
16384

1,22 KHz

Frecuencias por debajo de Fosc/16384 no son posibles porque los valores de


PR2 y PRE estn ya en su mximo posible.

Frecuencias por encima de Fosc/1024 son posibles pero a costa de bajar PR2
y por lo tanto disponer de menor resolucin para el ciclo de trabajo. Por

ejemplo si aceptamos trabajar con 8 bits (valores de DC de 0 a 255)


podemos llegar a una frecuencia de:

F_pwm = F_osc / [PRE x 4 x (PR2+1)] = Fosc/(1 x 256) = 78 KHz

para un oscilador de 20 MHz.

La razn por la que para frecuencias muy altas no podemos especificar con
tanta precisin el ciclo es que el periodo empieza a hacerse muy pequeo.
En el caso anterior (Fpwm = Fosc/256) es obvio que en un ciclo del PWM
slo entran 256 ciclos del oscilador. Como es imposible que el micro haga
algo entre ciclos de reloj, est claro que slo puede bajar la lnea del PWM
en 256 puntos como mucho (esto es, con una resolucin de 8 bits).

Valores de frecuencias intermedios son tambin posibles, pero de nuevo van


a exigir PR2<255. Por ejemplo para conseguir 10 KHz con un oscilador de 20
MHz

Fosc / Fpwm =20000/10 = 2000 = 4 x PRE x (PR2+1) -> PRE x (PR2+1) =


500

lo que puedo conseguir con PRE=2 y PR2 = 249. Pero entonces el valor del
ciclo de trabajo (DC) tiene que moverse en el rango 0 a 4(PR2+1) = 1000.
Con DC=1000 ya alcanzamos un 100% del ciclo de trabajo y valores
superiores no tendrn ningn efecto extra.

En cuanto al pin de salida al que se manda la seal PWM, usualmente la


salida PWM1 va al pin RC2 y la del PWM2 al RC1 (notad el cambio 1-2). En
algunos dispositivos (consultar datasheet) es posible cambiar la salida de
PWM2 a otro pin mediante un bit de configuracin

También podría gustarte