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

Simple PWM bug, please help...

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



Joined: 07 Jun 2022
Posts: 19

View user's profile Send private message

Simple PWM bug, please help...
PostPosted: Wed Jul 13, 2022 4:44 am     Reply with quote

Hi I'm using PIC16F877A (external crystal 20MHz) to implement PWM on CCP1.
I tried many cases using the same code and calculations, all works but this one particular case where f_PWM = 100kHz, T_PWM = 10 us, duty cycle = 50%, the osciloscope just gives out a straight line. Below is the code and my calculations for two cases, one works normally and one does not.

Code:

void main()
{
// PWM Period = [PR2 + 1] * 4 * Tosc * TMR2Prescale
// PWM duty cycle = (CCPR1L:CCP1CON<5:4>) * Tosc * TMR2Prescale

// Code works normally
// f = 19.53 kHz, T = 51.2 us
// PR2 = (51.2/ (4 * 1/20 * 1)) - 1 = 255
// Duty Cycle 50% => high time = T/2 = 25.6
// Value sent to (CCPR1L:CCP1CON<5:4>) is 512
//!   while(TRUE)
//!   {
//!        setup_ccp1(CCP_PWM);
//!        setup_timer_2(T2_DIV_BY_1,255,1);
//!        set_pwm1_duty(512);       
//!   }
// Code does not work normally
// f = 100 kHz, T = 10 us
// PR2 = (10/ (4 * 1/20 * 1)) - 1 = 49
// Duty Cycle 50% => High time is T/2 = 5 us
// Value sent to (CCPR1L:CCP1CON<5:4>) is 100
   while(TRUE)
   {
        setup_ccp1(CCP_PWM);
        setup_timer_2(T2_DIV_BY_1,49,1);
        set_pwm1_duty(100);       
   }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 18233

View user's profile Send private message

PostPosted: Wed Jul 13, 2022 5:45 am     Reply with quote

Key. Add 'L' here:

set_pwm1_duty(100L);

Problem is that the duty code has two operating modes, dependant on
whether the value passed is an 8bit value or a 16bit value. If a 16bit
value is passed the whole 10bits of the PWM register is set. If only 8bits
are passed, instead the 8bits are loaded into the top 8bits of the 10bit
value. Effecitively multiplying by 4. So your current code is equivalent to:

set_pwm1_duty(400);

Which just turns the output permanently on.

You need to tell the compiler to treat any value under 256 as a 'long'
(so 16bits), to load the whole register. This is what the 'L' does.
ThanhDan



Joined: 07 Jun 2022
Posts: 19

View user's profile Send private message

PostPosted: Thu Jul 14, 2022 9:16 pm     Reply with quote

Ttelmah wrote:
Key. Add 'L' here:

set_pwm1_duty(100L);

Problem is that the duty code has two operating modes, dependant on
whether the value passed is an 8bit value or a 16bit value. If a 16bit
value is passed the whole 10bits of the PWM register is set. If only 8bits
are passed, instead the 8bits are loaded into the top 8bits of the 10bit
value. Effecitively multiplying by 4. So your current code is equivalent to:

set_pwm1_duty(400);

Which just turns the output permanently on.

You need to tell the compiler to treat any value under 256 as a 'long'
(so 16bits), to load the whole register. This is what the 'L' does.


YESS!!! IT WORKED!! THANKS A LOT!! How could you have known that Smile)) Like is there a book where I can read this from?
Ttelmah



Joined: 11 Mar 2010
Posts: 18233

View user's profile Send private message

PostPosted: Thu Jul 14, 2022 10:58 pm     Reply with quote

This is what the manual is for.
Read the set_pwmx_duty entry. See what it says about 8bit and 16bit
values. You then need to understand that a constant under 256 is treated
by default as an 8bit value.
A search here would have also found this discussed many times.
ThanhDan



Joined: 07 Jun 2022
Posts: 19

View user's profile Send private message

PostPosted: Fri Jul 15, 2022 9:02 pm     Reply with quote

Thanks, noted
E_Blue



Joined: 13 Apr 2011
Posts: 374

View user's profile Send private message

PostPosted: Thu Jul 21, 2022 5:21 pm     Reply with quote

Interesting, I was thinking that, due to the high frequency, the bit resolution was decreased to 4 bits or so.

Every day learning something new.
_________________
Electric Blue
Ttelmah



Joined: 11 Mar 2010
Posts: 18233

View user's profile Send private message

PostPosted: Fri Jul 22, 2022 4:20 am     Reply with quote

Yes, the overall resolution is decreased. Just a count of 200 supported,
instead of 1024. Hence 100 for half scale. seven and a bit bits.
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