View previous topic :: View next topic |
Author |
Message |
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
Is Setting timer inside timer ISR legal? |
Posted: Sun Aug 03, 2014 9:32 am |
|
|
Hello.
I know its kind of silly question and yet I wanna ask:
Is it legal in regards to the reliability and steady operation of the system to set the timer inside the timer ISR.
I know, usually timer 2 has the ability to overflow at certain register value, but still I want to be sure if it is possible to implement (e.g tick scheduler) or variable time interrupt event using different timer.
In further development of the application may include PWM so I want to avoid using timer needed for.
Code: |
#INT_TIMER0
void tmr_isr(void)
{
increment_global_tick_here;
some_dummy_staffs_here;. . . .
. . .
. . .
set_timer0(global_var_here);
} |
10x _________________ A person who never made a mistake never tried anything new. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Sun Aug 03, 2014 10:01 am |
|
|
You can set/clear any register/variable in any ISR if you want to, the Compiler Cops won't be coming to your door.
Now as for 'reliability' that depends on what the application is.
The fact that you want to set the timer register inside the ISR means that you have a good reason to like...
"something" triggered the ISR ,so I need to change the timers value from 'x' to 'y' then carry on the 'main' task.
try it,see how the 'system' performs...
hth
jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Aug 03, 2014 10:21 am |
|
|
It's one of the techniques to control the timer interrupt rate.
Here are some CCS example and driver files that do it:
Quote: | c:\program files\picc\examples\ex_patg.c
c:\program files\picc\drivers\d41256.c
c:\program files\picc\drivers\mt4264.c |
|
|
|
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
|
Posted: Sun Aug 03, 2014 10:24 am |
|
|
Thx for the reply.
So it is a good/safe way to determine the time after which the next interrupt will occur?
Because the ultimate idea, is to control the delay for the next ISR event, by adjusting the timer register.
If i set the timer once inside the main function it would take effect once (probably undesirable). If I change the global variable instead, that will change the period of the ISR occurrence from that moment on.
I hope you get it! _________________ A person who never made a mistake never tried anything new. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sun Aug 03, 2014 10:45 am |
|
|
The big problem is the latency, and the 'range' of values you may want.
Calling the ISR takes time, as does getting out again. It takes typically perhaps 30 instruction times to get into the ISR. If you have other ISR's, and you happen to be inside one of them when the timer interrupt fires, the latency could jump to 100 instructions....
Now provided the 'times' you want are large, there is no problem, just add the value to the current timer count. Remember though what happens if the total value you want would be more than the count allowed?. If your times might be short, then you run into the problem of not being able to set a time below the total latency and service time.
So, what sort of range of times do you need to handle?. What is your CPU clock rate?. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Aug 03, 2014 11:00 am |
|
|
It's perfectly allowed.
A few hints on gotcha's:
1) It takes considerable time between the interrupt being triggered and the execution of your ISR because the compiler inserts code to save registers and to determine which ISR to call. Exact timing depends on compiler release and the PIC you use, for a PIC18 it is about 60 instructions, less for a PIC16.
2) Even with point 1 taken into account there is more variance in ISR entry timing because at the time your timer interrupt is triggered another interrupt might already being handled. That one has to finish first, restore all the registers (60 instruction times) and then save all registers to start handling your interrupt (another 60 instruction times).
2a) PIC18 processors and higher have multiple interrupt levels that can either make timing worse, or can be used to your advantage by giving the timer interrupt the highest interrupt level (so it can interrupt other interrupts).
One way to minimise the effects of the above is when you not only set the timer value in the ISR, but read the current value first and then compensate for this value. You know the timer interrupt got triggered as it overflowed from 65535 (or 255 for 8 bit) to 0. The timer value you read in the ISR is the (variable) time it took to get to the line where you read the timer value. Example: Code: | #define TIME_DELAY 500
void timer_ISR()
{
int16 time_till_here = read_timer1();
set_timer1(TIME_DELAY - time_till_here);
} |
|
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Sun Aug 03, 2014 11:51 am |
|
|
I use timers a lot for a delay time source and I set the new timer value in
the ISR. I set the timer value in the ISR so that I get exactly 10ms rate. I
do this by putting an output_toggle() command in the ISR then using my
scope to to "tune" the timer reset value get a 10ms rate on the toggle pin.
I then use the 10ms source for clock debounce and other things. If I add
more instructions to the ISR I then re-tune the reset value to keep the 10ms
time. Not extremely precise but definitely enough for what i need.
One thing I use it for is a heartbeat by counting one hundred 10ms intervals
then toggling a 1 second "heartbeat" pin connected to an LED. I put this in
every design and it quickly tells me if the MCU clock and timer are
functioning normally. Ultimately I always have a 10ms output and a one
second output reference in every project. _________________ Google and Forum Search are some of your best tools!!!!
Last edited by dyeatman on Sun Aug 03, 2014 11:59 am; edited 3 times in total |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sun Aug 03, 2014 11:56 am |
|
|
Ckielstra's scheme works well.
With minor tweaks you can get interrupt periods within a couple of machine cycles of the expected value and minimal jitter.
Once you've got it running at the required rate it's not sensitive (within reasonable limits) to later ISR modifications.
Mike |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sun Aug 03, 2014 12:52 pm |
|
|
However he is talking about wanting to vary the time. This opens a new 'can of worms'.....
It is worth perhaps pointing out that with Timer2, you can vary the point at which it automatically resets. |
|
|
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
|
Posted: Fri Aug 08, 2014 11:54 am |
|
|
Thanks to all of you.
Now i have more info to consider in order to create such an algorithm. _________________ A person who never made a mistake never tried anything new. |
|
|
|