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 period (freq) tweaking?

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



Joined: 30 Oct 2003
Posts: 209
Location: Norfolk, England

View user's profile Send private message Send e-mail Visit poster's website MSN Messenger

PWM period (freq) tweaking?
PostPosted: Mon Aug 02, 2004 9:37 am     Reply with quote

Hi,
I need to generate a fast low (processor) overhead square wave. I am thinking PWM is ideal, with the duty cycle set at 50%.
Is there any tweeks to change the PWM period? I have the presale and PR2 to play with (I assume I can adjust these on the fly) but I may need a little bit finer control. I need about 600kHz and don’t want to tie up the PIC in generating it!

Your advice and ideas, as always, are most welcome!

Keep well,

Will
valemike
Guest







PostPosted: Mon Aug 02, 2004 9:52 am     Reply with quote

What crystal frequency are you using?

Look at EX_PWM.c

The formula is:
// The cycle time will be (1/clock)*4*t2div*(period+1)

clock = Crystal Frequency
t2div = Let's keep it at 1

First state your crystal frequency, then I or someone will give you the values you need for PR2 and timer2 setup.

-Mike
Will Reeve



Joined: 30 Oct 2003
Posts: 209
Location: Norfolk, England

View user's profile Send private message Send e-mail Visit poster's website MSN Messenger

PostPosted: Mon Aug 02, 2004 10:09 am     Reply with quote

Hi,
I am using 40MHz. I found the formula you state in the datasheet, but thanks for supplying it. I think I didn't word my initial question very well, what I need is a little bit more resolution, for instance the difference between a PR2 of 0x02 and 0x03 is 625kHz and 833kHz. Any ideas how I could get 700kHz for instance?

Will
Ttelmah
Guest







PostPosted: Mon Aug 02, 2004 10:24 am     Reply with quote

Will Reeve wrote:
Hi,
I am using 40MHz. I found the formula you state in the datasheet, but thanks for supplying it. I think I didn't word my initial question very well, what I need is a little bit more resolution, for instance the difference between a PR2 of 0x02 and 0x03 is 625kHz and 833kHz. Any ideas how I could get 700kHz for instance?

Will

You get the best resolution, by using the lowest possible prescaler. With a prescaler of 1, you get frequencies of 714285Hz, with 14, and 666666Hz with 15 in PR2.
You can get 700KHz, by chosing a crystal that is a suitable multiple of this frequency (39.2MHz), but the step size for such a high frequency will remain large. If you need really fine resolution at this sort of frequency, look at using one of the programmable frequency synthesiser chips.

Best Wishes
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

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

PostPosted: Mon Aug 02, 2004 10:54 am     Reply with quote

Take a look at the compare module on the PIC (if you have one). You can get the best resolution with this method of generating the signal.
Will Reeve



Joined: 30 Oct 2003
Posts: 209
Location: Norfolk, England

View user's profile Send private message Send e-mail Visit poster's website MSN Messenger

PostPosted: Tue Aug 03, 2004 9:15 am     Reply with quote

Thanks guys. I had not looked at the compare module in detail, it is very useful. It’s a shame the special function doesn’t toggle the pin as well as re-set the timer but you can’t have everything I guess! This will be a very useful module for this project!

Keep well,

Will
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

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

PostPosted: Tue Aug 03, 2004 10:24 am     Reply with quote

You can setup to toggle the pin and then add your CCP value to the CCP register. This will cancel out any latency from the ISR handler. So lets say your 1/2 period value is 0x100. Load that value into the CCP register. When the timer hits 0x100 the pin will toggle and an interrupt will occur. By the time you handle the interrupt, the value will not be 0x100 but lets just say it's 0x120. Well just add the 0x100 to the CCP value which is 0x100 and the new CCP value will be 0x200. So long as the latency is never greater than your 1/2 period value it shouldn't miss a beat. I use this technique to control 6 software PWM's used for dimming.
Will Reeve



Joined: 30 Oct 2003
Posts: 209
Location: Norfolk, England

View user's profile Send private message Send e-mail Visit poster's website MSN Messenger

PostPosted: Wed Aug 04, 2004 9:19 am     Reply with quote

That is fantastic. Just what I need. Now I thought I was being clever by coding the following (PIC18 here):

int16 ccp1reg;
#locate ccp1reg=0xFBE

#INT_CCP1
void ccp1_int() {
ccp1reg+=300;
}

Which generates the following:

0096: MOVLW 2C
0098: ADDWF FBE,F
009A: MOVLW 01
009C: ADDWFC FBF,F

Which doesn’t seem to do what I want. Adding values up to 255 work fine! So it’s the 16bit addition which is playing up. I must be being thick here but don’t you need to handle the carry if the low byte rolls over 0xFF by the addition of 0x2C to it? I would have thought that the compiler would do this for me as that’s what I have asked for?

Is this a bug? Is there a good and fast way to do this?

Keep well,


Will
Will Reeve



Joined: 30 Oct 2003
Posts: 209
Location: Norfolk, England

View user's profile Send private message Send e-mail Visit poster's website MSN Messenger

PostPosted: Wed Aug 04, 2004 9:27 am     Reply with quote

I am blind, didn’t notice the ADDWFC is the second line! It’s strange that it doesn’t seem to do what I ask of it? I get a very strange square wave pattern with variable frequencies, just like a rollover problem.

Will
Will Reeve



Joined: 30 Oct 2003
Posts: 209
Location: Norfolk, England

View user's profile Send private message Send e-mail Visit poster's website MSN Messenger

PostPosted: Wed Aug 04, 2004 10:13 am     Reply with quote

Now this is REALLY strange, values up to 299 work perfectly. If I use 300 everything goes to pot, 301, doesn’t work but 302 does work. It’s beyond me this! Other random values I have chosen seem to work of 500, 1200 etc and even generate the expected frequencies! But go back to 301 and its broken! Help!
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

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

PostPosted: Wed Aug 04, 2004 12:12 pm     Reply with quote

Try this out. The problem has to do with the number of instructions the interrupt handler takes being the same as the low byte of the value being added to the CCP register. Timer1's value just happens to be at that value (CCP1 + low byte of value) and a false compare happens. This method seems to work better.

Code:

#if defined(__PCM__)
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7) 

#elif defined(__PCH__)
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7) 
#endif

#include <stdlib.h>
#include "input.c"

long CCP1;
#locate CCP1=0xFBE


long period;

#int_ccp1
void isr()
{
  long dummy;

  dummy = CCP1;
  dummy += period;
  CCP1 = dummy;
}

void main()
{
  period = 300;

  setup_ccp1(CCP_COMPARE_INT_AND_TOGGLE);   
  setup_timer_1(T1_INTERNAL);    // Start timer 1

  enable_interrupts(INT_CCP1);   // Setup interrupt on falling edge
  enable_interrupts(GLOBAL);

  while(TRUE)
  {
    printf("\n\rEnter period: ");
    period = get_long();
  }
}
Will Reeve



Joined: 30 Oct 2003
Posts: 209
Location: Norfolk, England

View user's profile Send private message Send e-mail Visit poster's website MSN Messenger

PostPosted: Thu Aug 05, 2004 10:35 am     Reply with quote

Thanks, that works much better. I guess it takes just the two commands to get the CCP1 register set using this method.
Keep well,

Will
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