Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Time base interrupt

Status
Not open for further replies.

atferrari

Well-Known Member
Most Helpful Member
Based on the "time-base interrupt" technique outlined by Stewart in this thread:
http://forum.microchip.com/tm.asp?m=59908&mpage=1&key=interrupt&anchor#60348

I've wrote some code for the 16F877, controlling eight LEDs, which I made it complex enough to see how far I could go:

LED 0 blinks once with a certain on time
LED 1 same as above with different on time
LED 2 blinks for a certain number of times with equal on-off periods
LED 3 blinks for a certain number of times with different on-off periods
LED 4 blinks for a certain number of times with equal on-off periods
LED 5 blinks continuously with equal on-off periods
LED 6 blinks continously with different on-off periods
LED 7 blinks continuously with equal on-off periods

The main loop consists of nine tasks: one for the keyboard and one for each LED. Each LED is activated by pressing a different key in the keyboard. Time base is 2 msec and on/off periods range from 250 msec to 1500 msec.

Basically I can say that it worked from the first try demonstrating his point but after experimenting for a while I've started to wonder about the following points:

a) A keyboard debouncing delay (I use 25 msec) requires just one 8-bit counter to be decremented while a 1500 msec delay demands three 8-bit counters. How to cope with VERY LONG delays and a SMALL time-base?

b) With many of the delays requiring two or three (BTW why not four or five?) 8-bit counters I've found that the time spent by the ISR could ammount up to one tenth of the time base period. Isn't that excessive? What if I have many other tasks to serve?

c) When only TMR0 interrupt is enabled, it's an event that repeats after an exact amount of time. The LEDs' blinking periods, since they affect each other, are essentially not exact. I assume then than whatever other event I want to occurr at an exact moment, could not! Let's say that if I want a pin going high exactly every 25 msec during 6 msec what I could only get is just ABOUT that.

d) What if other interrupts are enabled?. Being unable to assign any priority to TMR0 interrupt (16F877) the 2 msec time base would became not an exact occurrence anymore!

e) I run across an unforeseen difficulty: all LEDs required two flags: one showing they were or not "active" and another telling if they had to be ON or OFF. Probably due to lack of experience I found the handling of those flags complicate and cumbersome and hard to debug. I couldn't follow Stewart's pseudo code very well regarding flags. I work in assembler so whatever comes from C language is hard for me to understand. Sorry about that. :oops:

Comments of any kind appreciated.If at all possible, please follow the order of points as stated above. That would help me.

Agustín Tomás
 
First of all, I don't really get what you're trying to do, but I'll just try to answer the questions :D

atferrari said:
Based on the "time-base interrupt" technique outlined by Stewart in this thread:
http://forum.microchip.com/tm.asp?m=59908&mpage=1&key=interrupt&anchor#60348

I've wrote some code for the 16F877, controlling eight LEDs, which I made it complex enough to see how far I could go:

LED 0 blinks once with a certain on time
LED 1 same as above with different on time
LED 2 blinks for a certain number of times with equal on-off periods
LED 3 blinks for a certain number of times with different on-off periods
LED 4 blinks for a certain number of times with equal on-off periods
LED 5 blinks continuously with equal on-off periods
LED 6 blinks continously with different on-off periods
LED 7 blinks continuously with equal on-off periods

The main loop consists of nine tasks: one for the keyboard and one for each LED. Each LED is activated by pressing a different key in the keyboard. Time base is 2 msec and on/off periods range from 250 msec to 1500 msec.

Basically I can say that it worked from the first try demonstrating his point but after experimenting for a while I've started to wonder about the following points:

a) A keyboard debouncing delay (I use 25 msec) requires just one 8-bit counter to be decremented while a 1500 msec delay demands three 8-bit counters. How to cope with VERY LONG delays and a SMALL time-base?

You don't really need many counters. You can simply have 1 counter and 1 register.
Example:
;define variables
counter: 1
num_of_counts: 1

Then just increment the counter and when it reaches the maximum, increase the num_of_counts.
You can do, after that, some conditions, like if num_of_counts is 3, then do something, when it's 4, do something else and maybe set it to 0 again.
And after each increment of counter you'll have to check if it's reached its maximum (you can simply see the Z in status register, meaning that the counter reached 0 again).

b) With many of the delays requiring two or three (BTW why not four or five?) 8-bit counters I've found that the time spent by the ISR could ammount up to one tenth of the time base period. Isn't that excessive? What if I have many other tasks to serve?

