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

PIC18F87J50 2# PWM at different frequencies
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PIC18F87J50 2# PWM at different frequencies
PostPosted: Wed Jul 31, 2013 4:25 am     Reply with quote

Hello,

At this moment I want to use 2# PWM outputs...(PIC18F87j50)
So far so good.. But what I want is that one PWM output is running at i.e. 20.000Hz. and the other at 5.000Hz but that they start at the same moment.
What I read in the datasheet is that there are two timers involved with the PWM, Timer2 and Timer4.
But I can't figure out how they are related to the specific PWM output.
So what do I have to put in which timer to let the correct PWM output run at the frequency I want.....

anybody an idea???

Regards,
Jody
temtronic



Joined: 01 Jul 2010
Posts: 9188
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Jul 31, 2013 5:20 am     Reply with quote

Hmmm.. could you clarify the frequencies please?
When you typed in 20.000 Hz did you mean 20KHz ?
Being in Canada I'd type 20,000 Hz or 20 KHz..but I think the 'European' way is to use the decicmal point not the comma.
Just so we start off on the right foot !!

jay
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Wed Jul 31, 2013 5:45 am     Reply with quote

Yep I mean 20kHz....
And it is not that I need 20kHz it is just an example...
Different frequencies starting at the same moment....
And the one slower than the other...

Jody
Ttelmah



Joined: 11 Mar 2010
Posts: 19401

View user's profile Send private message

PostPosted: Wed Jul 31, 2013 12:13 pm     Reply with quote

You are not going to get perfect alignment. You can get it within a very few clock cycles.
The key is the two master clocks.

Forget about the PWM at first, just think about the two timers.

If you setup the two timers, one using perhaps /200, and div_by_1, and the other /200 and div_by_4, then they will generate two clocks at 1/4 the rate of each other.

All you do, is setup the PWM's as 'normal', but ensure one uses the second timer. Table 17-3, shows how to select example clock rates. The values needed will depend on your master clock. Then just clear each timer as quickly as possible after one another. This 'aligns' the timers.
Code:

set_timer2(0);
set_timer4(0);


The syntax needed to select the second timer, depends on the age of your compiler.
When a timer is set, it also clears the prescaler, and the setting occurs at the end of the value being written, so the clocks will be misaligned by the time taken to write the second number only. Since these timers run in 8bit mode for the PWM, just a couple of CPU instructions. This is as close as you can get.

Best Wishes
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Wed Jul 31, 2013 1:04 pm     Reply with quote

hello,
as soon I am back in the office I will give it a go....

Keep you informed......

Thanks,

Jody
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Jul 31, 2013 3:37 pm     Reply with quote

do you need a TRUE PWM frequency source ?
or
do you need arbitrary frequencies with a fixed duty cycle?
or
arbitrary frequency with a fixed non-50% duty cycle- say pulse train??

your question needs clarification.

more simply:
what frequencies or Range of freqs do you need
and what duty cycle ??

AND
Quote:

start at the same moment.


phase locked or arbitrary phase ??
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Tue Sep 17, 2013 5:07 am     Reply with quote

What I need is:
1 output at a (fixed) frequency say 8kHz.(jumper selectable 8kHz or 10kHz or 16kHz)
1 output which starts at the same moment (1~2mS different is no problem) but with a factor 2 or 4 or 8 slower..(output is 4kHz or 2kHz or 1kHz) but the rising edges must start at the same moment...

It this possible to do with the PWM outputs???

Regards,
Jody
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Tue Sep 17, 2013 5:25 am     Reply with quote

To get rising edges precisely at the same moment is not possible even with hardware. There is always going to be some amount of misalignment, even if its picoseconds or less. So, what amount of misalignment is acceptable in this application? Just how close to "aligned" do they really need to be?
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Tue Sep 17, 2013 5:35 am     Reply with quote

(1~2mS different is no problem)
Ttelmah



Joined: 11 Mar 2010
Posts: 19401

View user's profile Send private message

PostPosted: Tue Sep 17, 2013 1:42 pm     Reply with quote

Yes. Fairly easily.

What compiler version?.
What clock rate is your CPU running?.
Remember that if you change the clock rate using anything other than the prescaler, the numbers needed for each duty cycle will also have to change.
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Wed Sep 18, 2013 12:58 am     Reply with quote

Hi,
Compiler version in 4.119
CPU clock rate is the internal 8MHz. (40MHz Oscillator available).

and..... how is it fairly easily??

Regards,
Jody
Ttelmah



Joined: 11 Mar 2010
Posts: 19401

View user's profile Send private message

PostPosted: Wed Sep 18, 2013 4:02 am     Reply with quote

No guarantees. Haven't got that chip to try. However this should give two synchronised CCP's at a factor of 4 in frequency, on ECCP1/2 (Port C1, and C2), controlled by a two bit jumper pattern on B0, and B1.

Code:

#include <18F87J50.h>
#FUSES NOWDT, WDT128, NOXINST, INTRC, NOFCMEN, NOIESO
#use delay(clock=8000000)
#use rs232(baud=9600,parity=N,ERRORS,bits=8,stream=PORT1,errors)

int8 old_b;
int8 current_b=0xFF; //ensure pattern update on first call
int16 max_duty=0; //set this to allow the duty cycle to be controlled sensibly

