View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Apr 27, 2010 12:54 pm |
|
|
I'm using the test program shown below with vs. 4.084. I also get about
40% duty cycle measured on the scope. But that's correct, because the
duty cycle is not determined by 102 being 10% of 1024. It's determined
by 102 being a percentage of the Timer2 value. That's the middle value
in the setup_timer_2() function.
In 10-bit mode, the duty cycle equation is:
Code: |
16-bit Duty cycle Parameter 102L 102
--------------------------- = ------------ = ------ = 39.8%
(Middle value +1) * 4 (63 +1) * 4 256
|
Using the logic analyzer, I measure the high level pulse at 51.0 us,
and the total period at 128.1 us. This gives the following, which agrees
with the duty cycle equation:
Code: |
51.0
----- = .389
128.1
|
Test program:
Code: |
#include <16F88.h>
#fuses INTRC_IO,NOWDT,BROWNOUT,PUT,NOLVP
#use delay(clock=8000000)
//=======================
void main()
{
setup_timer_2(T2_DIV_BY_4,63,1);
setup_ccp1(CCP_PWM);
set_pwm1_duty(102L);
while(1);
} |
|
|
|
sirius
Joined: 27 Jun 2009 Posts: 16 Location: Bulgaria
|
|
Posted: Tue Apr 27, 2010 1:26 pm |
|
|
Problem solved . Seems to be a compiler issue, but don't want to investigate it profoundly. Manually configured PWM module, following PIC16F88 datasheet sequence:
Code: |
...............................................
#byte CCP1CON = 0x17
#byte T2CON = 0x12
#byte PR2 = 0x92
................................................
PR2=255;
T2CON=4;
CCP1CON=12;
set_pwm1_duty(102L); |
Now 102L gives 9.98%, as should be. Tested also with 512L - exactly 50% duty_cycle. All 10-bit of resolution are available now.
Could be a wrong initialization sequence of PWM-module, but don't want to dig any further. Thanks anyway for the interest in my topic! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Apr 27, 2010 1:30 pm |
|
|
Right, but you've changed the PR2 setting. That's the middle value.
I can do the same thing you just did, and I can do it in CCS. All I do is
set the middle value to 255 in the setup_ccp1() function, as shown below.
Then I read 10% duty cycle on the logic analyzer. This is with vs. 4.084.
Tested in hardware.
Quote: |
#include <16F88.h>
#fuses INTRC_IO,NOWDT,BROWNOUT,PUT,NOLVP
#use delay(clock=8000000)
//=======================
void main()
{
setup_timer_2(T2_DIV_BY_4,255,1);
setup_ccp1(CCP_PWM);
set_pwm1_duty(102L);
while(1);
} |
|
|
|
sirius
Joined: 27 Jun 2009 Posts: 16 Location: Bulgaria
|
|
Posted: Tue Apr 27, 2010 1:42 pm |
|
|
setup_timer_2(T2_DIV_BY_4,63,1); - Defined by CCS Project Wizard.
setup_timer_2(T2_DIV_BY_4,255,1); - just tested it in hardware. You are right - duty_cycle=10%, but frequency is now 1,95KHz , not as supposed to be 7,8Khz.
P.S. Adjusting Timer2 Prescaler to 1 and now is fine:
Code: |
setup_timer_2(T2_DIV_BY_1,255,1); | -7,8Khz, full 10-bit resolution
A Project Wizard issue? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Apr 27, 2010 2:33 pm |
|
|
I don't know. I never use the Wizard. I don't have that compiler version.
Changing the PR2 value will also affect the PWM frequency. So certainly
if the PR2 value is increased and nothing else is changed, the PWM
frequency will go down. You compensated for that by reducing the
prescaler. This post has the PWM frequency formula:
http://www.ccsinfo.com/forum/viewtopic.php?t=17993&start=1
If it's all working now, I'm happy. |
|
|
sirius
Joined: 27 Jun 2009 Posts: 16 Location: Bulgaria
|
|
Posted: Wed Apr 28, 2010 7:47 am |
|
|
Yes, everything is fine now . Thanks PCM |
|
|
slammer
Joined: 02 May 2010 Posts: 4
|
|
Posted: Sun May 02, 2010 7:35 am |
|
|
hi, I also have problem with PWM, I'm using Proteus 7.6 sp4 and PCWHD Compiler 4.106, the problem is pwm is not working, I don't know why, my code is like this
Code: | #include <16F877a.h>
#use delay(clock=20MHZ)
#fuses XT, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP
main()
{
enable_interrupts(GLOBAL);
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16,100L,1);
set_pwm1_duty(30L);
while(1);
} |
but if I cancel the line
Code: | set_pwm1_duty(30L); |
it is working then how can I control the duty cycle ?
my aim is to build a controller for Dc-Dc converter, my pic will take some data from ADC which is connected to output of the converter and referring to this data it will change the duty cycle of my 100kHz pwm,
please help me what is the problem with this code ? is it because of proteus or version of CCS, If I try in real pic, will it work ?
thanks |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Sun May 02, 2010 7:44 am |
|
|
It could be a proteus problem.
However there are two 'glaring' things that should be fixed:
1) Never _ever_ enable anything to do with interrupts without an interrupt handler present. If an interrupt does get enabled, this is a 'sure' way to crash code.
2) Set your fuses correctly for your clock. XT, does not support operation at 20MHz....
Best Wishes |
|
|
slammer
Joined: 02 May 2010 Posts: 4
|
|
Posted: Sun May 02, 2010 8:27 am |
|
|
the new code is like this, but still it's not working
I don't have the pic and the setup now so I have to simulate it :D that's why I used proteus, and if it's a proteus problem then how can I simulate it, I don't know CCS too much last year I was using pic with assembly however it's been 1 year and I don't remember...
Code: | #include <16F877a.h>
#use delay(clock=4MHZ)
#fuses XT, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP
main()
{
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16,100L,1);
set_pwm1_duty(30L);
while(1);
} |
|
|
|
slammer
Joined: 02 May 2010 Posts: 4
|
|
Posted: Sun May 02, 2010 8:45 am |
|
|
I have also tried PIC Simulator IDE - Evaluation Copy v6.65 and still not working :S |
|
|
slammer
Joined: 02 May 2010 Posts: 4
|
|
Posted: Sun May 02, 2010 9:18 am |
|
|
I've found a patch for proteus and now it's working, thanks for help |
|
|
luismramirez
Joined: 17 Feb 2011 Posts: 8
|
|
Posted: Wed Apr 06, 2011 9:20 am |
|
|
Hi,
I have an 8Mhz, with T2 BY 16, 250;
I know what duty % I need, so, using the equation:
16bit value = % * (250 + 1) * 4
Then, for 100% and 50%:
100% = 10400
50% = 50200
Is that right?
I read some were that this 16bit value can't be bigger than the middle value from the timer_2 setup.
Thank you. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Wed Apr 06, 2011 9:32 am |
|
|
Value can't be bigger than the ((middle value+1) *4)-1.
So for a middle value of 255, maximum value is 256*4 = 1024 -1 = 1023. The '10 bit' maximum for the chip.
Your formula is basically right, except for needing a division by 100.
value = (%/100) *(250+1) *4 -1
100% = 1003
50% = 501
You've lost a '0' in your 100% calculation.
Best Wishes |
|
|
luismramirez
Joined: 17 Feb 2011 Posts: 8
|
|
Posted: Wed Apr 06, 2011 11:47 am |
|
|
Thank you!
However, your formula has a "-1" at the end.
The one at the first page doesn't.
Which one is right and why?? |
|
|
luismramirez
Joined: 17 Feb 2011 Posts: 8
|
|
Posted: Wed Apr 06, 2011 6:35 pm |
|
|
ok. i got it.
thank you all ;) |
|
|
|