PDA

View Full Version : pic18f252 PWM duty update : Help



iw2fvo
- 30th September 2013, 12:57
Good day to all of you in the forum,
I wrote this simple program that would sweep the duty cycle of a 10 Khz frequency PWM on PIC18F252.
I found that the duty monitored by a scope is updated every 4 secs instead of 1 sec as wrote in the Basic program.

DUTY VAR word
TRISC.2 = 0

Main:

FOR DUTY=260 TO 325

CCPR1L = duty>>2

ccp1con.bit4=duty.bit0
ccp1con.bit5=duty.bit1

PR2 = 200 ' Set PWM Period
CCP1CON = %00001100 ' Select PWM Mode
T2CON = %00000101 ' Timer2 = ON + 1:4 prescale ( about 10 KHz )

debug dec duty, 13 ,10
pause 1000 ' change duty every one sec.

next duty
goto main

I need a duty to be changed every one sec: is there any help on the matter ?
What am I doing wrong ?
Thanks for any assistance
regards,
Ambrogio

HenrikOlsson
- 30th September 2013, 18:53
Hi,
You are overwriting the two LSB's of the dutycycle because you have CCP1CON = %00001100 within the FOR/NEXT loop. So you're actually only updating the dutycycle once every four times thru the loop.

Move the initialisation of the CCP module outside of the FOR/NEXT loop.


DUTY VAR word
TRISC.2 = 0

PR2 = 200 ' Set PWM Period
CCP1CON = %00001100 ' Select PWM Mode
T2CON = %00000101 ' Timer2 = ON + 1:4 prescale ( about 10 KHz )

Main:
FOR DUTY=260 TO 325
ccp1con.bit4=duty.bit0
ccp1con.bit5=duty.bit1
CCPR1L = duty>>2
debug dec duty, 13 ,10
pause 1000 ' change duty every one sec.
next duty
goto main

/Henrik.

iw2fvo
- 30th September 2013, 19:13
Thanks a lot Henrik for the great help.
It is a very useful reply : it solved my problem.
best regards,
Ambrogio
IW2FVO , North Italy.

iw2fvo
- 9th October 2013, 12:30
I am having another issue with this PWM output.
I understand from the data sheet that the duty cycle should have a 10 bit resolution since my PIC runs at 40 Mhz and the PWM freq is 10 Khz.
The DC should then range from 0 to 1023 : I did try to sweep the DC in that way and I found that the output stays HI if the the DC is more then 800 ( plus or minus ): there is no more pulse : it is not a 10 bit ?!
What am I doing wrong ?
Any clarification for me ?
Thanks
regards,
Ambrogio

HenrikOlsson
- 9th October 2013, 19:25
Post the code you're actually using for that test and someone will most likely see what's going on.

iw2fvo
- 9th October 2013, 21:34
THIS IS THE CODE:

TRISC.2 = 0 ' PORTC.2 IS OUTPUT
PR2 = 200 ' Set PWM Period
CCP1CON = %00001100 ' Select PWM Mode
T2CON = %00000101 ' Timer2 = ON + 1:4 prescale ( about 10 KHz )

FOR DUTY=1 TO 1023
GOSUB READ_DATA ' READS ADC INPUT
GOSUB SERIAL_OUT ' SEND DATA TO SERIAL PORT FOR DISPLAY
ccp1con.bit4=duty.bit0
ccp1con.bit5=duty.bit1
CCPR1L = duty>>2
NEXT DUTY

THANKS
AMBROGIO

HenrikOlsson
- 10th October 2013, 06:10
Hi,
The reason is because you have PR2 set to 200.
Remember how the PWM generator works: Basically, the PWM cycle starts over when TMR2 equals PR2 and because TMR2 is concatenated with two more bits at the "low end" the available number of discrete dutycycles is PR2*4 or, in this case, 800.

/Henrik.

iw2fvo
- 10th October 2013, 07:11
Henrik,
thanks for the interest.
I have read the data sheet again but it is still not clear to me: could you please spend few more words for me ?
( Will I have 10 bit resolution if PR2 is set to 256 since 256*4 =1023 : is this assumption correct ? ).
Thanks for your time
bst rgds,
Ambrogio

HenrikOlsson
- 10th October 2013, 07:37
Hello,
Well, PR2 is 8 bits so you can only really set it to 255 but otherwise yes you're correct.
This will of course also change the frequency - there's always a tradeoff between frequency and resolution. If you need to "hit" 10kHz exactly then you'll have to live with ~9.5 bits of resolution or change your oscillator frequency to one that better matches your needs. Faster isn't always better.

/Henrik.

iw2fvo
- 11th October 2013, 07:05
Thanks Henrik: it is clear to me now.
Best regards,
Ambrogio
IW2FVO
North Italy