View previous topic :: View next topic |
Author |
Message |
Mary
Joined: 02 Dec 2003 Posts: 3
|
PWM on 16F877 |
Posted: Wed Dec 03, 2003 5:55 pm |
|
|
Hi
I am trying to use the PWMs to run 2 seperate motors. I am using CCP1 and CCP2. PWM1 seems to be OK, but PWM2 goes high and stays high when I run the program... I have check my circuit and I have not found any hardware problems. Could you please check out my code and see if there is something wrong there...
Thanks
#include "16F877.h"
#fuses XT,NOPROTECT,NOWDT
#fuses DEBUG
#use delay(clock=4000000)
main()
{
long duty1 = 100; //PWM1 Duty cycle
long duty2 = 50; //PWM2 Duty cycle
//*********************************************************
//setting up the PWM
set_tris_c(0x00); //Make all port C floating RC outputs.
ENABLE_INTERRUPTS(GLOBAL);
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
setup_timer_2(T2_DIV_BY_1, 16, 1);
set_pwm1_duty(duty1);
set_pwm2_duty(duty2);
enable_interrupts(INT_TIMER2);
} |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Dec 03, 2003 6:34 pm |
|
|
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
|
|
Posted: Thu Dec 29, 2005 12:35 am |
|
|
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
|
|
Posted: Thu Dec 29, 2005 4:23 pm |
|
|
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
|
|
Posted: Sun Jan 14, 2007 11:43 am |
|
|
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
|
|
Posted: Sun Jan 14, 2007 11:54 am |
|
|
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
|
|
Posted: Sun Jan 14, 2007 12:02 pm |
|
|
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
|
|
Posted: Sun Jan 14, 2007 12:11 pm |
|
|
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
|
|
Posted: Sun Jan 14, 2007 12:24 pm |
|
|
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
|
|
Posted: Sun Jan 14, 2007 12:52 pm |
|
|
@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 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jan 14, 2007 1:14 pm |
|
|
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
|
|
Posted: Wed Jan 24, 2007 1:43 pm |
|
|
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
|
|
Posted: Wed Jan 24, 2007 2:05 pm |
|
|
Put an upper case 'L' after the 500. ie., make it be 500L. |
|
|
jksor1234
Joined: 18 Jan 2007 Posts: 9
|
|
Posted: Wed Jan 24, 2007 3:18 pm |
|
|
What does the upper case L do? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
|