PWM in pic18f4520 Help

Thread Starter

foux16

Joined Nov 19, 2015
1
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:
Main:
call    pwm_setup
goto    loop

pwm_setup
movlw    0x7F                     ;PR2 = Period = 1/F Setting PWM period as 127
movwf    PR2

movlw    0x00                      ;Set PWM duty cicle as a initial value of 0%
movwf    CCPR2L                ;This register contains the 8MSbit of the dutty cicle
bcf          CCP2CON, 5        ;Clear bit 5 (bits 5 and 4 are the LSbit
bcf          CCP2CON, 4        ;Clear bit 4

clrf    PORTB                        ;Clear PORTB
bcf     TRISB, 3                     ;Make RB3 output
bsf     TRISB, 0                     ;Make RB0 as input

movlw     0x07                      ;TMR2 = on, prescale = 1:16
movwf     T2CON
movlw     0x0C
movwf    CCP2CON              ;turn on pwm

return

loop
clrwdt
btfsc      PORTB,0                ;testing RB0(Button) was pressed
call        inc                           ;if was pressed call inc
goto      loop                         ;If not Check again

inc                                             ;Incremeting the Dutty cycle in 25%
movlw     0x20
addwf     CCPR1L,1
return

END

JohnInTX

Joined Jun 26, 2012
4,654
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:
Similar threads