10

Generando señales PWM por software

Ante la necesidad de armar un circuito para controlar LEDs RGB con un microcontrolador PIC16F627A me encuentro con que este chip posee un solo módulo PWM. La solución es generar las señales PWM mediante software, algo sencillo de implementar y que realmente funciona muy bien siempre y cuando la frecuencia de la señal no sea critica.

Tomando como base el documento que encontramos en el foro TodoPIC podemos resumir la lógica a lo siguiente:

1. Configuramos la interrupción por timer 0.
2. Inicializamos un variable «contador» con valor 0.
3. Inicializamos dos variables más: «TPWM» (período) y «DUTY» (ciclo de trabajo).
4. Cargamos TMR0 con el valor 254.
5. Definimos un bit de salida con el valor 1, el pin por donde vamos a sacar la señal PWM.

Dentro de la rutina de interrupción lo que hacemos es incrementar el contador en una unidad. Si este es igual al ciclo de trabajo manda el pin de salida a 0, si en cambio es igual al período manda el pin de salida a 1. Modificandole el valor a la variable DUTY cambiamos el tiempo de encendido de la señal.


Adjunto el código escrito en BASIC de PIC Simulator IDE:

'CONTROLANDO LEDS RGB VIA PWM POR SOFTWARE
'AUTOMATISMOS MAR DEL PLATA - 9 DE JULIO DE 2012
 
PORTA = %00000001
contador = %00000000
tpwm = %00000000
duty = %00000000
 
main:
tpwm = 4
duty = 3
End                                               
 
On Interrupt
 
contador = contador + 1
If contador = duty Then RA.0 = 0
If contador = tpwm Then
RA.0 = 1
contador = 0
Endif
 
TMR0 = 254
INTCON.T0IF = 0  'habilita nuevamente la interrupción
Resume

Por último agrego una captura de pantalla tomada con el analizador Logic donde podemos ver tres señales PWM generadas por software funcionando a una frecuencia de aproximadamente 1,4KHz y con distintos ciclos de trabajo. Cualquier duda o sugerencia es bienvenida vía comentarios!

Lucas Martin

Electrónico por sobre todas las cosas. Disfrutando del Hardware y Software Open Source.

10 comentarios

  1. Pingback: Bitacoras.com
  2. Muy bueno Martín; Podrias sumarle que con muy pocas reformas en la interrupcion, podes armar hasta un sencillo controlador RGB…
    Me gusto mucho el analizador… Precio? donde lo conseguistes? correra en XP y 7 starter? Un abrazo

  3. Hola!
    Primero felicitarte por tu pagina es muy buena y me ha ayudado bastante. Por otro lado yo estoy programando en XC8 y quiero controlar un led RGB pero en XC8 no se si tu puedes ayudarme en esto.
    Saludos

  4. hola! yo trato de hacer, algo asi pero asm, con el pic 16f887….. llevo esto
    list p=16f887
    #include
    __CONFIG _CONFIG1, _LVP_OFF & _FCMEN_ON & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
    __CONFIG _CONFIG2, _WRT_OFF & _BOR21V
    org 00H
    BANKSEL ANSEL
    clrf ANSEL
    clrf ANSELH
    BANKSEL TRISD
    clrf TRISA
    clrf TRISB
    clrf TRISC
    clrf TRISD
    BANKSEL PORTA
    clrf PORTB
    clrf PORTC
    clrf PORTD

    BANKSEL TMR0
    Movlw .254
    Movwf TMR0
    BANKSEL OPTION_REG
    Movlw b’00000001′
    Movwf OPTION_REG
    BANKSEL INTCON
    Movlw b’10100000′
    Movwf INTCON
    CBLOCK 20H
    contador, TPWM, DUT
    ENDC

    Movlw .0
    Movwf contador
    Movlw .100
    Movwf TPWM
    Movlw .20
    Movwf DUT
    org 21

    Inicio
    BANKSEL INTCON
    btfss INTCON,2
    goto $+5
    BANKSEL TMR0
    Movlw .254
    Movwf TMR0
    bsf PORTB,1
    Incf contador,f
    Movlw 14H
    subwf contador,w
    btfss STATUS,Z
    goto Incrementa
    bsf PORTB,1
    ochenta
    bsf STATUS,Z
    Incf contador,f
    Movlw 64H
    subwf contador,w
    Btfss STATUS,Z
    goto ochenta
    BANKSEL INTCON
    btfss INTCON,2
    goto $+5
    BANKSEL TMR0
    Movlw .254
    Movwf TMR0
    goto Inicio
    end
    lo que noc, es si este codigo me sirve para la habilitar la interrupcion, o si en verdad utilizo el tmr0 :/ espero puedan ayudar! gracias!

  5. Que tal Lucas Martin!
    Tengo un par de dudas sobre el codigo haber si me las puedes resolver son las siguientes:
    1.- por que cargar el TMR0 con 254 si la variable va de 0 a 255 por que no otro valor que
    vendria significando cargarlo con ese valor.
    2.- En el main pones TPWM=4,DUTY=3 esos valores como los sacaste,o de que formula y a que
    frecuencia corresponden.
    3.- Por que iniciar el PORTB.1=1 en alto.
    Gracias haber si me puedes responder…

  6. Este codigo no funciona lo probé y nada ya que estoy intentando hacer un temporizador con el tmr0 y pic16f887 si alguien puede colaburar ya que uso pic simulator ide

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.