PIC12F683 Variable PWM duty cycle

Discussion in 'Programmer's Corner' started by simo_x, May 9, 2011.

  1. simo_x

    Thread Starter Member

    Dec 23, 2010
    200
    6
    Hi all,

    I am programmig a dimmer for a 12V lamp with a PIC12F683 with duty cycle controlled by 2 button switch connected as PULL UP to GP5 (to decrease the duty cycle) & GP4 (to increase it).

    The PWM period is 312.5Hz, Internal clock oscillator is 4Mhz so Tosc is 0.25us

    PWM Period = [(PR2 + 1) ] · 4 · Tosc · TMR2Prescaler

    Taking a TMR2 prescaler of 16

    0.0032s = [(x + 1) ] · 16u
    PR2 = 0xC7
    T2CON = 0x03

    I started writing the program, which has to be written in Assembly language, but I have a problem.
    The register CCPR1L can't be changed during the program (has I know) so I use a general purpose register which I call dcycle.
    Normally, I just want to test if GP4 or GP5 are to logical 0 and than control dcycle and than store the variable in CCPR1L, but, if this last register cannot be changed, is obvious that maybe my idea will not works.. Or I am wrong?

    However, I my program which I am simulating through Proteus which seems to be a good PIC simulator (it always worked later with real PIC simulation)
    program works until the register settings, than PWM doesn't work no more..
    I post the code where I marked the line until the program works.
    Code ( (Unknown Language)):
    1.  
    2. INCLUDE P12F683.INC
    3. LIST p = 12F683
    4.  
    5. __CONFIG _CP_OFF&_CPD_OFF&_BOD_ON&_PWRTE_ON&_WDT_OFF&_HS_OSC
    6.  
    7. CBLOCK    0x20
    8.     dcycle                                ;variable duty cycle register
    9. ENDC
    10.  
    11. ;            configuration settings
    12.  
    13.             org    0x0000
    14.  
    15.             bsf        STATUS,    RP0        ; step to
    16.             bcf        STATUS,    RP1        ; bank 1
    17.    
    18.             clrf        OPTION_REG        
    19.  
    20.             movlw        0x30                ;enable pull up interrupt
    21.             movwf        IOC                ;for GP4 & GP5
    22.  
    23.             movlw        0xc7                ;configure PR2
    24.             movwf        PR2                
    25.  
    26.             clrf        ANSEL                ;set all pin as Digital Inputs
    27.  
    28.             movlw        0x3b                ;set GP4 as input
    29.             movwf        TRISIO                ;and GP2/CCP1 as output
    30.  
    31.             bcf        STATUS, RP0            ;step to bank 0
    32.  
    33.             movlw        0x07
    34.             movwf        CMCON0            
    35.  
    36.             movlw        0x03                ;set T2CON with prescaler 1:16
    37.             movwf        T2CON                ;and turn on T2
    38.            
    39.             movlw        0x3c
    40.             movwf        CCP1CON
    41.  
    42.            
    43.  
    44. start:            
    45.             movwf    dcycle
    46.             movwf    CCPR1L
    47.  
    48.  
    49. [B]             goto    $
    50.             end
    51.             ;program works just until here[/B]
    52.  
    53. main:
    54.             movwf    CCPR1L
    55.        
    56.             btfss    GPIO,    4                ;test if GP4 is 0
    57.             incf    dcycle, 1                ;if so increment dcycle
    58.  
    59.            
    60.             btfss    GPIO,    5                ;test if GP5 is 0
    61.             decf    dcycle,    1                ;if so decrement dcycle
    62.  
    63.             movf    dcycle,    W                ;move dcycle to W
    64.             goto    start                    
    65.             end
    66.  
    I am thinking the way I am structuring the program is not correct..
    How can I solve this problem? It's the first time I use PWM with PIC..

    Thank you for your help
    Regards,
    Simo
     
    Last edited: May 9, 2011
  2. ding_nz

    New Member

    May 8, 2011
    1
    0
    I have looked over some of my old code for PWM output on the PIC - Mine was a PIC 16F73

    I was able to write to the CCPR1L register to set the duty cycle

    I think that the problem you have is in the in the 2 lines after start:

    You have :

    Code ( (Unknown Language)):
    1. start:            
    2.             movwf    dcycle
    3.             movwf    CCPR1L
    When it should be:

    Code ( (Unknown Language)):
    1. start:            
    2.             movfw    dcycle   ; Put duty cycle value into W register
    3.             movwf    CCPR1L  ; Move W register into CCPR1L
    You are not moving the value of dcycle into the working register other than that you don't appear to be doing any thing wrong for the PWM module not to work

    I did notice the following

    Also you enabling the interupt on change function not the weak pull ups as intended?

    What oscillator do you plan on using as the GPIO's you have chosen are shared with the oscillator pins. In order to use them as inputs you need to change the _HS_OSC in you configuration word to _INTOSCIO or select 2 different inputs to use.

    I simulated the code with your configuration word then changed the oscillator configuration and found the following:

    With the _HS_OSC configuration the inputs were ignored so the value of dcycle was decremented then incremented for a net change of 0 - dcycle stayed the same

    With the _INTOSCIO configuration the inputs responded and dcycle ws controllable

    Hope that this helps I know that its alot of information but it should help get you on the right track

    Dan
     
  3. simo_x

    Thread Starter Member

    Dec 23, 2010
    200
    6
    Hi Dan, I read your response. Thank You very much for your interest ;)

    I will try later to change the details from you suggested about oscillator..
    I will update the post.

    ;)
    See you later
     
  4. simo_x

    Thread Starter Member

    Dec 23, 2010
    200
    6
    Hi Dan, it doesn't work. I changed to HS_OSC to _INTOSC, tried with _INTOSCIO, but nothing.. Also the MCLEAR is disabled...

    I can't change the pins because the circuit requires that pinout.
    The duty cycle control pins are set to enable interrupt on change, not to wake up the device..

    Maybe it's because I need to work just with interrupts.. I am trying.. Did you control the duty cycle between interrupts or during normal execution of the program?

    Regards,
    Simo
     
  5. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    If you want to use interrupts a good place to start is the assembler template for your PIC which should be found somewhere like:
    c:\program files\microchip\MPASM suite\template\code
     
  6. simo_x

    Thread Starter Member

    Dec 23, 2010
    200
    6
    Hi Markd77, I took a look to the file, thank you I didn' t know the example, but interrupt vector was not a secret yet ;)
    In addition to the previous code, I am implementing this section
    Code ( (Unknown Language)):
    1.  
    2.             ;at starting
    3.             org    0x000
    4.             goto    settings
    5.             org    0x004
    6.             goto    INT_ON_CHANGE
    7.  
    8.  
    9. ;after configuration & goto $
    10.  
    11. INT_ON_CHANGE:
    12.             bsf        INTCON,    0
    13.             movf    CCPR1L,    W
    14.  
    15.             btfss    GPIO,    4
    16.             call    inc
    17.  
    18.             btfss    GPIO,    5
    19.             call    dec
    20.  
    21.             retfie
    22.  
    23. inc
    24.             addlw    0x64
    25.             movwf    CCPR1L
    26.             bcf        INTCON,    0
    27.             return
    28.  
    29. dec
    30.             sublw    0x64
    31.             movwf    CCPR1L
    32.             bcf        INTCON,    0
    33.             return
    34.  
    Which works.. I can increase or decrease the duty cycle, 0x64 = 100 is the interval test value, and I'll have to check for do not overflow 100% or 0% later... Now it's half past two in the morning here and I need to rest a little, to be spry again tomorrow morning :)

    In simulation, the program seems to be quiet slow respect other PIC programs.. Should be the PWM simulation that over run the CPU (considering I run it in VBox)..

    Maybe there is another way to improve the program section?

    Thank you
    Regards,
    Simon
     
    Last edited: May 9, 2011
Loading...