ISROnChange

SwordfishUser.ISROnChange History

Show minor edits - Show changes to output

Added lines 1-111:
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...

=code [=
// 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...

=code [=
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
=]