INTERRUPT ... RETURNINT | Examples |
INTERRUPT {NOPRESERVE | NOCODE} {Rate} Instruction(s) ... RETURNINT {Cycles}
Function
INTERRUPT allows the insertion a code block to handle an interrupt
in an SX/B program. The interrupt code block is terminated with
RETURNINT.
Explanation
An interrupt handler allows the SX to perform "background" task, at regular
intervals (using the internal RTCC rollover) or asynchronously (using the
external RTCC input pin, or Port B inputs). The interrupt code must be
located in Page 0 of your program, and before any other code -- this is a
requirement of the SX microcontroller.
SX/B automatically saves internal program variables (__PARAMx) at the start of the ISR and restores them on exit of the ISR. This consumes ISR cycles (14 cycles on entry, 13 cycles on exit) and must be accounted for in time-critical ISR applications. If high-level instructions will not be used in the ISR, the NOPRESERVE option may be specified, eliminating the code that preserves and restores internal SX/B program variables. If the NOPRESERVE option is used, you must make sure that none of the __PARAMx variables are modified by the ISR (i.e., use high-level SX/B instructions). If the NOCODE option is specified then the interrupt routine must set FSR to zero to access variables in location $10 to $1F reliably.
When the interrupt Rate is specified, in calls per second, the SX/B compiler will automatically generate the proper !OPTION register and RETURNINT values in the initialization code. If a rate is specified that is not possible within specified FREQ setting, the Rate parameter will flag an "Invalid Parameter" error.
Periodic Interrupts
The SX chip can be set to cause an interrupt upon rollover of the Real Time
Clock Counter (RTCC). By configuring an interrupt on RTCC rollover, the SX
chip can perform an operation at a predefined time interval in a deterministic
fashion. This can be configured by setting the STACKX or OPTIONX fuse (in
the DEVICE directive, and required by SX/B) and writing to the RTI, RTS and
RTE bits of the Option register (OPTION). The RTCC rollover interrupt is
disabled by default.
To configure the RTCC rollover interrupt:
An interrupt handler that uses the RTCC rollover to create a periodic interrupt might look as follows:
' ------------------------------------------------------------------------- INTERRUPT ' ------------------------------------------------------------------------- ISR_Start: INC tix ' update tix counter IF tix = 200 THEN ' check for 1 second tix = 0 INC secs IF secs = 60 THEN secs = 0 INC mins IF mins = 60 THEN mins = 0 INC hrs IF hrs = MaxHr THEN hrs = 0 ENDIF ENDIF ENDIF ENDIF ISR_Exit: RETURNINT 156
This routine (ISR) maintains a real-time clock. The variable called tix is updated each time through the ISR and when it reaches 200 the seconds counter is updated. This indicates that the ISR is designed to run 200 times per second.
Even when using a 4 MHz oscillator, each instruction takes only 0.25 microseconds. By using the RTCC prescaler we can slow the RTCC timing to a more manageable value and simplify the code. For the timer above, the RTCC prescaler ratio is set to 1:128 via the OPTION register (and clearing OPTION.6 enables the ISR):
OPTION = $86 ' prescaler = 1:128
Note that the Cycles count is set to 156 -- this means that the ISR will run after 156 cycles of the internal RTCC. The final math for the ISR timing works out like this:
4 MHz (FREQ) ÷ 128 (prescaler) ÷ 200 (ISR rate) = 156.25 (Cycles)
Option Register
The OPTION register is a run-time writable register used to configure the
RTCC and the Watchdog Timer. The size of this register is affected by the
OPTIONX device setting.
OPTION | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
RTW | RTI | RTS | RTE | PSA | PS2 | PS1 | PS0 |
When OPTION Extend = 0, bits 7 and 6 are implemented.
When OPTION Extend = 1, bits 7 and 6 read as '1's.
RTW | If = 0, register $01 is W If = 1, register $01 is RTCC | |
RTI | If = 0, RTCC roll-over interrupt is enabled If = 1, RTCC roll-over interrupt is disabled | |
RTS | If = 0, RTCC increments on internal instruction cycle If = 1, RTCC increments on transition of RTCC pin | |
RTE | If = 0, RTCC increments on low-to-high transition If = 1, RTCC increments on high-to-low transition | |
PSA | If = 0, prescaler is assigned to RTCC, divide rate determined by
PS2..PS0 bits If = 1, prescaler is assigned to WDT, and divide rate on RTCC is 1:1 |
Prescaler Division Ratios | |||||||
PS2, PS1, PS0 | RTCC Divide Rate |
Watchdog Timer Divide Rate |
|||||
000 | 1:2 | 1:1 | |||||
001 | 1:4 | 1:2 | |||||
010 | 1:8 | 1:4 | |||||
011 | 1:16 | 1:8 | |||||
100 | 1:32 | 1:16 | |||||
101 | 1:64 | 1:32 | |||||
110 | 1:128 | 1:64 | |||||
111 | 1:256 | 1:128 |
Using the Rate Parameter
With SX/B version 1.5 the programming of interrupts is simplified with the
Rate parameter. When used, the Rate parameter designates the interrupt
frequency in calls per second. For example, to automate the timer code shown above
at a rate of 200 calls per second, the INTERRUPT code could be modified as follows:
' ------------------------------------------------------------------------- INTERRUPT 200 ' ------------------------------------------------------------------------- ISR_Start: INC tix ' update tix counter IF tix = 200 THEN ' check for 1 second tix = 0 INC secs IF secs = 60 THEN secs = 0 INC mins IF mins = 60 THEN mins = 0 INC hrs IF hrs = MaxHr THEN hrs = 0 ENDIF ENDIF ENDIF ENDIF ISR_Exit: RETURNINT
By using this style the programmer does not need to set the OPTION register manually.
Asynchronous Interrupts
Every I/O pin in port B can be set to cause an interrupt upon logic level
transitions (rising edge or falling edge). By configuring interrupts on input
pins, the SX chip can respond to signal changes in a quick and deterministic
fashion. In addition, an interrupt of this sort will wake up the SX chip from
a SLEEP state. This can be configured by writing to the Edge Selection register
(WKED_B) and the Wake-Up Enable register (WKEN_B) and detected by monitoring
the Pending register (WKPND_B) in the interrupt routine. The I/O pins have
interrupts disabled and are set to detect falling edge transitions by
default.
As with edge selection, the Pending register bits will never be cleared by the SX alone; the running program is responsible for doing so. This means if a desired edge is detected, the interrupt will occur and the flag indicating this will remain set until the program clears it. Additional transitions on that pin will not cause interrupts until the associated bit in the Pending register is cleared.
To configure the I/O pins for wake-up (interrupt) edge detection:
Special Notes
Interrupts that are not precisely timed should be avoided -- or at the very least
disabled -- when using time-sensitive instructions such as SERIN, SEROUT,
PULSIN, PULSOUT, etc. If an interrupt with variable timing is triggered
while a time-sensitive instruction is active the instruction is likely to fail, or
return bad results. If, however, the interrupt code is constructed such that is always
runs a given number of cycles, the EffectiveHz parameter of FREQ may be
used to allow time-sensitive SX/B instructions to operate while the interrupt is
enabled.
Related projects: Clock / Timer and Quadrature Encoder Input