Está en la página 1de 14

11/12/13

Tutoriales PIC: Modulacin PWM (Pulse Width Modulation)

Tutoriales PIC
Fundamentos de microcontroladores aplicados a la familia PIC de Microchip. Proyectos y Aplicaciones.
Seleccionar idioma
Con la tecnologa de

Traductor de Google

MIRCOLES, 27 DE JUNIO DE 2012

PGINAS VISTAS EN TOTAL

Modulacin PWM (Pulse Width Modulation)


Nuestro controlador (digital) eventualmente tendr que interactuar con el mundo exterior (analgico). Al margen de usar dispositivos externos (convertidor digital analgico o DAC) muchos microcontroladores cuentan con un mdulo PWM (Pulse Width Modulation) que puede usarse (con ciertas limitaciones) para mandar "ordenes" analgicas. En este tutorial describiremos en que consiste la modulacin por ancho de pulsos (PWM), veremos las rutinas disponibles en C18 y, como hacemos habitualmente, describiremos los registros asociados y su funcionalidad. Aprovecharemos los conocimientos adquiridos para escribir una rutina para inicializar el mdulo PWM especificando la frecuencia deseada y escribiremos un pequeo programa para usar los dos mdulos PWM de un PIC para crear transiciones de colores en un LED bicolor. En una entrada posterior aplicaremos lo que hemos aprendido a una aplicacin ms interesante usando el mdulo PWM como conversor DAC para un archivo de audio. Archivos de cdigo asociados a esta entrada: pwm1.c y pwm2.c -------------------------------------------------------------------------------------------PROYECTOS:

74,760
SEARCH IN THIS BLOG Buscar

LO MS VISTO ESTE MES

Modulacin PWM (Pulse Width Modulation) Conversor ADC Manejo de motores DC usando PWM Controlador PID para posicin de un motor DC Comunicaciones puerto serie (UART)

Audio con PWM Brjula electrnica Levitador magntico Medidor de potencia Monitor pulso cardaco
ARCHIVO DEL BLOG

Descripcin de la modulacin por ancho de pulso (PWM) En algunos de los tutoriales anteriores usbamos un truco para estimar la ocupacin del PIC. Consista en poner a 1 un cierto pin mientras estbamos haciendo una cierta tarea. Luego, nos bastaba con medir el voltaje medio (con un voltmetro) en dicho pin. Dicho voltaje (dividido por los 5V de alimentacin) nos daba el % del tiempo que el pin estaba alto. La modulacin PWM consiste precisamente en eso. El mdulo PWM del micro genera una onda cuadrada con una frecuencia dada (tpicamente bastante alta, por ejemplo 10 KHz). Luego nosotros podemos ir cambiando el ciclo de trabajo (% del periodo en ON) de la seal:

2013 (16) 2012 (13) julio (3) junio (10) Aplicacin: Audio con PWM Modulacin PWM (Pulse Width Modulation) Decodificador de un mando a distancia Comunicaciones UART con paridad

Si usamos un dispositivo externo con un ancho de banda suficiente (p.e. un osciloscopio) veremos la seal al completo, esto es, la modulacin rpida (o portadora) de 10 KHz y las variaciones ms lentas (seal a transmitir) del ciclo de trabajo. Si por el contrario aplicamos un filtro paso-bajo a la seal PWM, los cambios rpidos (10 KHz) de la seal se eliminarn y simplemente veremos los cambios lentos del ciclo de trabajo, observando un voltaje "medio" entre 0 y 5V dependiendo del ciclo de trabajo (0% -> 100%) programado. No siempre es necesario implementar un filtro paso-bajo de forma explcita. Muchas veces usamos un dispositivo externo (voltmetro, motor, etc) con suficiente "inercia", de forma que no es capaz de seguir los cambios rpidos de la seal (los 10 KHz). Por as decirlo el dispositivo (motor, altavoz) lleva incorporado su propio filtro paso-bajo.

Comunicaciones UART con interrupciones Comunicaciones puerto serie (UART) Uso de temporizadores (timers) Niveles de prioridad en interrupciones Interrupciones (conceptos bsicos) Introduccin al BLOG

picfernalia.blogspot.mx/2012/06/modulacion-pwm-pulse-width-modulation.html

1/14

11/12/13

Tutoriales PIC: Modulacin PWM (Pulse Width Modulation)


DATOS PERSONALES

Lo que hemos conseguido es una especie de conversor digital analgico que nos permite traducir una orden digital (ciclo de trabajo del periodo PWM) en una variable analgica (el voltaje medio a la salida entre 0 y 5V). Obviamente tendremos algunas limitaciones. Como queremos que desaparezca la frecuencia de modulacin (los 10 KHz) de antes los cambios (frecuencia) de la seal que queremos transmitir deben ser lo suficientemente lentos (frecuencia baja) para que no desaparezcan tambin en el filtrado paso-bajo (explcito o implcito) de nuestro dispositivo.

Antonio Ver todo mi perfil


SEGUIDORES Participar en este sitio
Google Friend Connect

Miembros (18) Ms

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
Ya eres miembro? Iniciar sesin

Recordando que el tiempo total del periodo es:

picfernalia.blogspot.mx/2012/06/modulacion-pwm-pulse-width-modulation.html

2/14

11/12/13

