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

PWM module as square freq generator

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



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

PWM module as square freq generator
PostPosted: Sun Oct 02, 2011 4:19 pm     Reply with quote

Hi!

I need sanity check in this function. (I have no hardware yet, but I'm writing the code in advance.)

What I want to achieve is to simply pass the required frequency to the function and function sets everything up and outputs desired frequency at 50% duty cycle at PWM output.

So here is the code:
Code:
void FG(int32 freq)
{
   int32 _t1;
   int PR2,presc;
   int16 cycl; 
   set_pwm1_duty(0); //Turn off PWM output. 
   presc=1;
   _t1=(clock/(4*freq))-1; //prescaler = 1   
   if (_t1>255)
   {
      presc=4;
      _t1=(clock/(16*freq))-1; // prescaler = 4
      if (_t1>255)
      {
         presc=16;
         _t1=(clock/(64*freq))-1; // prescaler = 16
         if (_t1>255) _t1=255;
      }
   }   
   PR2=_t1;   
   cycl = 2*(PR2+1);
   switch (presc) {
    case 1:setup_timer_2(T2_DIV_BY_1,PR2,1);
           break;
    case 4:setup_timer_2(T2_DIV_BY_4,PR2,1);
           break;
    case 16:setup_timer_2(T2_DIV_BY_16,PR2,1);
           break;

   } 
   setup_ccp1(ccp_PWM);   //Don't know if this is always necessary
   set_pwm1_duty(cycl); // Set PWM to 50% duty   
}


I forgot to mention I know the upper and lower freq limits, so this is not an issue. And clock variable is (const int32 clock=[crystal freq in Hz])

Any and every comment is welcome Cool
Thanks
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Oct 02, 2011 4:54 pm     Reply with quote

I didn't check your code in detail, but I've written a routine like this in
the past. The basic concept is the same as your code. Based on the
input frequency, you select a prescaler. Then you setup Timer2 with
the selected prescaler. Then you set the duty as a fraction of the PR2
value. So your basic concept is good.
bungee-



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

PostPosted: Mon Oct 03, 2011 5:22 pm     Reply with quote

Thank you for your answer. And yes basic concept is good and it actually work.

But (yes there is an but), I'm not satisfied with output accuracy. Problem is with my method of elimination for prescaler values.

So I have to calculate three PR2 values (in worst case scenario) and then pick one of three which is closer to my desired frequency.

Ok I know how to calculate three PR2 values and how to calculate back the frequency.
But how to decide what value have lowest absolute error.
(It's 1:30 in the morning) I can't see an elegant solution. Any suggestions?
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