Paul Lamar wrote:Do you have an example of an ISR routine embedded in a program? Say in the middle of a for next loop.
It is important to understand that an ISR is not conceptually "in the middle" of anything. It is essentially like a subroutine that gets called when the event happens that triggers the interrupt. Because it is invoked asynchronously with respect to "normal" subroutines, you cannot pass any parameters to it nor return any values from it except by way of global variables.
The syntax for defining an ISR is described in the ZBasic Reference Manual in the section titled
Defining Interrupt Service Routines. Note that in addition to defining the ISR and writing the code for it you also need to set up the device to respond to the external stimulus. In order to know how to do this you must read and understand the relevant sections of the datasheet for the particular AVR upon which the ZX device is based. A link to the datasheet for the underlying devices can be found on the
Downloads Page. Suffice to say that you will be reading/writing one or more Register.XXX elements to prepare the device to respond to external interrupts.
Given that you are probably interested in recording the elapsed time between active edges of the input signal, you'll probably want to set up a timer to free run at a convenient frequency. When the external interrupt ISR executes, you would then read the timer register and store it in an array or circular buffer. The mainline code could then compute the difference between each "timestamp" reading and the previous one thus giving you the instantaneous period of the input signal (i.e. the inverse of the frequency) from which you could compute instantaneous engine RPM. Of course, the instantaneous values are not as useful as the average value over some period of time so you'll probably want to include some sort of moving average calculation as well.
If you read the description of InputCapture() you'll probably recognize the similarity between what it does and what I described above. Consequently, you may want to look into using the input capture capability of the AVR device. Essentially, when you set up the device for input capture you enable a timer to free run at a convenient frequency. Then, when the active edge of the input capture signal occurs, the value of the timer is transferred to a holding register and an interrupt is generated (if it is enabled). Then, the ISR for the input capture interrupt can read the holding register and do something useful with it. Due to the fact that the transfer of the timer value to the holding register is done in hardware you have zero latency at the time of data capture. The only issue, then is ensuring that you respond to the input capture ISR in a timely fashion.
Although you could actually use InputCapture() to effect an RPM measurement (and I'm pretty sure that others posting here, in fact, do so) your requirements may obviate its direct use.