Tutoriales PIC: Modulacin PWM (Pulse Width Modulation)


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 255 255 255 PRE (divisor previo de TMR2) 1 4 16 F_pwm Fosc / 1024 Fosc / 4096 Fosc / 16384 Para Fosc = 20 MHz 19.75 KHz 4.88 KHz 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. Las rutinas bsicas del compilador C18 para manejar los mdulos PWM son las siguientes (las declaraciones se encuentran en pwm.h): OpenPWM1(uint8 periodo) : habilita el mdulo y hace PR2=periodo SetDCPWM1(uint16 duty_cicle) : establece ciclo de trabajo 0% -> 100% ClosePWM1(); : deshabilita modulo PWM Notad que las rutinas anteriores no tocan el timer TMR2. Es responsabilidad del usuario invocar a la rutina OpenTimer2 para fijar el valor del divisor o pre-scaler y arrancar el temporizador. El siguiente programa (cdigo en pwm1.c) pone en marcha ambos mdulos y va variando el ciclo de trabajo de PWM1 entre 0 y DC_max (valor mximo = 1023, correspondiente a un 100%). Simultneamente el ciclo de PWM2 se establece como el valor complementario. Tras los #include (no olvidar aadir pwm.h, timer.h y delays.h) y los #pragma de configuracin habituales el programa principal es simplemente:
v o i dm a i n ( ) { u i n t 1 6D C _ m a x ,d d = 0 ;

picfernalia.blogspot.mx/2012/06/modulacion-pwm-pulse-width-modulation.html

3/14

11/12/13
i n t 8i n c = 1 ;

Tutoriales PIC: Modulacin PWM (Pulse Width Modulation)

D C _ m a x = 1 0 2 3 ;

O p e n P W M 1 ( 2 5 5 ) ;O p e n P W M 2 ( 2 5 5 ) ;

/ /S e tP W M 1a n dP W M 2w i t hP R 2=2 5 5

O p e n T i m e r 2 ( T I M E R _ I N T _ O F F&T 2 _ P S _ 1 _ 1 ) ;/ /S t a r t sT M R 2w i t h1 : 1p r e s c a l e r

w h i l e ( 1 ) { S e t D C P W M 1 ( d d ) ;S e t D C P W M 2 ( D C _ m a x d d ) ; d d + = i n c ; / /S e tc o m p l e m e n t a r yD Ci nP W M 1a n dP W M 2 / /I n c r e a s ed u t yc i c l e

i f( ( d d = = D C _ m a x )| |( d d = = 0 ) )i n c = i n c ;/ /I fw eg e tt oD C _ m a xo r0r e v e r s ed i r e c t i o n . D e l a y 1 0 K T C Y x ( 5 ) ; } }

Vemos que hemos usado PR2=255 y pre-scaler = 1. Esto nos da una frecuencia PWM de : Fpwm = Fosc/(4 x 256 x1) = 20000 KHz / 1024 = 19.5 KHz El siguiente video es una captura de pantalla del osciloscopio monitorizando PWM1 y PWM2. Se observa que el periodo del PWM (unos 51 usec, correspondientes a 19.5 KHz) no cambia y es comn a ambos canales. El tiempo en ON de PWM1 (arriba) es justo el tiempo OFF del PWM2 (abajo) ya que los hemos programado para ser complementarios: dd y (DC_max-dd)

Los saltos que se observan en las transiciones del duty_cicle son debidas a la frecuencia (baja) con la que se refrescan en pantalla los datos del osciloscopio. En el osciloscopio se ve una variacin gradual, como corresponde a un incremente de 1 en 1 en el ciclo de trabajo. Vamos a cambiar la frecuencia haciendo O p e n P W M 1 ( 1 9 9 ) ; O p e n P W M 2 ( 1 9 9 ) ; lo que corresponde a (PR2+1)=200 y a una frecuencia de 20000/(4x200) = 25 KHz. En el siguiente video vemos la captura del osciloscopio:

La frecuencia son justo los 25 KHz esperados. Sin embargo, se aprecia que algo va mal. Ahora canales no son complementarios. El canal PWM1 llega al 100% y permanece all, no empezando hasta despus de un rato. El comportamiento de PWM1 y PWM2 no parece ser el que programado. La evolucin del ciclo de trabajo antes describa la funcin de la izquierda corresponda a nuestro programa), y ahora parece describir la de la derecha.

