PWM in pic18f4520 Help

Discussion in 'Embedded Systems and Microcontrollers' started by foux16, Nov 23, 2015.

  1. foux16

    Thread Starter New Member

    Nov 19, 2015
    Hello guys, First really thanks for the attention. Well going to the subject of my doubts, I'm planing to do a LED dimmer using PWM modulation in a PIC18f4520 using assembly language as my final project. I'm varying the duty cycle from 0 to 100% using a button that increases the duty cycle in 25%. But i'm having problems to make my circuit work, maybe because of some questions that I still don't know the answers or maybe because I programed wrongly, but I really hope that you guys can help me to overcome these issues.
    So first I did some research about PWM to understand how it works, and after got some understanding about the subject I tried to implement the process in the pic18 using the steps provided by the datasheet of the PIC18f4520 to set the PWM mode. But I still have some questions.
    I. How do I know the proper PWM frequency that I will need to my project? I just need choose any frequency and check if it works?!
    II. I'm thinking to use the internal clock of the PIC18f which is 8Mhz, for these application. Is this possible or do I need to use a external clock for my project? If yes how can I set this in my code?

    OBS: After wired my Pic and test my output in PORTB with a oscilloscope i didn't got nothing but noisy. It is like the PWM setup to PORTB isn't working. I really don't know what else to do, please anybody could help me with these big problem?!

    The result of my work is the following code:

    Code (Text):
    1. Main:
    2.     call    pwm_setup
    3.     goto    loop
    5. pwm_setup
    6.     movlw    0x7F                     ;PR2 = Period = 1/F Setting PWM period as 127
    7.     movwf    PR2
    9.     movlw    0x00                      ;Set PWM duty cicle as a initial value of 0%
    10.     movwf    CCPR2L                ;This register contains the 8MSbit of the dutty cicle
    11.     bcf          CCP2CON, 5        ;Clear bit 5 (bits 5 and 4 are the LSbit  
    12.     bcf          CCP2CON, 4        ;Clear bit 4
    14.     clrf    PORTB                        ;Clear PORTB
    15.     bcf     TRISB, 3                     ;Make RB3 output
    16.     bsf     TRISB, 0                     ;Make RB0 as input
    18.     movlw     0x07                      ;TMR2 = on, prescale = 1:16
    19.     movwf     T2CON
    20.     movlw     0x0C
    21.     movwf    CCP2CON              ;turn on pwm
    23.     return
    25. loop
    26.     clrwdt
    27.     btfsc      PORTB,0                ;testing RB0(Button) was pressed
    28.     call        inc                           ;if was pressed call inc
    29.     goto      loop                         ;If not Check again
    31. inc                                             ;Incremeting the Dutty cycle in 25%
    32.     movlw     0x20          
    33.     addwf     CCPR1L,1
    34. return
    36. END
  2. JohnInTX


    Jun 26, 2012
    Hi and welcome to AAC!

    On the 4520, the default CCP2 is RC1. I don't see where you have changed CCP2MX in CONFIG so your output is going to be to RC1 - assuming it is set up right. It's very important to FULLY specify ALL config bits, every time. You also should specify ALL IO inits as well.

    To make this all work, you set up TMR2/PR2 to generate the PWM period as a number of counts. The duty cycle is specified by loading a count into CCPR2L (and CCP2CON <5,4> if you want 10 bit resolution). That value is NOT in %, it is in counts that represent a fraction of the PWM period counts.

    I would start by just setting up a 25% duty cycle and running that. When that works, add the code that modifies the duty cycle.

    Some starting numbers:
    8MHz oscillator
    Prescaler = 16
    PR2 = 124
    Gives a PWM period of 1KHz.
    CCPR1L= 31 gives about 25% duty cycle

    Have fun.
    Last edited: Nov 23, 2015
    foux16 likes this.