View previous topic :: View next topic |
Author |
Message |
Nick Guest
|
PWM with a range of 9-12 Hz |
Posted: Mon Nov 29, 2004 7:56 pm |
|
|
Since the PWM hardware will not go less than 1.2khz with a 20mhz clock. I need a different way.
I was thinking about using set_timer1 (16 bit), but I am confused. What is a prescaler? In the CSS manual it doesnt describe what it is on page 144 when it talks about set_timer function.
Thanks
Nick |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Nov 29, 2004 9:02 pm |
|
|
Look at the datasheet. But basically it divides the clock by this value so that the timer increments more slowly |
|
|
Nick Guest
|
|
Posted: Mon Nov 29, 2004 9:41 pm |
|
|
thanks for the info, i was on the wrong page.
Here is a question about my math
1/20,000,000 mhz = 0.00000005 sec
0.00000005 sec*16(prescaler)*16(postscaler)*255(peroid)
gives me an interupt every 0.0032
Does anyone have any ideas how to get me down the the herts range?
I guess I could put a static int counter inside the interupt function, but is there another solution that is cleaner using a 20mhz clock?
Nick |
|
|
Kenny
Joined: 07 Sep 2003 Posts: 173 Location: Australia
|
|
Posted: Mon Nov 29, 2004 10:00 pm |
|
|
Nick wrote: |
I guess I could put a static int counter inside the interupt function, but is there another solution that is cleaner using a 20mhz clock?
Nick |
Static int counter is nice and clean.
Check out Ttelmah's example using timer 0:
http://www.ccsinfo.com/forum/viewtopic.php?t=17993
Using the same divider of 16, and with loopcount 120, you get 10.17Hz with
120 increments. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Nov 29, 2004 10:55 pm |
|
|
Your calculation is a bit off. The timer is driven by 1/4 of the clock so it is really 5MHz instead of 20MHz.
Now about that PWM, timer1 is 16bits and can have a prescaler of 8. So that is (5MHz/8)/65536 or 9.536Hz. Now if you use the CCP module you could generate a 9.536Hz PWM with 16bits of resolution! You can't get much better than that. |
|
|
Nick Guest
|
|
Posted: Mon Nov 29, 2004 11:08 pm |
|
|
Code: | #include <16F876.h>
//set fuses
#fuses HS,NOWDT,NOPROTECT,PUT//,//BROWNOUT,NOLVP
#use delay(clock=20000000)// 20mhz clock
//set up PC communications
#use rs232(baud=4800, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//timer interupt
#int_timer2
void blah()
{
static long bs =0;
bs++;
if (bs ==600)
{
printf("BS\r\n");
bs =0;
}
}
void main()
{
output_high(PIN_B1);
delay_ms(1000);
output_low(PIN_B1);
delay_ms(1000);
printf("Starting\n\n");
printf("Starting 2\n\n");
output_high(PIN_B1);
delay_ms(1000);
output_low(PIN_B1);
setup_timer_2(T2_DIV_BY_16, 127, 16);
while (true)
{
printf("going to sleep\r\n");
sleep(); //sleep for a second
printf("back from sleep\r\n");
}
}
|
Here is my code, somethings up with my interupt. its never called. Anyone got an idea?
Nick |
|
|
Kenny
Joined: 07 Sep 2003 Posts: 173 Location: Australia
|
|
Posted: Mon Nov 29, 2004 11:24 pm |
|
|
Mark wrote: | Your calculation is a bit off. The timer is driven by 1/4 of the clock so it is really 5MHz instead of 20MHz.
|
Yep, 5MHz, 0.2uS increments
With divide by 16, and timer 0 overflowing every 256 counts, and loopcount of 120, period is
0.2*16*256*120 = 98304uS or 10.17Hz.
Edited: Oops, sorry Mark, your comment was in regard to Nick's code,
not mine.
Nick, in the timer 2 code you forgot to enable the interrupts.
Put these statements at the beginning of main()
setup_timer_2(T2_DIV_BY_16, 127, 16);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
and don't go to sleep :-) |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Nov 29, 2004 11:33 pm |
|
|
I was referring to this calculation:
Quote: |
1/20,000,000 mhz = 0.00000005 sec
0.00000005 sec*16(prescaler)*16(postscaler)*255(peroid)
gives me an interupt every 0.0032
|
|
|
|
Nick Guest
|
|
Posted: Tue Nov 30, 2004 2:30 pm |
|
|
thanks for the help! |
|
|
Nick Guest
|
my 9.5hz timer 1 comes up as 4.7Hz on the scope? |
Posted: Wed Dec 08, 2004 10:46 am |
|
|
I have timer 1 setup as setup_timer_1(T1_internal,t1_div_by_8) and in my interupt function it just turns a pin on and off every other call. I figure i should be at around "(5MHz/8)/65536 or 9.536Hz". But the oscilloscope shows me 4.7Hz.
setup is very simple 20mhz cr clock(which reads 20mhz on the scope) and a pic16f876a with a LED
Nick |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Dec 08, 2004 11:37 am |
|
|
Nope, you are turning on every other int so divide that by 2 to get 4.768Hz. |
|
|
Nick Guest
|
|
Posted: Wed Dec 08, 2004 1:09 pm |
|
|
Hum.. my solenoid is rated at 30Hz with max of 80% duty. Does that mean I would need a 30Hz signal which at 50% is only 15Hz on the scope?
Which one of these is correct if I use software to implement my PWM signal
_ is 0 volts and - is 5 volts
____---- @ 50% duty
or
_-_-_-_-_- @ 50% duty
Thanks
Nick |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Dec 08, 2004 1:20 pm |
|
|
Quote: |
Does that mean I would need a 30Hz signal which at 50% is only 15Hz on the scope?
|
No
30Hz is the time between rising edges or about 33ms. 80% duty cyle means that the high time for the waveform should be 80% of 33ms or less which is about 26.6ms |
|
|
Guest
|
|
Posted: Wed Dec 08, 2004 7:33 pm |
|
|
When the solenoid says rated at 30 Hz, does that mean it needs a 30Hz wave form which means i need 60Hz pulses? or does that mean it needs a 30Hz pulses that can produce 15 Hz waveforms?
Thanks for the help
Nick |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Dec 08, 2004 7:59 pm |
|
|
What??? Did you understand my explaination? Hz means cycles per second. It is the repetition rate of the signal. The signal has a high time and a low time. A 50% duty cycle is a symmetrical waveform. That is the high time is equal to the low time which is one half of the period. |
|
|
|