ambos a bajar hemos (como

picfernalia.blogspot.mx/2012/06/modulacion-pwm-pulse-width-modulation.html

4/14

11/12/13

Tutoriales PIC: Modulacin PWM (Pulse Width Modulation)

La razn es que al haber bajado PR2 hemos subido la frecuencia (correcto) pero sin darnos cuenta tambin hemos alterado el rango de valores posible para DC. El valor mximo para el que alcanzamos e 100% es de 4x(200) = 800. Al llegar dd a 800, la seal PWM alcanza un 100% y se mantiene mientras dd sigue subiendo hasta 1023 y vuelve a bajar. Slo cuando volvemos a entrar en el rango [0 800] volvemos a notar variacin. En resumen, recordar que si PR2 no es 255 el valor mximo de DC no ser 1024 sino DC_max = 4 x (PR2+1).

Nuestras propias rutinas Ahora que entendemos como funciona el mdulo PWM y conocemos los registros involucrados, vamos a escribir nuestras propias rutinas de manejo del PWM. En primer lugar las rutinas para ajustar el duty cicle:
v o i ds e t _ p w m 1 ( u i n t 1 6d u t y ) { C C P 1 C O N b i t s . D C 1 B 0 = ( d u t y &0 x 0 1 ) ;d u t y > > = 1 ; / / L e a s tS i g n i f i c a n tb i t C C P 1 C O N b i t s . D C 1 B 1 = ( d u t y &0 x 0 1 ) ;d u t y > > = 1 ; / /2 n dL e a s tS i g n i f i c a n tb i t C C P R 1 L = ( d u t y ) ; / /8M o s tS i g n i f i c a n tb i t s }

v o i ds e t _ p w m 2 ( u i n t 1 6d u t y ) { C C P 2 C O N b i t s . D C 2 B 0 = ( d u t y &0 x 0 1 ) ;d u t y > > = 1 ; C C P 2 C O N b i t s . D C 2 B 1 = ( d u t y &0 x 0 1 ) ;d u t y > > = 1 ; C C P R 2 L = ( d u t y ) ; }

Vemos que slo es cuestin de poner los 2 bits menos significativos del argumento en los bits DC1b0 y DC1b1 de CCP1CON y los 8 ms significativos en CCPR1L. Lo mismo para los registros CCP2CON y CCPR2L para PWM2. Obviamente, estas rutinas no aportan nada sobre las suministradas por C18, slo nos permiten confirmar que lo que se est haciendo no es nada complicado. Veamos una rutina con algo de "valor aadido". Era un poco incomodo tener que acordarnos de configurar y arrancar TMR2 por separado. Vamos a escribir una rutina que combine la configuracin del mdulo y el arranque del timer TMR2. Adems, en vez de aportar como argumentos los valores de PR2 y del prescaler de TMR2 vamos a especificar la frecuencia Fpwm deseada (en KHz) y dejar que la rutina calcule y configure los registros adecuados. Como siempre est rutina puede ser combinada con las del C18. Podemos usar esta rutina para inicializar el mdulo y luego usar las rutinas de C18 para fijar el ciclo de trabajo. El cdigo es el siguiente:
u i n t 1 6s e t u p _ P W M ( u i n t 1 6F o s c ,u i n t 8F p w m ,u i n t 8c h ) / / F o s c>Fo s c i l l a t o ri nK H z , F p w m>d e s i r e dF p w mi nK H z

/ /c h >c o n f i g u r ec h a n n e l1( 1 ) ,2( 2 )o rb o t h( 3 ) / /R e t u r n sm a xp o s i b l ev a l u eo fd u t yc i c l e { u i n t 1 6x ,D C _ m a x ; u i n t 8p r e ; u i n t 8l o g 2 , p r 2 ;

x=F o s c > > 1 ;x = ( x / F p w m ) + 1 ;x > > = 1 ; / /C o m p u t e sr o u n d ( ( F o s c / 4 ) / F p w m )

i f( x > 1 6 3 8 4 ){ p r e = 1 6 ;p r 2 = 2 5 5 ; } e l s e { p r e = 0 ;

/ /R e q u e s t e dF p w mt o ol o w>s e tF p w m=F o s c / 1 6 3 8 4

w h i l e ( x > 2 5 6 ){ x > > = 2 ;p r e + + ; } / /F i n dp r 2a n dp r es ot h a t( p r 2 + 1 ) * p r e = ( F o s c / 4 ) / F p w m p r 2 = ( x 1 ) ; / /p r e0 , 1 , 2>1 : 1 ,1 : 4 ,1 : 1 6

picfernalia.blogspot.mx/2012/06/modulacion-pwm-pulse-width-modulation.html

5/14

11/12/13
}

Tutoriales PIC: Modulacin PWM (Pulse Width Modulation)

i f( c h & 1 ){T R I S C b i t s . T R I S C 2 = 0 ;C C P R 1 L = 0 ;C C P 1 C O N=0 b 0 0 0 0 1 1 0 0 ;}/ /S E Tc h a n n e l1 i f( c h & 2 ){T R I S C b i t s . T R I S C 1 = 0 ;C C P R 2 L = 0 ;C C P 2 C O N=0 b 0 0 0 0 1 1 0 0 ;}/ /S e tc h a n n e l2

P R 2 = p r 2 ; T 2 C O N=0 b 0 0 0 0 0 1 0 0|p r e ; / /s t a r tT M R 2w i t hp r e s c a l e rp r ea n dp o s t s c a l e r1 : 1 / /T 2 C O N=0 b 01 1 1 110 0; / / / / / / / / / / | | | | || | || | _P r e s c a l e :0 0( 1 ) 0 1( 4 ) 1 X ( 1 6 ) || _ _ _ _T I M E R 2o n / o f f( 1 = o n ,0 = o f f ) | _ _ _ _ _ _P o s t S c a l e r :1 : ( b b b b + 1 )0 0 0 0 :1 : 1 1 1 1 1 :1 : 1 6

| _ _ _ _ _ _ _ _ _ _ _N o tu s e d

D C _ m a x=p r 2 ;D X _ m a x + + ;D C _ m a x < < = 2 ; / /4x( P R 2 + 1 ) / /M A Xv a l u ef o rD u t yc i c l e r e t u r nD C _ m a x ; }

La rutina recibe la frecuencia del oscilador y la frecuencia PWM deseada (ambas en KHz, uint16 para Fosc y uint8 para Fpwm) y el canal PWM que deseamos inicializar (1 para PWM1, 2 para PWM2 o 3 para ambos). Todo esto pensando en PICs con dos mdulos PWM, aunque sera fcilmente modificable para otros casos. El tener una sola funcin para inicializar todos los canales tiene sentido porque los parmetros calculados (PR2, pre-scaler) son comunes entre canales. La funcin calcula el valor de PR2 y PRE que consiguen la frecuencia pedida y los usa para el registro PR2 y para configurar el divisor previo del TMR2. Tambin arranca el timer por lo que no es necesaria una llamada adicional. Si la frecuencia requerida es demasiado baja se fija la frecuencia permitida ms baja posible. Como es posible que en PR2 resulte un valor < 255, la funcin devuelve el valor de DC que corresponde a un 100% del ciclo ON. Usando las nuevas rutinas podramos reescribir el programa anterior como:
v o i dm a i n ( ) { u i n t 1 6D C _ m a x , d d = 0 ; i n t 8i n c = 1 ;

D C _ m a x = 1 0 2 3 ; / /N o m i n a lV a l u ef o rD Cm a x

D C _ m a x = s e t u p _ P W M ( 2 0 0 0 0 , 1 0 , 3 ) ;/ /S e tb o t hc h a n n e l s@F p w m = 1 0K H zf o ra2 0M H zo s c i l l a t o r

w h i l e ( 1 ) { s e t _ p w m 1 ( d d ) ;s e t _ p w m 2 ( D C _ m a x d d ) ; d d + = i n c ; / /I n c r e a s ed u t yc i c l e

i f( ( d d = = D C _ m a x )| |( d d = = 0 ) )i n c = i n c ; / /R e v e r s ed i r e c t i o n . D e l a y 1 0 K T C Y x ( 5 ) ; } }

Vemos como para DC_max no usamos el valor nominal 1023 sino el que nos devuelve la funcin setup_PWM. La aplicacin ms sencilla que podemos ver del uso de PWM es modular la luminosidad de un LED. Al contrario que con una lmpara incandescente no podemos atenuar un LED bajando su voltaje ya que al ser esencialmente un diodo, pasar de no conducir (OFF) a conducir (ON) con una muy pequea variacin de voltaje. Lo que podemos hacer con PWM es encenderlo y apagarlo muy rpidamente (a la frecuencia del PWM). El tiempo ON del ciclo (duty) determinar la luminosidad aparente del LED (en este caso el elemento integrador o paso bajo es nuestro ojo, que es incapaz de apreciar como el LED se enciende y se apaga). En el ejemplo siguiente usamos la salida de PWM1 y PWM2 para modular el color e intensidad de un Led bicolor RG. Usaremos RC1 y RC2 conectados al positivo de los leds R y G y pondremos el negativo comn a tierra:

picfernalia.blogspot.mx/2012/06/modulacion-pwm-pulse-width-modulation.html

6/14

11/12/13

Tutoriales PIC: Modulacin PWM (Pulse Width Modulation)

El diferente valor de las resistencias usadas (800K, 100K) es para compensar la mayor eficiencia del LED rojo e intentar que la luminosidad de ambos LED estn equilibradas. El cdigo (pwm2.c) es muy similar al anterior, pero ahora los valores del ciclo de trabajo los sacamos de un par de tablas (bsicamente una oscilacin sinusoidal dando ms preferencia a los niveles cerca del 0). El tamao de ambas tablas corresponde a dos nmeros primos y se ha elegido as para que se de una mayor combinacin de colores, antes de que empiecen a repetirse las combinaciones. Tambin se han definido un par de macros que incrementan los respectivos punteros p1 y p2 a las tablas, hacindolos voltear al llegar al final. Como ambas tablas son de slo lectura una posibilidad sera colocarlas en la memoria de programa (usando el calificador const rom) para no gastar memoria de datos.
# d e f i n eN 16 1 # d e f i n eN 25 9 u i n t 1 6d u t y 1 [ N 1 ] = { 1 2 1 ,1 5 3 ,1 9 2 ,2 3 9 ,2 9 4 ,3 5 7 ,4 2 8 ,5 0 7 ,5 9 0 ,6 7 6 ,7 6 1 ,8 4 0 ,9 0 9 ,9 6 4 , 1 0 0 1 , 1 0 1 8 , 1 0 1 2 ,9 8 5 ,9 3 9 ,8 7 6 ,8 0 1 ,7 1 9 ,6 3 3 ,5 4 8 ,4 6 7 ,3 9 2 ,3 2 4 ,2 6 5 ,2 1 5 ,1 7 2 ,1 3 7 ,1 0 8 , 8 4 , 6 5 , 5 0 , 3 8 , 2 9 , 2 2 , 1 6 , 1 1 , 1 , 2 , 4 , 6 , 8 , 5 , 3 , 2 , 1 , 0 , 0 , 0 ,

9 , 1 3 , 1 8 , 2 5 , 3 3 , 4 4 , 5 7 , 7 4 , 9 5 } ;