//Check if input pattern on jumpers has changed
int1 pattern_changed(void)
{
   current_b=input_b() & 3;
   if (current_b==old_b)
      return(FALSE);
   return(TRUE);
}

void set_dutys(int8 duty)
{
  int32 temp;
  //Now because the PR2 value changes with the rate, need to use different
  //values for the same duty cycle.
  //This allows 'duty' in percent to be sent and automatically set the right
  //factor.
  if (max_duty==0 || duty==0) //avoid possible division by zero...
  {
     set_pwm1_duty(0L);
     set_pwm2_duty(0L);
     return;
  }
  //Now have 'max_duty' for 100%, and need to work out what has to go to the
  //timing registers from this.
  //Use int32 as fastest way.
  temp=(int32)duty*max_duty;
  temp/=100;
  set_pwm1_duty(temp);
  set_pwm2_duty(temp);   
}
 
//set PWM's according to the jumper pattern
//using (two bits):
// 0 = both off
// 1 = 8KHz/2KHz
// 2 = 10KHz/2.5KHz
// 3 = 16KHz/4KHz
void set_pwms(void)
{
   //now need to switch according to the current two bit pattern on B0/B1
   //This is in 'current_b' if pattern_changed has been called
   if (current_b>3)
      pattern_changed(); //here if it hasn't been called. - first time.     
     
   //Now stop PWM, momentarily
   set_pwm1_duty(0L);
   set_pwm2_duty(0L);
   
   switch (current_b)
   {
   case 0b00:
      //Here both jumpers make = both PWM's off
      //Since already done ready for chaqnge, only have to set max_duty
      max_duty=0;
      break;
   case 0b01:
      //Now want the slowest rate.
      //Setup two timers
      setup_timer_2(T2_DIV_BY_1, 249, 1); //8KHz
      setup_timer_4(T4_DIV_BY_4, 249, 1); //2KHz
      max_duty=1000;
      break;
   case 0b10:
      //10K rate
      setup_timer_2(T2_DIV_BY_1, 199, 1); //10KHz
      setup_timer_4(T4_DIV_BY_4, 199, 1); //2.5KHz
      max_duty=800;
      break;
   case 0b11:
      //16K rate
      setup_timer_2(T2_DIV_BY_1, 124, 1); //16KHz
      setup_timer_4(T4_DIV_BY_4, 124, 1); //4KHz
      max_duty=500;
      break;
   }
   set_dutys(50); //start PWM's at 50% duty
   old_b=current_b;
}     

void main()
{
   setup_comparator(NC_NC_NC_NC);
   //Now assume jumpers are on two low portB pins, using internal pullups
   port_b_pullups(TRUE);
   delay_us(50); //allow pins time to settle
   setup_ccp1(CCP_PWM);
   setup_ccp2(CCP_PWM);
   //Your compiler does not correctly set the T3CCP1 bit, as documented.
   //Have to use:
   setup_timer_3(T3_DISABLED | T3_CCP2_TO_5);
   //second timer for second CCP
   //This is confusing. The bit to select the 'alternative' timer, selects
   //T3, for 'compare', and 'capture', so CCS refer to T3, but selects T4
   //for PWM.....

   //Now force the PWM's to the current pattern
   set_pwms();
   do
   {
      //Now your main code
     
     
      //At some point check the pins if you want the PWM's to be able to
      //update 'live'.
      if (pattern_changed())
         set_pwms(); //will only be called if the jumpers change
   }
   while (TRUE);
}


The synchronisation will be a few CPU clocks apart, as already explained.
I set the duty cycles at 50%, with a function that can correctly set this for the different rates.

Best Wishes
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Wed Sep 18, 2013 5:09 am     Reply with quote

Hi Ttelmah,
Output C2 is not working...you wrote in the code that there was something confusing about the T3 timer and selecting the T4 timer.....
Output C1 is exactly as you wrote down....

So I am almost there..
I will try and (a lot) error.. keep you informed..
BUT Great that you want to help!!!

Regards,
Jody
Ttelmah



Joined: 11 Mar 2010
Posts: 19401

View user's profile Send private message

PostPosted: Wed Sep 18, 2013 7:19 am     Reply with quote

Both timers are running, and the PWM's as well (in MPLAB). Try using 'output_drive(PIN_C2);' in the setup. CCS may not be setting the tris. Didn't check for that.

I was just saying that the CCS nomenclature is confusing....

The 'point' about the timer setting, is that there are two bits in the timer3 config register, which sets various CCP's to use the alternate timer. When using the PWM, the alternate timer is timer4... CCS, also say in the 'include' file that you can or the configuration with the CCP setup, but on this compiler version this does not work. You have to setup timer3, to select the alternate timer, then use timer4.....

Best Wishes
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Wed Sep 18, 2013 9:17 am     Reply with quote

YES got it working!!!!!
My C2 pin is broken... so was looking for a solution which never came...
But now I am using C1 and G0 and it is working like you said!!
I changed the T3 setting:
Code:
 setup_timer_3(T3_DISABLED | T3_CCP3_TO_5);

Ttelmah THANK!!!!!!!!!!!!!!!!!!!!!

Regards,
Jody
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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