|
|
View previous topic :: View next topic |
Author |
Message |
Guest
|
PWM frequency versus resolution set up |
Posted: Fri Sep 07, 2007 1:32 pm |
|
|
Hi,
I have already sent this question to CCS support, but I not sure I will get a quick answer, so I decided to post it here as well, as I am sure I'll get a quicker answer.
I am trying to set-up my pwm frequency on a project using a PIC18F4620, my clock frequency is 10.0 MHz and I need to get 7.184 KHz (or anything between 6 to 7.5 KHz) with a 10 bit pwm resolution. Using the PIC setup WIZ it does show that this is accomplishable at 10 bits of resolution and that the timer2 configuration is: setup_timer_2(T2_DIV_BY_4,86,1) However, when I use this configuration, although I am getting the right frequency, the resolution is way off, it is something less than 7 bits? I have also done the calculations using the PIC data sheet and if I set the PR2 register to 86, timer 2 prescaler to divide by 4 (same as above) it should work?, the actual frequency is 7267 and if we calculate the pwm resolution it is well within 10 bits.
for the above, If we use PWM res = ln(Fosc/Fpwm) / ln(2) = 10.44 bits
Also the PWM freq above is well within the counter constraints for timer2 using a 10 MHz clock
I'm I missing something? can anyone shed some light? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Sep 07, 2007 1:36 pm |
|
|
Post the statement that sets the PWM duty cycle. Also post the
declaration of the variable used in that statement. |
|
|
cbarberis
Joined: 01 Oct 2003 Posts: 172 Location: Punta Gorda, Florida USA
|
|
Posted: Fri Sep 07, 2007 2:10 pm |
|
|
I declare a variable as follows:
unsigned int16 k= 512; // set it to 50% duty
set_pwm1_duty(k);
// the above gives me a fully saturated output out of CCP2?
void init()
{
set_tris_a(0xFF); // RA7-RA0 -> in,in,in,in,in,in,in,in
set_tris_b(0xC7); // RB7-RB0 -> in,in,out,out,out,in,in,in
set_tris_c(0x91); // RC7-RC0 -> in,out,out,in,out,out,out,in
set_tris_d(0xF0); // RD7-RD0 -> in,in,in,in,out,out,out,out ***Reconfigures in LCD driver
set_tris_e(0xf); // RE3-RE0 -> in,in,in,in
setup_adc_ports(AN0_TO_AN1|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
setup_psp(PSP_DISABLED);
//setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4);
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4|SPI_XMIT_L_TO_H |SPI_SS_DISABLED);
port_b_pullups(TRUE);
setup_wdt(WDT_ON);
//setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_bit); //will overflow at 154Hz or every 6.5mS
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); //will overflow at 38Hz or every 26.2mS
setup_timer_2(T2_DIV_BY_4,86,1); // generates pwm freq of 7.267 KHz with 10 bit res
// setup_timer_2(T2_DIV_BY_1,255,1); // generates pwm freq of 9.77KHz with 10 bit res works ok
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
//setup_timer_4(T4_DISABLED,0,1);
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
ext_int_edge( H_TO_L); // Set up PIC18 EXT
ext_int_edge( 1, H_TO_L); // Set up PIC18 EXT2
enable_interrupts(INT_TIMER0);
//disable_interrupts(INT_TIMER0);
disable_interrupts(INT_TIMER1);
disable_interrupts(INT_EXT);
//enable_interrupts(INT_EXT);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_low_volt_detect(FALSE);
setup_oscillator(False);
//enable_interrupts(INT_RB);
// enable_interrupts(INT_EXT1);
enable_interrupts(INT_RDA);
disable_interrupts(INT_EXT1);
enable_interrupts(GLOBAL);
//disable_interrupts(GLOBAL);
InitBothPots();
lcd_init(); // initialize LCD
store_tripleline(); // store triple line for first page in lcd CGRAM
write_to_pot_R1(0);
set_pwm1_duty(0);
set_pwm2_duty(0);
FAN = OFF;
}
If I do the following to just continuosly test the pwm output
void main()
{
int8 i;
init();
set_pwm1_duty(128);
while(1) restart_wdt() }
I get approximately a 75% ON time duty ???? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Guest
|
|
Posted: Fri Sep 07, 2007 3:20 pm |
|
|
Thank you PCM programmer.
I realized I should just pasted only a couple of things of my init() which is mostly unrelated to the problem.
The post you sent me answer the issue, I think this is something that should be indicated on the app notes, the value of PR2 prescaler is critical to the pwm frequency resolution. |
|
|
Kenny
Joined: 07 Sep 2003 Posts: 173 Location: Australia
|
|
Posted: Fri Sep 07, 2007 4:38 pm |
|
|
Edited to fix error:
The number of bits resolution calculation needs the prescaler value
ie. log((Fosc/Prescaler)/Fpwm) / log(2)
The prescaler is 4 in this case, and this works out to be 8.443 bits.
2^8.443 = 348 steps.
An easier way to get the number of steps is as follows.
Timer 2 is concatenated with two other bits, so the number of steps is (PR2 + 1) * 4. This is independent of the prescaler.
With PR2 = 86
Number of steps is (86+1)*4 = 348
Note that when setting a constant less than 256 the compiler will need to be told to generate code for 10 bit pwm either by adding an 'L' to the value or casting it to an int16.
eg. set 50% duty cycle
set_pwm1_duty(174L); |
|
|
|
|
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
|