u i n t 1 6d u t y 2 [ N 2 ] = { 1 2 1 ,1 5 5 ,1 9 5 ,2 4 4 ,3 0 2 ,3 6 9 ,4 4 4 ,5 2 6 ,6 1 3 ,7 0 2 ,7 8 9 ,8 6 7 ,9 3 4 ,9 8 3 , 1 0 1 2 , 1 0 1 8 , 1 0 0 0 ,9 6 1 ,9 0 2 ,8 2 9 ,7 4 6 ,6 5 8 ,5 6 9 ,4 8 4 ,4 0 5 ,3 3 4 ,2 7 2 ,2 1 9 ,1 7 4 ,1 3 7 ,1 0 7 , 8 3 , 6 4 , 4 9 , 3 7 , 2 7 , 2 0 , 1 4 , 1 0 , 3 , 5 , 7 , 4 , 2 , 1 , 0 , 0 , 0 , 1 , 2 ,

8 , 1 2 , 1 7 , 2 4 , 3 2 , 4 2 , 5 6 , 7 3 , 9 5 } ;

u i n t 8p 1 = 0 ; u i n t 8p 2 = 0 ;

# d e f i n ei n c _ p 1{ p 1 + + ;i f ( p 1 = = N 1 )p 1 = 0 ;} # d e f i n ei n c _ p 2{ p 2 + + ;i f ( p 2 = = N 2 )p 2 = 0 ;}

