CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Setting up for PWM

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
davt



Joined: 07 Oct 2003
Posts: 66
Location: England

View user's profile Send private message

Setting up for PWM
PostPosted: Fri Feb 06, 2004 11:12 am     Reply with quote

Hi all

I am trying to use the PWM module in a 16F876 with a crystal frequency of of 20mhz.

What I want is a frequency of 50khz with 8 bit resolution.

I have got the PWM working but can only get 7 bits resolution at ~37khz.
I have set up the registers as follows:

t2con=0x04; // timer2 on, postscale=1

ccp1con=0x3c; // PWM on and lsb's set

pr2=0x82; // sets period

ccpr1l=0x10; // sets duty cycle

To give me a variable duty cycle I read a pot connected to A0 and after dividing by 8 pass the value to ccp1L to give me a variable pulse width - that bit works OK.

Could someone please help?
Thanks in advance.

Dave
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Feb 06, 2004 11:36 am     Reply with quote

You're not using the CCS functions and you're setting the registers
directly.

If you look at this chart, and if you can believe it, it says
that what you want should be possible:
http://www.piclist.com/techref/microchip/pwmrescalc.htm

The CCS manual says the set_pwm1_duty() function can take
a 10-bit value.
Quote:
Writes the 10-bit value to the PWM to set the duty. An
8-bit value may be used if the least significant bits are
not required.


In your code that writes directly to the registers, you've set the
bottom two bits as constants. So you're only going to get 8-bits
max, anyway.

You should use the CCS functions, and give them a 10-bit parameter.
davt



Joined: 07 Oct 2003
Posts: 66
Location: England

View user's profile Send private message

PWM
PostPosted: Fri Feb 06, 2004 3:44 pm     Reply with quote

Thanks for your reply PCM programmer.
Very Happy
8 bits resolution is all I require.
What I trying to achieve is to have a variable pulse width from almost zero to say 99%.
If I want a frequency of 50khz that is a period of 20us - if I divide by 255
I get 78ns per bit is this possible to achieve?
Many thanks for your time.

Dave
Ttelmah
Guest







Re: PWM
PostPosted: Fri Feb 06, 2004 4:22 pm     Reply with quote

davt wrote:
Thanks for your reply PCM programmer.
Very Happy
8 bits resolution is all I require.
What I trying to achieve is to have a variable pulse width from almost zero to say 99%.
If I want a frequency of 50khz that is a period of 20us - if I divide by 255
I get 78ns per bit is this possible to achieve?
Many thanks for your time.

Dave

Your problem is that you are not changing the least significant bits of the PWM duty. The CCPR1L register, holds eight bits of the duty cycle, but the two LSB's, are held in bits 4 and 5 of CCP1CON. You need to rotate your duty cycle value right by two bits, and put this into CCPR1L (as you are doing), and then mask the two low bits, and put these into CCP1CON. Without this, the CCP, runs in 'low resolution mode', which only gives just over 6 bits of resolution at the frequency you require.
At the end of the day, the 'set_ccp1_duty' function _does this_, and you are not going to make the code any smaller or neater, by going DIY...

Best Wishes
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: PWM
PostPosted: Fri Feb 06, 2004 4:31 pm     Reply with quote

davt wrote:
Thanks for your reply PCM programmer.
Very Happy
8 bits resolution is all I require.
What I trying to achieve is to have a variable pulse width from almost zero to say 99%.
If I want a frequency of 50khz that is a period of 20us - if I divide by 255
I get 78ns per bit is this possible to achieve?
Many thanks for your time.

Dave



Asume the timer increments once every 78ns with a prescaler of 1 you need a crystle speed of 1/.000000078 x 4 or 51.2 Mhz
That means you cant divide by 255 and get 50 Khz

This is doable.

Your timer actualy increments every 0.2 uS
If you simply setup the timer to overflow at 99 it will put a 50Khz wave out that has 1% control. Then simple set the puls width in % increments. Thats you best 50 Khz output.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Feb 06, 2004 6:13 pm     Reply with quote

The following test program will give you a 50 KHz pwm frequency,
with 400 steps available. This gives you better than 8-bit resolution.

The key is to use a 16-bit variable as the parameter in the
set_pwm1_duty() function. Notice that I'm using a variable, below.
If you use a constant, be sure to declare it as a "long" by putting
a "L" on the end. Example:

set_pwm1_duty(200L);

When you specify it as a 16-bit value, this tells the compiler
to use 10-bit resolution mode when it compiles the code.

Code:
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#use Delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

main()
{
int16 pwm_duty;

output_low(PIN_C2);    // Set CCP1 output low

setup_ccp1(CCP_PWM);   // Configure CCP1 as a PWM

setup_timer_2(T2_DIV_BY_1, 99, 1);         

pwm_duty = 200;      // Set for 50% duty cycle

set_pwm1_duty(pwm_duty);                   

while(1);
}
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Fri Feb 06, 2004 9:19 pm     Reply with quote

PCM programmer wrote:
The following test program will give you a 50 KHz pwm frequency,
with 400 steps available. This gives you better than 8-bit resolution.

The key is to use a 16-bit variable as the parameter in the
set_pwm1_duty() function. Notice that I'm using a variable, below.
If you use a constant, be sure to declare it as a "long" by putting
a "L" on the end. Example:

set_pwm1_duty(200L);

When you specify it as a 16-bit value, this tells the compiler
to use 10-bit resolution mode when it compiles the code.

Code:
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#use Delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

main()
{
int16 pwm_duty;

output_low(PIN_C2);    // Set CCP1 output low

setup_ccp1(CCP_PWM);   // Configure CCP1 as a PWM

setup_timer_2(T2_DIV_BY_1, 99, 1);         

pwm_duty = 200;      // Set for 50% duty cycle

set_pwm1_duty(pwm_duty);                   

while(1);
}


Is that going to toggle the output on quarter cycles of the instruction clock?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Feb 06, 2004 9:56 pm     Reply with quote

Quote:
Is that going to toggle the output on quarter cycles of the instruction clock?

Yes. Microchip doesn't come right out and say it as plainly as they
should, but yes, it will.

In AN594, Using the CCP Module, on page 2, Microchip says:
"This gives a maximum accuracy of Tosc (50 ns when the device
is operated at 20 MHz)".

In the 16F877 data sheet they say that in 10-bit mode, the two
LSB's come from the pre-scaler for Timer2. That pre-scaler
is clocked at Fosc, so that means that 2-bit counter will count
at a 50 ns rate. They have this small note at the bottom of
the PWM block diagram:

"Note 1: The 8-bit timer is concatenated with 2-bit internal Q
clock, or 2 bits of the prescaler, to create 10-bit time-base".
davt



Joined: 07 Oct 2003
Posts: 66
Location: England

View user's profile Send private message

setting up for PWM
PostPosted: Sat Feb 07, 2004 1:48 pm     Reply with quote

Very Happy
Many thanks for your help.
Have a good weekend!

Dave
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group