HC11 interrupt handling query

Hi, I have an HC11 counting edges from an external, asynchronous source, into the pulse accumulator (PA in what follows). Pulse rate is 'slow' in relation to processing and program loop cycle.

The count may exceed 255, so I'm using a small ISR on pulse accumulator counter overflow to increment a high order counter byte. I need to count the pulses over a 1 second window, every second, as follows:

LOOP: Collect the accumulated total from the PA register and high count byte, and store. Clear the PA register and high byte. Wait for a second. GOTO LOOP

The PA rollover is the only interrupt involved, everything else is polled, within a single mainline routine. My concern is what happens if there are almost exactly 256n pulses in one second. If this occurs, then I need to be sure that no mainline - ie. non-ISR - instructions can be interposed between the PA register overflowing and the ISR performing the bump of the high byte. If they can, then there is a possibility that my stored count could be stored incorrectly.

I've been through the detailed timing in the venerable 'pink book', but this is one case that seems not to be covered.

Do I need to do anything special to ensure the count is guaranteed right? BTW, real problem not homework (surely the HC11 is long gone from classrooms these days.?).

Reply to
bruce varley
Loading thread data ...

You dont need to worry about it, the ISR will always perform the update before you can read it. You do need to worry about the counter overflowing between reading the 2 bytes but this is easily cured by stopping the counter before reading it. This is a really poor method because it uses 100% of the prcessors time just about all of it doing nothing.

Reply to
cbarn24050

The problem is more general that HC11. Most timers/processor combos will have this issue that it is possible for the timer to overflow, reading the counter before the overflow but picking up the overflow counter after the interrupt, or the reverse.

the

and

be

between

be

classrooms

Ther are several solutions. For slow counting read the overflow counter before and after reading the PA. If the two overflows match then the PA value is safe. If the overflows don't match then take the second and treat the PA as if it were zero (equally take the first and treat the PA as max value). This works well as long as the cound speed is slow relative to the time to do the above processing. Assuming that "wait for a second" in your loop really means the processor is idle then we can make good use of it and work a different way that doesn't ever reset PA. In pseudo-C and all values are bytes.

count = 0; overflow = 0; old_pa = PA; do { new_pa = PA; delta = new_pa - old_pa; if (carry) overflow++; count += delta; old_pa = new_pa; } while (waiting for 1 second); // result in count and overflow.

This loop needs to run faster that PA can overflow then if PA is less then the previous time it must have overflowed exactly once. Note that in this scheme the PA is read but never zeroed, so it should never lose a count as long as the polling doesn't lose an overflow. Better still, it doesn't need a interrupt, but i does require polling regularly during the second.

Peter

Reply to
Peter Dickerson

Peter's suggestions are good.

Alternately, have the ISR write the _whole_ count value, including the counter, to memory. When you go to read it turn off interrupts just long enough to copy it into your local variable, then turn on interrupts.

Now do whatever you were going to do with the count. You may have delayed registering a count until the next time your task comes around, but you won't have lost any counts or gotten any grossly wrong numbers.

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

Posting from Google?  See http://cfaj.freeshell.org/google/

"Applied Control Theory for Embedded Systems" came out in April.
See details at http://www.wescottdesign.com/actfes/actfes.html
Reply to
Tim Wescott

Op Mon, 24 Jul 2006 10:27:42 -0700 schreef Tim Wescott:

You can set a flag in the main program and wait until the ISR resets it, after writing the whole count to memory accessible by your program. I've used it this semaphore for another CPU when reading/setting time. When the interrupt timing is not too slow, the wait won't be long.

--
Coos
Reply to
Coos Haak

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.