v o i dm a i n ( ) { s e t u p _ P W M ( 2 0 0 0 0 , 5 , 3 ) ;

w h i l e ( 1 ) { s e t _ p w m 1 ( d u t y 1 [ p 1 ] ) ;i n c _ p 1 ; s e t _ p w m 2 ( d u t y 2 [ p 2 ] ) ;i n c _ p 2 ;

D e l a y 1 0 K T C Y x ( 5 ) ; } }

En la siguiente pelcula podemos ver el resultado. A la derecha, los LEDs de la placa EasyPic6 correspondientes a RC1 y RC2 se van encendiendo y apagando. A la izquierda el LED Red-Green conectado a ambas salidas va cambiando de color.

picfernalia.blogspot.mx/2012/06/modulacion-pwm-pulse-width-modulation.html

7/14

11/12/13

Tutoriales PIC: Modulacin PWM (Pulse Width Modulation)

El problema del video es que los sensores de las cmaras digitales son muy sensibles al rojo (de hecho ms al infrarrojo), saturandose el canal rojo y no apreciandose correctamente los detalles de las transiciones de color.

Publicado por Antonio

Recomendar esto en Google

28 comentarios:
Tony 20 de marzo de 2013 18:44 Bastante completo, me surge una duda, las seales pwm las pones para que tengan las mismas caracteristicas, como se podria hacer para que las dos seales esten desfasadas un angulo? Responder Respuestas Antonio 20 de marzo de 2013 19:33

Supongo que te refieres a que las dos seales PWM tengan un desfase entre ellas. Usando el mdulo PWM del PIC creo que no es posible, ambas seales van guiadas por el mismo timer y se ponen en alto en el mismo instante (aunque dependiendo del duty cycle programado para cada una de bajan en instantes distintos).

Tony 20 de marzo de 2013 20:11 Gracias por responder tan rapido. Si, es mi problema, habia pensado en usar interrupciones para intentar controlarlo, pero no le encuentro solucion correcta. Mirare a ver si se puede hacer de otras maneras.

Alvaro Tasco 10 de julio de 2013 20:00 Si tambien tengo ese problema necesito generar 2 seales PWM desfasada 180 y adicionarle un tiempo muerto...

Alvaro Tasco 10 de julio de 2013 20:00 Si tambien tengo ese problema necesito generar 2 seales PWM desfasada 180 y adicionarle un tiempo muerto...

Antonio

11 de julio de 2013 10:13

Cuando dices desfasadas 180 te refieres a que una est desplazada medio ciclo respecto a la

picfernalia.blogspot.mx/2012/06/modulacion-pwm-pulse-width-modulation.html

8/14

11/12/13

Tutoriales PIC: Modulacin PWM (Pulse Width Modulation)


otra (caso a) o a que la segunda es la complementaria de la primera (caso b)? Si es el caso b) es muy sencillo con un PIC con EPWM (enhanced PWM). Solo programas el PWM normalmente y la seal complementaria sale por otro pin (RD5 o asi, consulta el datasheet). Adems puedes programar tiempos muertos. Si es el caso a) no creo que sea posible usando PWM, aunque podras hacerlo a travs de una interrupcin con un timer. Tambin supongo que con un poco de electrnica detrs de la salida PWM podras crear una seal retrasada. Antonio

