![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
timer 2, 4 & 6 issues |
Posted: Mon Feb 28, 2011 6:10 pm |
|
|
Hi There,
I'm experiencing problems setting up timer 2, 4 & 6. I calculate the value but the interrupt seems to be all over but sure not where it's supposed to be...
Thus I assume i'm doing some mistake in my calculation:
10MHz/4=2500000Hz
TX_DIV_BY_4=625000Hz
1/625000=0.0000016s
I want the interrupt to kick in after 200uS so:
0.00002/0.0000016=12.5. So if I setup my timer like this:
setup_timer_2(T2_DIV_BY_4, 13, 1); and then use set_timer2(13); when I set the output and reset the output in timer2_isr() where I also set_timer2(0) it should give me nice pulses slightly over 20uS, right?
Well it's not, it's actually not even running my application correctly anymore...
I'm wondering what I'm doing wrong? I had gone through this over and over again today but couldn't figure it out, it doesn't seem to be that difficult... :(
I appreciate little hints to my wrong doing.
Thanks a lot! |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 28, 2011 6:39 pm |
|
|
Post a short, compilable test program that demonstrates the problem.
The program should be similar to the one shown below. It's very short.
It only contains code needed to show the problem and no more.
It can be copied-and-pasted into MPLAB and it will compile with no errors.
Also post your compiler version.
Code: |
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
// Blink the LED on pin B0 at approximately 1 Hz.
#int_timer1
void timer1_isr(void)
{
output_toggle(PIN_B0);
}
//======================================
void main()
{
output_low(PIN_B0);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
set_timer1(0);
clear_interrupt(INT_TIMER1);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
while(1);
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19368
|
|
Posted: Tue Mar 01, 2011 3:45 am |
|
|
Also think about overhead.
You have a 10Mhz clock. 2.5MIPS.
It takes typically about _30_ instruction times to get into the interrupt handler.
So about 12uSec, to actually get into the handler!. It then takes about the same time to get out of the handler again. So with your processor, doing _nothing else_, you could get to about 24uSec pulses....
So, 'no', you will not get "nice pulses slightly over 20uS"...
Also, if the interrupt is continually being called, then you will only get one instruction of the main code executed between each successive interrupt call, so performance of the main code will disintegrate....
If you want pulses at this sort of frequency, you need to let the _hardware_ do it. (PWM).
Then use the third parameter in the timer2 settings (count between interrupts), to give the interrupt rate required.
So if you wanted '20uSec' as the output period, implying 200 cycles of the clock, something like:
setup_timer_2(T2_DIV_BY_1, 49, 10);
Remember the timer clock is already crystal/4.
Then:
setup_ccp1(CCP_PWM);
set_pwm1_duty(100L);
Will give a square wave at 50KHz on the PWM output.
The interrupt will be called every tenth cycle of this clock (200uSec), and you do whatever you need in here (but keep it quick....).
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
|
Posted: Tue Mar 01, 2011 11:08 am |
|
|
Thanks for these two replies, I haven't gotten to write a test project to demonstrate the problem yet and it seems as if I need to give some more information, I'm not looking for something pulsing at 20uS but for single pulses of 20uS appearing in a frequency of ~50-60Hz (can be 100Hz or 120Hz too) but nothing too critical...
thus,
I set e.g. timer1 to kick in every 20ms where i set my output and i also set timer2 to kick in in 20uS to reset my output. Doesn't this sound like something that should be possible with the timers? Or would be better of studying PWM anyways? Also I need 3 pulses that may be synchronized, may be offset to each other or may even have different frequencies.
Thanks for hints! |
|
![](templates/subSilver/images/spacer.gif) |
5440
Joined: 08 Feb 2009 Posts: 11
|
|
Posted: Tue Mar 01, 2011 12:28 pm |
|
|
I wrote one for a 1ms TMR INT, but now do my interupt handlers (GLOBAL INTS) manually, using ASM where required.
It was more work and lots of re-reading of the data sheet, but I now have a better understanding of the complier and 18F part I'm using. I can also adjust for interupt latency best I can, so I can get close to 1ms TMR events.
One just has to make sure they save all the correct registers in the ISR using this method. It's not 100% predictable as I have other INT's enabled, but works for me.
I have this one set up as a array of timers with a 1ms base (20MHZ, 18F part with TMR as HIGH priority), sort of like how timers are implemented in a PLC (ie Control Logix). Every 1ms int event just increments a counter and exits the ISR. The main program handles the software timer over head. These GP timers work well for debouncing, poors man's PWM with a period =100ms and duty cycles of 10%, 20% etc. I'm about to set up another GP timer to produce a 50ms sample tick for my PID routine. This method of software timers seems to work well assuming your longest/worst case scan time is shorter than the choosen timer base. |
|
![](templates/subSilver/images/spacer.gif) |
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
|
Posted: Tue Mar 01, 2011 2:10 pm |
|
|
Uh, I just figured out that I don't need any pulses that are as short as 20uS, they actually won't go shorter than 200uS so I'm probably still gonna stick to my timer solution...
First figure out which one is the smallest and then set the "frequency timers" with delays in order to get the correct offsets... in the "frequency timers" that would kick in every 20ms or similar, I would set the pin and each 8bit timer that would kick in after 200uS (or more) to reset the pin again.... that doesn't seem like a bad solution to me... anyone? |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|