PICs can be set to operate in 2 frequencies, if the internal oscillator is used. So, during ISRs, you can set it to a higher frequency.
Also, I don't know how you set the time base, but maybe you could change it for the time of ISRs.

c) When only TMR0 interrupt is enabled, it's an event that repeats after an exact amount of time. The LEDs' blinking periods, since they affect each other, are essentially not exact. I assume then than whatever other event I want to occurr at an exact moment, could not! Let's say that if I want a pin going high exactly every 25 msec during 6 msec what I could only get is just ABOUT that.

Then you should improvise here. Define a memory address, called interrupts. Then, when TMR0 interrupt is executed, set the corresponding bit (out of eight) to 1 and exit the interrupt routine. Then, somewhere in the code, check for those bits and make LED changes (blinking) accordingly. When you finished processing a particular LED, clear its bit in interrupts memory address (the variable you defined).

d) What if other interrupts are enabled?. Being unable to assign any priority to TMR0 interrupt (16F877) the 2 msec time base would became not an exact occurrence anymore!

Same as above.

e) I run across an unforeseen difficulty: all LEDs required two flags: one showing they were or not "active" and another telling if they had to be ON or OFF. Probably due to lack of experience I found the handling of those flags complicate and cumbersome and hard to debug. I couldn't follow Stewart's pseudo code very well regarding flags. I work in assembler so whatever comes from C language is hard for me to understand. Sorry about that. :oops:

The assembler is THE way to go, especially when u'r learning. Try applying your logic to it, I'm sure you'll find an efficient way to do it.

Comments of any kind appreciated.If at all possible, please follow the order of points as stated above. That would help me.

Agustín Tomás

Getting back to your timebase. I don't know how you set (generate) it, either internally or externally, but in my opinion (and that's how it's usually done), you set an external oscillator to a much higher frequency than your timebase and you scale it down for the parts that require a precise timing. That way, 1. the timebase is more precise, because a difference in a couple of cycles at 100MHz is not notisable when it's scaled to 1MHz, and 2. your code can be executed much faster, for the parts that don't require precise timing (so, the program waits 2 ms for the timebase, then spends 1 us to execute everything, then waits again; instead of getting 2ms pulses and trying to do everything during that time).

Good Luck,
TI|CP
 
There's nothing 'magic' about interrupts, you need to keep them as small and fast as possible - otherwise (as you've found) they may be taking up too much processor time - with the ultimate result that they may not have time to exit before the next timer interrupt occurs.

For a clock I usually use tmr2 to generate 10mS interrupts, this allows timing down to 100th of a second - but leaves plenty of time for the interrupt routine and normal processing.
 
Hi Nigel,

Any special reason for using TMR2? Whay not TMR0 which has its own interrupt?

In other forum someone suggested (but not explained how) to use slow, medium and fast time bases? Any idea about that? One timer or three?

Thanks for your help. :)

Agustín Tomás
 
atferrari said:
Hi Nigel,

Any special reason for using TMR2? Whay not TMR0 which has its own interrupt?

Tmr2 is more versatile, and easier to use, Tmr0 is a very old timer (back to the very early PIC days) and has a number of flaws which you have to compensate for.

In other forum someone suggested (but not explained how) to use slow, medium and fast time bases? Any idea about that? One timer or three?

I suppose it all depends what you are trying to do, I used 10mS Tmr2 interrupts to generate a digital alarm clock, the interrupt keeps a running count of seconds, minutes, hours, and sets a flag every time the seconds change. The main program waits for this flag and updates the display when it's set (and clears it again), then it checks the alarm settings - you can add as many alarms as you want, as you have almost a second to check them.

If you use three timers things are probably going to get complicated?.
 
Homework done...

Hi Nigel,

Finally I've implemented the same LEDs now using two time bases, based on TMR0 interrupts. :) Two was enough.

It took little work to get it up and running.

Having only LEDs, all turning on/off with delays in the hundreds of msec range, I set up two time bases: 5 msec directly from TMR0 and 50 msec, also inside the ISR from a counter decremented continuously from 10 to 0.

The thread in charge of checking what delay counter had to be decremented, is in the main code. That keeps ISR to a real minimum.

Let's say that I got the concept proved satisfactorily. I am now exploring ADC and PWM together. :(

Thanks for replying.

Agustín Tomás
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top