Alvaro Tasco 15 de julio de 2013 06:28 Muchas graacias antonio por tu respuesta tan pronta. Las seales las necesito complementaria, Ando trabajando con el 18F4550 y trae ese modulo ECCP, la aplicacion que esto haciendo es controlar un puente H, al cual le pueda variar la frecuencia pwm y el ciclo de trabajo. Obligatoriamente estas seales no pueden tener un ciclo de trabajo superior al 50%.. He hecho unas simulaciones [URL=http://imageshack.us/photo/my-images/842/pxj.png/] [IMG]http://imageshack.us/a/img842/4375/pxj.th.png[/IMG][/URL] esa es la imagen.. Y realizando el programa.. me sale esto..[URL=http://imageshack.us/photo/myimages/51/kf4m.jpg/][IMG]http://imageshack.us/a/img51/4980/kf4m.th.jpg[/IMG][/URL]

Alvaro Tasco 15 de julio de 2013 06:29 Este comentario ha sido eliminado por el autor.

Antonio

15 de julio de 2013 16:28

Pero las seales que veo en tu captura de osciloscopio parecen bastante correctas. Tienes ambas seales complementarias con un "deadband" entre ellas. Es cierto que, a ojo, tu ciclo de trabajo es del orden de un 78%, pero si ese es el problema, podras modificarlo limitando el valor de los registros correspondientes. Las formulas relevantes son (pag 155 del manual del 2550-4550): Period_pwm = 4 x Tosc x (PR2+1) x TMR2_pre T_Duty_on = Tosc x (valor duty) x TMRpre max(valor_duty) = 4*(PR2+1) = 100% Delay (tiempo muerto) = 4 x Tosc x ECCP1DEL (7 bits)

Imagina que tienes un cristal de 8Mhz (Tosc = 1/8 usec) y programas el PWM con un TMR2_pre=1 y PR2=255. Tendras un periodo de 4 x 1/8 x 256 x 1 = 128 usec = 7.8KHz de frecuencia PWM. Si ahora programas un delay de 32 usec (con ECCP1DEL=64) y varas duty entre 0 y 768 tendrs dos seales complementarias (fuera del tiempo muerto) y ninguna de las dos ocupara ms de un 50%. No se si he entendido lo que queras. Antonio.

ricardo lara 22 de agosto de 2013 00:28 Buena respuesta... tengo una duda, tengo el pic 18f4550 este posee solo 2 salidas pwm, Como se pueden generar mas salidas ya sea por software o hatware?, pues necesito controlar 6 servos Agradecera tu respuesta

Antonio

28 de agosto de 2013 13:46

Podras hacerlo con software usando timers y las interrupciones asociadas. De hecho solo necesitaras gastar un timer para controlar hasta 8 servos (asumiendo una frecuencia de 50 Hz y un mximo pulso de control de 2.5 usec que es lo standard en muchos servos). Obviamente precisaras 1 pin libre para controlar cada servo.

picfernalia.blogspot.mx/2012/06/modulacion-pwm-pulse-width-modulation.html

9/14

11/12/13

Tutoriales PIC: Modulacin PWM (Pulse Width Modulation)


Estaba pensando escribir una entrada sobre el tema explicando los detalles. Con tu pregunta, la subir de prioridad en mi cola de cosas para hacer. Antonio. Responder

Annimo 4 de abril de 2013 01:39 Es decir, si deseo hacer un PWM de 100KHz tendra que poner el PR2 a 50 con lo cual 4x50=200 si todo el periodo son 1024 entonces slo tendra un duty "til" o "con tensin positiva en la salida" un 19,5% del periodo total? Gracias por tu artculo, me ha parecido muy interesante :) Responder Respuestas Antonio 4 de abril de 2013 11:16

Asumiendo que tienes un cristal de 20 MHz y que programas un PRESCALER=1 entonces efectivamente obtendrs un PWM de 100 KHz si usas PR2=49 (PR2+1=50). Lo que no es cierto es que solo puedas conseguir un duty mximo del 19% (200/1024). Puedes alcanzar un duty del 100% si pones 200 en el resistro del duty cycle. No has perdido rango del duty, ya que puedes ir desde 0% (duty=0) hasta 100% (duty=200). Lo que has perdido es resolucin al especificar el duty. Todo el rango posible (de 0 a 100%) lo cubres en 200 pasos, en vez de en los 1024 pasitos posibles si hubieras optado por una frecuencia PWM ms baja. Espero haberte aclarado algo, Antonio.

Annimo 6 de abril de 2013 00:52 Todo claro, muchas gracias :) Responder

Annimo 22 de agosto de 2013 19:47 Hola, tengo una duda, una tontera ms bien pero no me termina de quedar claro. En modo PWM, el periodo de la seal generada, est limitado por el tamao del Timer 2 o no?. S que el periodo depende del timer, pero no tengo claro exactamente de qu caracterstica del timer depende. Otra pregunta que tengo, por si alguien la sabe es si, El mdulo CCP en modo PWM slo produce interrupcin en modo captura con un sensor de ultrasonidos o no tiene nada que ver. Muchas gracias.. Un saludo.. Responder Respuestas Antonio 28 de agosto de 2013 13:38

No entiendo muy bien a que te refieres con el tamao del Timer 2. El Timer 2 siempre es de 8 bits. El periodo del PWM es: 4 * Tosc * (PR2+1) * TMR2_PREESCALER y por lo tanto depende del valor del registro PR2 (asociado al Timer 2) y del valor de preescalado (1,4 o 16) del Timer 2. Respecto a tu segunda pregunta, si el mdulo CCP est en modo PWM no producir interrupciones asociadas al modo CAPTURE, aunque es posible programar uno de los mdulos CCP en modo PWM y el otro en modo CAPTURE. Respecto a lo del sensor de ultrasonidos, una interrupcin de captura saltar cuando la lnea correspondiente suba o baje. Lo que sea que cause ese cambio es indiferente. Hay una entrada ms reciente sobre el modo CAPTURE del mdulo CCP que puede aclararte

picfernalia.blogspot.mx/2012/06/modulacion-pwm-pulse-width-modulation.html

10/14

11/12/13
algunas conceptos:

Tutoriales PIC: Modulacin PWM (Pulse Width Modulation)

http://picfernalia.blogspot.com.es/2013/07/modo-de-captura-en-el-modulo-ccp.html Espero haberte aclarado algo, Antonio

Alisanz 29 de agosto de 2013 13:23 Este comentario ha sido eliminado por el autor.

Annimo 29 de agosto de 2013 13:24 S, muchas gracias. A lo que me refera con el mdulo CCP era si slo produce interrupciones en modo captura, pero he ledo que es en modo comparacin dnde si las produce, no?

Antonio

29 de agosto de 2013 16:59

El modulo CCP (Capture/Compare/PWM) puede producir interrupciones en sus tres modos: * En modo Capture la interrupcin CCPxIF saltara cuando la linea suba, baje, o cada 4 o 16 subidas (se puede programar). * En modo Compare CCPxIF se levanta cuando el valor del Timer asociado (TMR1/TMR3) coincide con el valor del registro CCPRx. * El modo PWM no provoca interrupciones CCP, pero como por debajo usar el timer TMR2, disparar la interrupcin asociada al Timer TMR2. POr supuesto en todos los casos para que la interrupcin salte los correspondiente bits IE (interrupt enable) deben estar a 1, tanto de tipo general como especficos. Un saludo, Antonio.

