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 CCS Technical Support

PWM on 16F877
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Dec 03, 2003 6:34 pm     Reply with quote

Try the following program. Copy and paste it into MPLAB.

Remember that the PWM duty value should not be set greater
than the middle number in the setup_timer_2() function.
If you set it greater than that value, then you will get a constant
high level out. (100% duty cycle)

Code:
#include <16F877.h>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)

main()
{
output_low(PIN_C1);   // Set CCP2 output low
output_low(PIN_C2);   // Set CCP1 output low

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

setup_timer_2(T2_DIV_BY_16, 124, 1);  // 500 Hz     
set_pwm1_duty(31);                    // 25% duty cycle on pin C2
set_pwm2_duty(62);                    // 50% duty cycle on pin C1

while(1);  // Prevent PIC from going to sleep  (Important !)
}


---
Edited to put the code in a Code Block.


Last edited by PCM programmer on Sun Dec 23, 2007 4:26 pm; edited 1 time in total
crushneck



Joined: 27 Nov 2005
Posts: 29

View user's profile Send private message MSN Messenger

PostPosted: Thu Dec 29, 2005 12:35 am     Reply with quote

How to make setup_timer_2 to 200Khz??im using it to trigger the MOSFET dc/dc....

Quote:
#include <16F877.h>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)

