Vous êtes sur la page 1sur 3

Generar PWM TIMER 

Ahora  vamos  a  generar  PWM  desde  un  TIMER  que  es  mejor  que  con  demoras  en  donde 
dedicamos al uC solo a las demoras. 

Como  en  el  caso  anterior  debemos  determinar  la  frecuencia  de  trabajo,  y  esta  vez  vamos  a 
trabajar a 300Hz, que normalmente si utilizamos uno de los módulos CCP  tendríamos que trabajar 
con  un  cristal  de  4MHz  pero  si  trabajamos  con  un  cristal  de  20MHz  o  si  el  uC  no  cuenta  con  el 
módulo CCP. 

Determinamos el periodo.  

1
p
f
1
p  
300
p  0, 00333s
p  3,33ms

Ahora utilizaremos un TIMER que puede ser cualquiera pero depende de nuestra aplicación para 
saber cuál utilizaremos, ya que sería mejor utilizar uno sin pre‐escaler o post‐escaler  utilizaremos 
un TIMER de 16 bits.  

Ttiempo  (65535  VTMR 0 ) * 4TOSC *V pre divisor


1
3,33ms  (65535  VTMR 0 ) * 4 *1
20 Mhz
3,33ms  (65535  VTMR 0 ) * 200ns
3,33ms
 (65535  VTMR 0 )  
200ns
16650  65535  VTMR 0
VTMR 0  65535  16650
VTMR 0  65535  16650
VTMR 0  48886

Entonces el valor a precargar en el TIMER es  48886 y el valor correspondiente a 3,33ms es 16650. 
Lo que quiere decir que para un duty cycle de 0% el valor es de 0 y para un 100% el valor es 16650 
para un 50% es de  8325. 

 
 

Entonces  si  cargamos  el  TMR1  con  el  valor  máximo  (65535)  menos  el  Ciclo  Útil  el  TIMER  se 
desbordará e ira a interrupción al completar el Ciclo Útil. TMR1= TMAX‐CICLO_UTIL para el valor 
en alto. 

Luego  debemos  cargar  el  tiempo  que  falta  para  completar  el  periodo    TMR1=  TMAX‐(PERIODO‐ 
CICLO_UTIL) con esto se completa el tiempo en bajo.  

Finalmente para ver como varia la señal haremos: 

WHILE TRUE    'bucle infinito 
     FOR  CICLO_UTIL=0 to  16650 
      delay_ms(1) 
     next CICLO_UTIL 
WEND 
 

Esto solo es una muestra básica de cómo se puede hacer hay otras maneras para poder generar 
varios  PWM  como  por  ejemplo  para  manejar  varios  servomotores,  como  práctica  les  propongo 
generar 3PWM para controlar un LED RGB.  

 
program PWM_TIMER

' Declarations section


symbol PWM_1 = PORTD.0 'defino para mi programa el puerto D0 como PWM1
DIM TEMPORAL AS WORD
DIM HLFLAG AS BYTE 'Bandera para saber si esta en alto o bajo
DIM CICLO_UTIL AS INTEGER ' valor del ciclo util
CONST TMAX AS WORD = 65535 ' FFFF del TIMER
const periodo as word = 16650 'VALOR DE 3.3ms

SUB PROCEDURE INTERRUPT


IF TESTBIT(PIR1,TMR1If) = 1 then
IF HLFLAG= 1 THEN
PWM_1 = 0
TEMPORAL=TMAX-periodo+ CICLO_UTIL
TMR1L=TEMPORAL
TEMPORAL=TEMPORAL>>8
TMR1H=TEMPORAL
HLFLAG=0
ELSE
PWM_1 = 1
TEMPORAL=TMAX-CICLO_UTIL
TMR1L=TEMPORAL
TEMPORAL=TEMPORAL>>8
TMR1H=TEMPORAL
HLFLAG=1
END IF
clearbit(PIR1,TMR1If)
end if
END SUB
main:
' Main program
TRISD.0 = 0
'Configuracion de TIMMER
INTCON=%11000000
T1CON=0
SETBIT(PIE1,TMR1IE)
CICLO_UTIL=10000
' cargo DUTY_CYCLE
TEMPORAL= TMAX-CICLO_UTIL
TMR1L=TEMPORAL
TEMPORAL=TEMPORAL>>8
TMR1H=TEMPORAL
PWM_1=1 'pwm en alto
HLFLAG=1 'bandera de ALTO
SETBIT(T1CON,0) 'prendo el timer
WHILE TRUE 'bucle infinito
FOR CICLO_UTIL=0 to 16650
delay_ms(1)
next CICLO_UTIL
WEND
end.

Vous aimerez peut-être aussi