Responder

Annimo 13 de noviembre de 2013 07:42 Hola, buenas noches soy estudiante de Biomedica en la universidad, me piden que genere un programa en C utilizando el PIC18F45K22, y un LCD para representar los datos manejando los 2 modulos PWM del pic, mi pregunta es , tengo que ingresar todas las declaraciones y definiciones que manejas para poder ejecutarlo, claro aparte de la interfaz LCD al microcontrolador, ya que el maestro nos solicita generar 2 frecuencias, una de 38.53KHz y otra de 63.75Khz con cada modulo PWM respectivamente. Gracias por su respuesta!!!! Responder Respuestas Antonio 13 de noviembre de 2013 11:11

Si vas a usar las funciones del C18 para los TIMERS y el PWM si que deberas usar los correspondientes #includes. Respecto a mi fichero ints_C18.h donde defino la posicin de los diferentes bits de interrupciones, flags, etc no sera necesario. De hecho si quieres usar algo similar por conveniencia tendras seguramente que modificarlo, ya que es casi seguro que algunos de los bits asociados a los timers y al PWM estn en registros/posiciones diferentes. De hecho, lo de generar 2 frecuencias distintas en ambos canales es algo que no es posible en los PIC (18F4520) que yo estoy usando. En estos PICs ambos mdulos PWM usan el mismo timer TMR2, por lo que la frecuencia PWM es comn en ambos mdulos. Sin embargo, en los que tu mencionas 18F45K22 he visto que es posible asociar cada mdulo a un timer distinto, por lo que podrs obtener las 2 frecuencias distintas que te han pedido. Las frmulas que doy para calcular la frecuencia PWM siguen siendo vlidas, pero ahora, en vez de usar exclusivamente el registro PR2 (asociado al TMR2) puedes usar un distinto PRx para el otro mdulo, asocindolo a un segundo timer TRMx. UN saludo,

picfernalia.blogspot.mx/2012/06/modulacion-pwm-pulse-width-modulation.html

11/14

11/12/13
Antonio. Responder

Tutoriales PIC: Modulacin PWM (Pulse Width Modulation)

Gabriel Iiguez 22 de noviembre de 2013 06:54 Hola buenas noches,, espero me puedas ayudar, estoy realizando un proyecto con el PIC16F887 en el que debo controlar con el PWM un foco convencional, solo que este prende y apaga en lugar de ir subiendo la intensidad, para ello tengo un led a la salida del PWM del micro para monitorear y este si lo hace como debe de ser, solo que con el foco conectado prende y apaga solamente. Como el foco lleva corriente alterna, hice un circuto analogico de un optocoplador (MOC3011) con un triac (MAC15A6G). Gracias!! Responder Respuestas Antonio 22 de noviembre de 2013 09:49

Si en el LED de control ves la subida y bajada gradual de intensidad es que la parte del programa del PIC es correcta. Lo que estari fallando en tu caso seria el circuito interfaz con el foco. Dados mis casi nulos conocimientos de electrnica, dar consejos sobre circuitos sera temerario. Si es un circuito de electrnica de potencia como es tu caso, entrara en el terreno de la negligencia criminal. De todas formas si busco en google con PWM, dimmer, TRIAC me salen numerosos ejemplos, aunque no se si en tu caso es obligado hacerlo con los componentes que indicas. De hecho en varios ejemplos que he visto no usan PWM. Simplemente detectan los pasos por cero del voltaje de la red y en ese momento activan el TRIAC con un pin de control, manteniendolo alto durante el porcentaje adecuado del medio ciclo de la red. Si la red va a 50 Hz un ciclo son 20 ms y medio ciclo 10 ms. El tiempo e activacin del triac estara entre 0 ms (0%) y 10 ms (100%). Espero que esto te sirva de algo, Antonio Antonio

Gabriel Iiguez 23 de noviembre de 2013 05:43 Gracias por tu respuesta Antonio, me sirvi de mucho, de hecho voy a empezar a detectar los cruces por cero de la seal alterna y saber el periodo de la seal, para as saber donde activar el TRIAC. Si logro terminar este proyecto te comparto la solucin. Muchas gracias y saludos. Responder

Annimo 24 de noviembre de 2013 10:52 buenas noches soy nuevo en esto de los microcontroladores, tengo un proyecto es un inversor monofasico medio puente y debo controlar la conmutacin de los 2 transistores he leido que puedo generar mi seal PWM y que hay una funcin en el pic que me genera la seal complementaria, y tambien he leido que se le puede asignar ya los tiempos muertos y ya con esas seales pienso enviarlas a un driver IR2111 que me haran el cambio de referencia a tierra e invertiran la polarizacion de la seal complementaria logrando asi el desfase a 180 que se necesita para que no conmuten al mismo tiempo los transistores y con el tiempo muerto asignado para que no se corto circuiten, te agradecera mucho me pudieras orientar un poco cualquier informacion de verdad seria de gran ayuda ya que no encuentro ni ejemplos de como implementar estas seales, muy poca informacin de lo que he investigado justo lo que necesito es aplicar este modo HALF-BRIDGE OUTPUT MODE ojala me puedas orientar gracias Responder Respuestas Antonio 25 de noviembre de 2013 09:40

