Very Simple Demo of Interupt in SX/B
John Kauffman
Posts: 653
The literature on SX/B and interupts contains many examples, but all that I have seen include multiple features above and beyond the core interupt behavior. I find it useful to start with the most elemental presentation, then build in the extra features.
To that end I tried to write an SX/B program that would flash an LED at 500 mSec. When a switch is closed on a B port that triggers the interupt and flashes the LED five times at 100 mSec.
The MAIN: works fine with the 500 mSec flash. But I'm not getting·any change when I close the switch.·Any suggestions? Thanks.
' =========================================================================
'
'·· File...... DemoInterupt-B-01.SXB
'·· Purpose...
'·· Author....
'·· E-mail....
'·· Started...
'·· Updated... 2006 04Apr 04 - 12:42
'
' =========================================================================
'
' Program Description
'
' Purpose = Demonstrate simplest use of interupts
' normal behvior = LED flashes at 500 mSec
' interupt triggered by switch on RB.0
' during interupt LED flashes 5 times at 100 mSec
'
' Device Settings
'
DEVICE········· SX28, OSC4MHZ, TURBO, STACKX, OPTIONX
FREQ··········· 4_000_000
'
' IO Pins
'
LED··VAR·RC.0
' LED circuit:
'·RC.0 - 470ohm - LEDcath - LEDanode - Vdd
MySwitch VAR RB.0
' Switch circuit used to trigger interupt on B ports
' RB.0 - 470ohm - SwitchSideLower - 10kohm - Vss
'·SwitchSideUpper - Vdd
'
' Constants
'
'
' Variables
'
ISRCounter VAR byte
'
· INTERRUPT
'
ISR_Start:
· ' ISR code here
FOR ISRCounter = 0 to 5
·HIGH RC.0
·Pause 100
·LOW RC.0
·Pause 100
NEXT
ISR_Exit:
· RETURNINT ' {cycles}································
' =========================================================================
· PROGRAM Start
' =========================================================================
Pgm_ID:
· DATA· "DemoInterupts-01", 0
'
' Subroutine Declarations
'
'
' Program Code
'
Start:
· ' initialization code here
TRIS_B=$FF
WKED_B=$FF
WKPND_B=0
Main:
· ' main code here
DO
·HIGH LED
·Pause 500
·LOW LED
·Pause 500
Loop
'
' Subroutine Code
'
·
To that end I tried to write an SX/B program that would flash an LED at 500 mSec. When a switch is closed on a B port that triggers the interupt and flashes the LED five times at 100 mSec.
The MAIN: works fine with the 500 mSec flash. But I'm not getting·any change when I close the switch.·Any suggestions? Thanks.
' =========================================================================
'
'·· File...... DemoInterupt-B-01.SXB
'·· Purpose...
'·· Author....
'·· E-mail....
'·· Started...
'·· Updated... 2006 04Apr 04 - 12:42
'
' =========================================================================
'
' Program Description
'
' Purpose = Demonstrate simplest use of interupts
' normal behvior = LED flashes at 500 mSec
' interupt triggered by switch on RB.0
' during interupt LED flashes 5 times at 100 mSec
'
' Device Settings
'
DEVICE········· SX28, OSC4MHZ, TURBO, STACKX, OPTIONX
FREQ··········· 4_000_000
'
' IO Pins
'
LED··VAR·RC.0
' LED circuit:
'·RC.0 - 470ohm - LEDcath - LEDanode - Vdd
MySwitch VAR RB.0
' Switch circuit used to trigger interupt on B ports
' RB.0 - 470ohm - SwitchSideLower - 10kohm - Vss
'·SwitchSideUpper - Vdd
'
' Constants
'
'
' Variables
'
ISRCounter VAR byte
'
· INTERRUPT
'
ISR_Start:
· ' ISR code here
FOR ISRCounter = 0 to 5
·HIGH RC.0
·Pause 100
·LOW RC.0
·Pause 100
NEXT
ISR_Exit:
· RETURNINT ' {cycles}································
' =========================================================================
· PROGRAM Start
' =========================================================================
Pgm_ID:
· DATA· "DemoInterupts-01", 0
'
' Subroutine Declarations
'
'
' Program Code
'
Start:
· ' initialization code here
TRIS_B=$FF
WKED_B=$FF
WKPND_B=0
Main:
· ' main code here
DO
·HIGH LED
·Pause 500
·LOW LED
·Pause 500
Loop
'
' Subroutine Code
'
·
Comments
You need to setup WKEN_B like: "WKEN_B = %11111110" enable the interrupts for the pin.
Also you must do "WKPND_B = 0" just before RETURNINT to clear the interrupt. Otherwise you will get stuck in the interrupt.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"SX-Video·Module"·available from Parallax for only $28.95 http://www.parallax.com/detail.asp?product_id=30012
"SX-Video OSD module"·available from Parallax for only·$49.95 http://www.parallax.com/detail.asp?product_id=30015
Product web site: www.sxvm.com
Available now! Cheap 4-digit LED display with driver IC·www.hc4led.com
"I reject your reality, and substitute my own." Mythbusters
·
Bean beat me to it, like he said...Change your WKED_B=$FF to WKEN_B=$FE and add WKPND_B=0 just before your "RETURNINT ' {cycles}" line.
You may also want to do a TRIS_C=$FE in your initialization.
Charlie
Post Edited (dy8coke) : 4/4/2006 6:12:47 PM GMT
Could you review the theory behind that, as I have written up below?
SX/B code for a simple interrupt invoked by a Port B external trigger.
n.b.: In this example ignore edge selector (accept default of falling edge)
Four key lines of code (underlined) to use interrupts:
Program START:
Interupt Port must be set as in input, for example for RB.0:
TRIS_B = %11111111·'Alternate = $FF
Interupt Port must be set as able to trigger an interrupt, for example for RB.0:
WKEN_B = %11111110·'Alternate = $FE
Program MAIN:
Interrupt ISR_START:
(must contain a flow-through or jump to ISR_Exit)
Interrupt ISR_EXIT:
WKPND_B = 0
Following line ends execution of interrupt and returns flow to MAIN
RETURNINT································
Execution of code (assuming RB.0 is the external trigger).
1.·On start, execution begins with Program:START
2.·Registers are set: RB.0 as input, RB.0 as able to trigger.
3.·By default, WKPND for RB.0 is set to zero, meaning no need to execute interupt
4.·MAIN: executes
5.·After every step SX checks status of WKPND for RB.0
6.·When RB.0 changes state, SX changes WKPND for RB.0 from 0 (default) to 1
7.·When WKPND for RB.0=1 then ISR_START executes
8.·Somewhere in ISR_START there is a jump to or flow-through to ISR_EXIT
9.·ISR_EXIT must include changing WKPND for RB.0 to 0
10.·ISR_EXIT· ends with a REUTRNINT command
11.·(if WKPND RB.0 was not set to zero, ISR_START would immediately be re-executed and thus you could never get out of re-executing the interrupt.)
A couple things.
You can just use "INPUT MySwitch" instead of messing with the TRIS register.
You should do a "WKPND_B = 0" just before you enable the interrupt with "WKEN_B" otherwise your interrupt may execute as soon as you enable it. (This is caused by jitter on the port pin at startup that looks like an edge).
If you are going to use a switch (or button) the built-in pull-up resistor work great. Then you only need a switch to ground to trigger the interrupt.
If you enable multiple port b interrupts, then you can interrogate WKPND_B to see which one triggered the interrupt. Then you can only reset that bit in WKPND_B and if a different interrupt occurs DURING processing of the first one, the interrupt will immediately run again and you can process the new interrupt. But a new interrupt will NOT interrupt an ongoing interrupt routine.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"SX-Video·Module"·available from Parallax for only $28.95 http://www.parallax.com/detail.asp?product_id=30012
"SX-Video OSD module"·available from Parallax for only·$49.95 http://www.parallax.com/detail.asp?product_id=30015
Product web site: www.sxvm.com
Available now! Cheap 4-digit LED display with driver IC·www.hc4led.com
"I reject your reality, and substitute my own." Mythbusters
·
Some of those I'll use to modify the simplest level and some I'll add in as next steps.