View previous topic :: View next topic |
Author |
Message |
bungee-
Joined: 27 Jun 2007 Posts: 206
|
PWM module as square freq generator |
Posted: Sun Oct 02, 2011 4:19 pm |
|
|
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
Thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Oct 02, 2011 4:54 pm |
|
|
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
|
|
Posted: Mon Oct 03, 2011 5:22 pm |
|
|
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? |
|
|
|