Forums

HC11 interrupt handling query

Started by bruce varley July 24, 2006
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.?).




bruce varley wrote:
> 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.
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.
"bruce varley" <bxvarley@weqstnet.com.au> wrote in message
news:44c4a582@quokka.wn.com.au...
> 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 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 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.?).
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
bruce varley wrote:

> 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.?). >
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
Op Mon, 24 Jul 2006 10:27:42 -0700 schreef Tim Wescott:

<snip>
> 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.
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