ISROnChange
This module generates an on change event if the state of PORTB 4..7 changes. If you don't want a particular pin to fire the event handler, use a call to SetRBMask() to block the trigger. Here is some code to test the module with...
// device and osc... device = 18F452 clock = 20 // import modules... include "ISROnChange.bas" include "Utils.bas" // event handler... event OnChange() toggle(PORTD.0) end event // program start... SetAllDigital SetRBMask($80) // only interested in PORTB.7 on change events ISROnChange.Initialize(OnChange) // initialize the OnChange module, pass OnChange event handler // loop forever... while true wend
Here is the module code itself...
module ISROnChange // set interrupt priority level... #if IsOption(CHANGE_PRIORITY) and not (CHANGE_PRIORITY in (ipLow, ipHigh)) #error CHANGE_PRIORITY, "Invalid option. Priority must be ipHigh or ipLow." #endif #option CHANGE_PRIORITY = ipLow const PriorityLevel = CHANGE_PRIORITY public type TEvent = event() dim FPullupsDisabled as INTCON2.Booleans(7), // RBPU, pullups FOnChangeIF as INTCON.Booleans(0), // RBIF, on port change interrupt flag FOnChangeEnable as INTCON.Booleans(3), // RBIE, enable on change inetrrupts FIPHigh as INTCON2.Booleans(0) // RBIP, interrupt priority dim FOnChangeEvent as TEvent, // address of the OnChange event handler FLastState as byte, // last state of PORTB FRBMask as byte, // the port bits we are interested in FRBChanged as byte // holds the changed state flags public dim RB7 as FRBChanged.Booleans(7), // RB7 has changed RB6 as FRBChanged.Booleans(6), // RB6 has changed RB5 as FRBChanged.Booleans(5), // RB5 has changed RB4 as FRBChanged.Booleans(4) // RB4 has changed { **************************************************************************** * Name : OnChange (PRIVATE) * * Purpose : On port change interrupt handler * **************************************************************************** } interrupt OnChange(PriorityLevel) dim StateOfPort as byte // end mismact condition and clear interrupt flag... WREG = PORTB FOnChangeIF = false // has the state of the port changed - if yes, set // the port changed flags and execute the on change event handler... StateOfPort = PORTB and FRBMask if StateOfPort <> FLastState then FRBChanged = StateOfPort xor FLastState FLastState = StateOfPort FOnChangeEvent() endif end interrupt { **************************************************************************** * Name : SetRBMask * * Purpose : Sets the port pins we want to process. For example * * : %1100 0000 ($C0) is RB7 and RB6 * * : %1001 0000 ($90) is RB7 and RB4 * **************************************************************************** } public sub SetRBMask(pMask as byte) FRBMask = pMask and $F0 end sub { **************************************************************************** * Name : Initialize * * Purpose : Initialize the module * **************************************************************************** } public sub Initialize(pOnChangeEvent as TEvent) FLastState = PORTB and FRBMask // get current state FPullupsDisabled = false // enable PORTB pullups FOnChangeEvent = pOnChangeEvent // assign the event handler #if CHANGE_PRIORITY = ipLow FIPHigh = false #endif FOnChangeEnable = true enable(OnChange) end sub // initialize the module FRBMask = $F0