main()
{
output_low(PIN_C1); // Set CCP2 output low
output_low(PIN_C2); // Set CCP1 output low

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

setup_timer_2(T2_DIV_BY_16, 124, 1); // 500 Hz <<???
set_pwm1_duty(31); // 25% duty cycle on pin C2
set_pwm2_duty(62); // 50% duty cycle on pin C1

while(1); // Prevent PIC from going to sleep (Important !)
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Dec 29, 2005 4:23 pm     Reply with quote

Download Microchip Reference manual for CCP module:
http://ww1.microchip.com/downloads/en/DeviceDoc/31014a.pdf
Go to page 10. It has a chart which shows Timer2 pre-scaler
and the PR2 value to get a PWM frequency of approximately 200 KHz.
Plug those values into the 1st and 2nd parameters of the CCS
setup_timer_2() function. Leave the 3rd parameter = 1.
You must use a 20 MHz crystal for this example. Even so, you
will only have about 5 bits of resolution on your PWM duty cycle.
vsmguy



Joined: 13 Jan 2007
Posts: 91

View user's profile Send private message Visit poster's website

PostPosted: Sun Jan 14, 2007 11:43 am     Reply with quote

PCM programmer wrote:


Remember that the PWM duty value should not be set greater
than the middle number in the setup_timer_2() function.
If you set it greater than that value, then you will get a constant
high level out. (100% duty cycle)


"PCM programmer",

sorry to bring back an ancient thread, but this is related to some problem's I am facing.

I am running PIC16F877A@20Mhz and wish to generate constant PWM Freq @ 1250 Hz but with 0% to 100% duty cycle.

For that the code is :
Code:

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

   setup_timer_2(T2_DIV_BY_16, 249, 1);
   set_pwm1_duty(500); /* Init to 50% */


Does that mean I don't get a 50% duty cycle in the first place ?
If what you say is correct across all PICs, then for the above configuration, I cannot set set_pwm1_duty() to more than 249 (which means a 25% duty cycle).

Am I right ? Or is this an issue only for 877/16f ?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jan 14, 2007 11:54 am     Reply with quote

The duty value is a fraction of the middle number in setup_timer_2().
Look at the example program.

31/124 = 25% duty cycle

62/124 = 50% duty cycle

In your modified code, you have picked 249 as the middle number.
So in the same way as above, you can choose values for 25% and 50%.
vsmguy



Joined: 13 Jan 2007
Posts: 91

View user's profile Send private message Visit poster's website

PostPosted: Sun Jan 14, 2007 12:02 pm     Reply with quote

OK... so I just use percentage of the timer value to set the duty cycle ..

That means I do not get 0% to 100% steps in practice, because some percentages will have the same period when the floating point value value is truncated to integer . Is that correct ?

In that case, there is a tool called PWMWizard on this board which gives incorrect PWM Duty cycle values for my case.. the OP should be notified...

Could you, "PCM Programmer" please verify if that tool is giving correct output for this case.. I think not..
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jan 14, 2007 12:11 pm     Reply with quote

There is no floating point used in the PWM functions. It's all unsigned
integers.

I have not downloaded the other guy's PWM program because I am
very cautious about running strange programs. I don't want to take
a chance on getting a computer virus.
vsmguy



Joined: 13 Jan 2007
Posts: 91

View user's profile Send private message Visit poster's website

PostPosted: Sun Jan 14, 2007 12:24 pm     Reply with quote

I do the calculations by hand and truncate the floating point values I get to integers before feeding it to the CCS PWM function.

That was the floating point value I was talking about.

@PCM : Could you have a go at answering my thread on PWM channels and duty cycle ?
vsmguy



Joined: 13 Jan 2007
Posts: 91

View user's profile Send private message Visit poster's website

PostPosted: Sun Jan 14, 2007 12:52 pm     Reply with quote

@PCM : I am amazed at your competency. I have seen such not even in very "big name" semiconductor companies (National and TI are an exception).

Are you a Microchip employee ? Feel free to ignore this question.

Do you have a website/blog ?

BTW - could you check out the PWMWizard program - it's free from Malware - I know. I ran it.

See if I am right about it being buggy.. I already mad e a wring BUG report.. don't wanna upset more nerves around here Smile
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jan 14, 2007 1:14 pm     Reply with quote

I think there are other people on this forum that know much more
than I do. They are very knowledgeable on interrupt issues, ethernet,
bootloaders, and much more.

I don't want to look at the PWMwizard because to me, the risk is
still there and the personal gain of using it is very low. I don't have
have anything against the program and it may be perfectly OK, but
I just don't like downloading and running random programs.
As a result, I rarely if ever get a virus.
jksor1234



Joined: 18 Jan 2007
Posts: 9

View user's profile Send private message

PostPosted: Wed Jan 24, 2007 1:43 pm     Reply with quote

PCM programmer wrote:
The duty value is a fraction of the middle number in setup_timer_2().
Look at the example program.

31/124 = 25% duty cycle

62/124 = 50% duty cycle

In your modified code, you have picked 249 as the middle number.
So in the same way as above, you can choose values for 25% and 50%.


I understand that what was said above is true.

However, this is what I got using CCS's PIC Wizard:
Set up the project as follows:
Device = PIC16F877A
Osc Freq = 20MHz
Set the CCP1 as a PWM and set the PWM frequency to 20KHz it generates the following code for timer2:
Code:
   setup_timer_2(T2_DIV_BY_1,249,1);

which is correct.
However, in the PIC Wizard when you set the duty cycle to 50% it generates the following code:
Code:
   set_pwm1_duty(500);

which is not correct.

Why is the PIC Wizard not correct?
I am using PCWH version 4.020

The equations I use to set up the PWM frequency and duty cycle are as follows...

value = Fosc / (Fpwm * 4 * T2DIV) - 1
setup_timer_2(T2_DIV_BY_X, value, 1);

value = (Desired_Duty_Cycle% * Fosc) / (Fpwm * 4 * T2DIV)
set_pwm1_duty(value);

These equation are much more reliable than the PIC Wizard.

But still, why is the PIC Wizard not correct?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jan 24, 2007 2:05 pm     Reply with quote

Put an upper case 'L' after the 500. ie., make it be 500L.
jksor1234



Joined: 18 Jan 2007
Posts: 9

View user's profile Send private message

PostPosted: Wed Jan 24, 2007 3:18 pm     Reply with quote

What does the upper case L do?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jan 24, 2007 3:31 pm     Reply with quote

It tells the compiler that the number is a 'long' integer (greater than
8-bits). When the compiler sees a 'long' value as the duty cycle
parameter, it switches to use 10-bit PWM mode instead of 8-bit.
Here are several threads that discuss this:
http://www.ccsinfo.com/forum/viewtopic.php?t=26751
http://www.ccsinfo.com/forum/viewtopic.php?t=24055
http://www.ccsinfo.com/forum/viewtopic.php?t=22119
http://www.ccsinfo.com/forum/viewtopic.php?t=9927
vsmguy



Joined: 13 Jan 2007
Posts: 91

View user's profile Send private message Visit poster's website

PostPosted: Sat Feb 10, 2007 10:23 am     Reply with quote

PWMWizard tells me to write :

set_pwm1_duty(500l);

for the above example...

but from what you said, I should call

set_pwm1_duty(124);

I have posted a new thread to this effect, could you (PCM) have a look at it ?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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