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

Hardware PWM 100Hz, 50% duty

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



Joined: 23 Apr 2004
Posts: 227
Location: The Netherlands

View user's profile Send private message

Hardware PWM 100Hz, 50% duty
PostPosted: Sun Aug 05, 2007 2:23 pm     Reply with quote

How can i made this?

Hardware is:
PIC18F4620 with 20Mhz Crystal
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Aug 05, 2007 5:15 pm     Reply with quote

This post has the formula to calculate the PWM frequency:
http://www.ccsinfo.com/forum/viewtopic.php?t=17993

To find the lowest possible PWM frequency for a 20 MHz crystal,
just put the following values into the equation:

Crystal frequency: 20,000,000 Hz
PR2 value: 255
Timer2 prescaler: 16

Then calculate the result.
The Puma



Joined: 23 Apr 2004
Posts: 227
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun Aug 19, 2007 6:53 am     Reply with quote

Then this is the lowest freq 1220Hz?
Ttelmah
Guest







PostPosted: Sun Aug 19, 2007 7:44 am     Reply with quote

With that clock, and that chip, in PWM mode, yes.
However there is a solution, provided you are not using timer3. In _CCP_ mode (as opposed to PWM mode), the module can be programmed to use timer1 or timer3, instead of timer2 as it's source. If you program it in this mode, to drive the output high on address match, then have a CCP interrupt handler, which changes it to drive the output low on match (and back again on the next call), much slower frequencies can be achieved. (potentially down to 20000000/4/8/65535/2 Hz).
Even easier, just program a Timer2 interrupt at 200Hz, and toggle the output pin in this. Downside is that the output timing, can be fractionally affected by other interrupts (whereas the CCP version gives accurate timings).

Best Wishes
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun Aug 19, 2007 8:49 am     Reply with quote

Or use a slower crystal.
Why is it that everybody wants to use the highest clock frequency possible? At half the clock frequency your PIC will consume half the power, meaning a cheaper power supply, longer battery life, less heat generated and you will help to save the environment as well. For a 100Hz PWM you can reduce the clock to 1MHz, save 95% on power consumption and still have lots of processing power for other functions.
The Puma



Joined: 23 Apr 2004
Posts: 227
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun Aug 19, 2007 10:11 am     Reply with quote

@Ttelmah

Can you give me an example code how that is done
Let say for 10Hz

Then i can play with that code for other freq.
Ttelmah
Guest







PostPosted: Tue Aug 21, 2007 5:16 am     Reply with quote

OK. No guarantees!....
Code:

//add processor definition here
#use delay(clock=20000000)
int1 toggle=0;

#int_CCP1
void  CCP1_isr(void)
{
  if (toggle) {
     //On alternate interrupts, set back to set the pin.
     toggle=0;
     setup_ccp1(CCP_COMPARE_SET_ON_MATCH);
  }
  //The first time the interrupt occurs, the output pin has been _set_, and
  //we arrive here. Reprogram the CCP, to clear the pin next time
  else {
     toggle=1;
     setup_ccp1(CCP_COMPARE_CLR_ON_MATCH);
  }
}

void main()
{
   //Adjust the setups t suit your chip
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_ccp1(CCP_COMPARE_SET_ON_MATCH);
   //No guarantees that the compiler realises that is has to do this,
   //so setting TRIS manually.
   set_tris_c(0xFB);
   set_timer1(0);
   CCP_1=31250;
   clear_interrupt(INT_CCP1);
   enable_interrupts(INT_CCP1);
   enable_interrupts(GLOBAL);
   //Using Timer 1 (change the CCP setup, if you want to use Timer3)
   //Timer1, will count in steps of 20000000/4/8
   //to give (say) 10Hz, we want a _half cycle_ of 50mSec. The
   //count needed
   //for this is 50E-3/(1/(20000000/4/8)) = 31250
   
   while (TRUE) {
   //rest of code here
   
   }
}

Now, the 'key', is that the hardware sets or resets the pin, on the defined count. At the same time an interrupt is triggered, depending on what else is going on (other higher priority interrupts etc.), _so long as the interrupt handler is reached, before the count once again triggers the CCP_, we can reverse the operation to happen at this point. Hence on the first pass, I set the pin, then next time, reset it, etc. etc.. So the CCP, represents 'half cycle' time. Because the CCP, allows 16 bit compare values, and uses Timer1, or Timer3, The longest 'half cycle' possible, is just over 100mSec, allowing down to about 5Hz operation from a 20MHz clock. :-)

Best Wishes
The Puma



Joined: 23 Apr 2004
Posts: 227
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Aug 21, 2007 10:18 am     Reply with quote

Ok thanks, i will playing with it
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