|
|
View previous topic :: View next topic |
Author |
Message |
vpan
Joined: 31 Oct 2008 Posts: 14
|
TIMER interrupt question |
Posted: Sun Nov 30, 2008 6:41 am |
|
|
hello to all...
I have an 16f877 and 20 MHZ XT.
I want to estimate the minimal time for 1 interrupt on TIMER0.
How can I do this?
There is a formula for this?
Thank you. |
|
|
Rohit de Sa
Joined: 09 Nov 2007 Posts: 282 Location: India
|
|
Posted: Sun Nov 30, 2008 7:42 am |
|
|
Timer interrupts are dependent on the following:
- oscillator frequency
- timer size (8bit/16bit/32bit)
- prescaler value
- postscaler value
Timers can be run off several clock sources - internal oscillators, the main external crystal, and other external clocks. Naturally, the faster the clock source, the faster the timer will increment.
The 'prescalar' for the timer is like a clock speed divider: it slows the clock being 'seen' by the timer. Thus, the timer roll-overs occur slower.
In the case of a postscaler, the timer rolls-over as usual, but does not generate an interrupt. The postscaler 'slows' the pulses created by the roll-over, ie after the timer. An interrupt is generated only when the postscaler also 'rolls-over'.
In the case of timer0, there is no postscaler, so whenever timer0 overflows from 0xFF to 0x00, an interrupt is generated.
Datasheet for the '877: http://ww1.microchip.com/downloads/en/DeviceDoc/30292c.pdf . Look at section 5.0
Timer0 interrupt rate can be calculated using this algorithm:
(oscillator speed) / 4 = (instruction cycle speed)
(instruction cycle speed) / (prescaler value) = (timer0 input rate)
(timer0 input rate) / 256 = (interrupt frequency)
The reciprocal of the interrupt frequency will give you the time for 1 interrupt.
Rohit |
|
|
vpan
Joined: 31 Oct 2008 Posts: 14
|
|
Posted: Sun Nov 30, 2008 8:45 am |
|
|
Thanks for answer!!
Let's say I put prescaler=1 (and 20MHz XT).
That means the minimal time for 1 interrupt is 51.2usec ???
Correct me if I'm doing wrong! |
|
|
Rohit de Sa
Joined: 09 Nov 2007 Posts: 282 Location: India
|
|
Posted: Sun Nov 30, 2008 9:02 am |
|
|
If you have a 20MHz oscillator, the instruction clock speed is 20/4=5MHz (more technically correct is '5MIPS' - 5 million instructions per sec). Note that the PIC has a quadrature-clocked instruction cycle. This basically means that instructions are executed at (oscillator speed/4).
Timer0 is an 8bit timer; it will count upto 255 before rolling-over. It increments on every instruction cycle (ie with a 20Mhz oscillator, it increments at 5Mhz). Therefore, if prescaler=1:1, timer0 generates an interrupt every 256*(1/5MHz), as you correctly calculated.
Rohit |
|
|
vpan
Joined: 31 Oct 2008 Posts: 14
|
|
Posted: Sun Nov 30, 2008 9:10 am |
|
|
Can I achieve smaller time for one interrupt
with these materials (same pic, same crystal) ? |
|
|
Ttelmah Guest
|
|
Posted: Sun Nov 30, 2008 3:07 pm |
|
|
Yes, and no....
You can get a shorter interval, by using Timer2. This has the ability to automatically trigger/reset at a programmed count.
_However_ there is a big caveat. Interrupts take _time_ to be handled. Even with a tiny routine, doing nothing, you need something in the order of 70 instruction times between interrupts. By the time you actually 'do' anything in the interrupt handler, even 256 instruction times is 'pushing it'.
It is possible to shorten this time overhead, by completely writing the interrupt handler yourself, but unless what you want to do is minimal, the savings decline (basically, the more you do in the handler, the more overhead there _has_ to be as more registers _must_ be saved).
There should not normally be any need to interrupt at high speed. If you want to do things at high speed, you do them in the main code, and don't get involved in interrupts at all. The main 'point' about interrupts, is to give a response to an external event. If you just want timings, monitor the event in a loop, and read the timer when it happens. You can get resolution down to only a few instructions. Alternatively, use the CCP hardware, which can _record_ the time, when an event happens for you.
Best Wishes |
|
|
Rohit de Sa
Joined: 09 Nov 2007 Posts: 282 Location: India
|
|
Posted: Sun Nov 30, 2008 10:08 pm |
|
|
Another option to obtain shorter interrupt intervals would be to 'pre-load' the timer with the appropriate value. Follow the scheme shown in this pseudo-code:
Code: | timer0_isr:
{
(user code)
write preload_value to timer0
}
main:
{
(user code)
} |
This will cause the timer to increment (255-preload_value) times before it generates an interrupt. Note that timer0 does not increment for two instruction cycles just after it has been written to.
But keep in mind what Ttelmah posted - it takes around 70 instruction cycles to go into the interrupt; plus you have to execute your own ISR code. So in that case: Quote: | There should not normally be any need to interrupt at high speed. If you want to do things at high speed, you do them in the main code, and don't get involved in interrupts at all. The main 'point' about interrupts, is to give a response to an external event. If you just want timings, monitor the event in a loop, and read the timer when it happens. You can get resolution down to only a few instructions. |
Rohit |
|
|
|
|
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
|