La mejor documentacin sobre lo que quieres hacer la encontraras en el datasheet del PIC que vayas a usar (en la seccin correspondiente a EPWM (Enhanced PWM). Por ejemplo, en el caso de la familia PIC4520 est en las pginas 147 a 152 del manual. Bsicamente debes (asumiendo que usar el mdulo PWM1 * Selecciona el mdulo PWM: poner los 4 bits menos significativos de CCP1CON a 11xx

picfernalia.blogspot.mx/2012/06/modulacion-pwm-pulse-width-modulation.html

12/14

11/12/13

Tutoriales PIC: Modulacin PWM (Pulse Width Modulation)


* Configurar el mdulo PWM en modo HalfBridge (poniendo los 2 bits ms significativos de CCP1CON a 10) * Configurar periodo y duty del PWM (esto es igual que lo explicado en esta entrada). * Configurar tiempos muertos usando los 7 bits menos significativos de PWM1CON: delay = 4*Tosc*PWM1CON Los pines de salida para las seales complementarias sern RC2 y RD5. Ambos tienen que ser declarados de salida con los correspondientes registros TRISC y TRISD. Un saludo, Antonio Responder

Annimo 4 de diciembre de 2013 17:23 Buenas tardes, Antonio: Felicidades en primer lugar por tu trabajo. Mi pregunta est relacionada con el control PWM de un motor de continua mediante un hardware halfbridge. La idea es utilizar un pic y configurar dos salidas PxA y PxB en modo half-bridge y con una banda de retraso (dead-band delay mode) para evitar cortos. Pero tengo una duda sobre el control del puente. Entiendo que cuando PxA est a nivel alto y PxB a nivel bajo el motor gira en un sentido y con PxA a nivel bajo y PxB a nivel alto se invierte el sentido. Sin embargo no entiendo el comportamiento cuando estas conmutaciones son a alta frecuencia, supongo que ser porque depende de la amplitud de la seal PWM, si PxA est ms tiempo a nivel alto que a nivel bajo gira en un sentido y si est ms tiempo a nivel bajo girar en el contrario pero no entiendo muy bien como se adapta el motor a esos cambios tan rpido en la polarizacin. Entiendo los cambios en amplitud que el motor ve como un promedio pero no los cambios en la polarizacin. Te agradecera que me confirmases mi sospecha o me indiques como funciona realmente esta configuracin. Saludos. Jos ngel. Responder Respuestas Antonio 8 de diciembre de 2013 15:04

Buena pregunta. Yo tambin entiendo mejor el concepto de modular la velocidad con PWM usando el montaje que llamo A) en el post. Encendemos el motor durante un rato (% del ciclo) y lo apagamos durante el resto, dejando que siga girando por inercia. Si la frecuencia del PWM es lenta veremos que la velocidad baja, pero a las frecuencias que estamos usando (del orden de 10KHz) ese efecto ser inapreciable. En cambio la idea de "decirle" al motor que gire en un sentido y luego en otro para que se mantenga quieto (opcin B con duty del 50%) es poco intuitiva. Al igual que antes, si lo hacemos a frecuencias bajas veramos al motor girar en ambos sentidos, pero a medida que aumentamos la frecuencia el movimiento pasa a ser una vibracin para finalmente desaparecer cuando el motor es incapaz de seguirlo. En ese caso (motor parado) la situacin es como alimentar un circuito LR (Inductancia y Resistencia del motor) con corriente alterna de alta frecuencia. La forma en que yo lo visualizo es que si en esas circunstancias subo p.e. el duty a 80% (esto es, durante un 80% aplico V al motor y durante 20% aplico -V) durante un 40% del ciclo tengo una corriente alterna equilibrada (20% + y 20% -) que no produce ningn efecto. El resto del ciclo (60%) estoy aplicando una corriente DC positiva, que provoca el giro en el sentido correspondiente. No se si esto tiene mucho sentido o te aclara algo. Estoy de acuerdo contigo en que lo de invertir polaridades es mucho menos intuitivo. De hecho, la primera vez que vi este enfoque (en una app note de microchip) como no lo vea claro acud a las ecuaciones diferenciales de un motor DC: L dI/dt = V - R I - K w J dw/dt = K I - b w donde I es intensidad, V voltaje aplicado, R Y L resistencia e inductancia del motor, J = momento de inercia, K = cte motor (V/rads) y b un coeficiente de friccin. w es la velocidad angular del motor. Con este modelo puedes resolver las ecs. diferenciales para diferentes voltajes y comprobar por ejemplo que la velocidad alcanzada por el motor al 60% en modo unipolar(opcin A) es la misma que si invertimos la polaridad (OPcion B) y usamos un duty del 80%. Tambin puedes comprobar como las oscilaciones dentro de un ciclo van desapareciendo al aumentar la frecuencia del voltaje aplicado. Un saludo, Antonio

picfernalia.blogspot.mx/2012/06/modulacion-pwm-pulse-width-modulation.html

13/14

11/12/13
Responder

Tutoriales PIC: Modulacin PWM (Pulse Width Modulation)

Introduce tu comentario...

Comentar como:

Cuenta de Google

Publicar

Vista previa

Entrada ms reciente
Suscribirse a: Enviar comentarios (Atom)

Pgina principal

Entrada antigua

Plantilla Picture Window. Con la tecnologa de Blogger.

picfernalia.blogspot.mx/2012/06/modulacion-pwm-pulse-width-modulation.html

14/14