* Updated version listing and Zipped MB Project files folder download are in forum "User Projects" as of 23/10/2010. Post also contains expanded usage information, please see.
I would like to share some code I've done as an example for managing the PIC18 PORTB interrupts by using MB's "SYMBOL" feature. This helped me manage some complex interrupt handling on a recent project and hope it can help others as well.
Basically, I've assigned an alias to the most common interrupt SFR bit manipulations that one needs to do in order to implement PORTB interrupt routines in your project code.
Two (2) variables are defined also and needed for this code: PORTB_BUFFER [Byte] for holding last state of inputs, and FLAGSB [Byte] for using Bits 4,5,6,7 as Flags for which pin changed with the RBIE Interrupt.
Another 'Temp' Byte variable should be used to read PORTB and hold its current state to compare with the last state PORTB_BUFFER variable on a Bit by Bit basis to determine which pin changed states. Then update PORTB_BUFFER after checks so it holds new pin last states for next interrupt event.
See the example code in the Interrupt sub-procedure I've included for checking which pin changed and updating the PORTB_BUFFER Bits.
The same principle can be used on all of the PIC18's various peripheral Hardware interrupt sources also.
Code: Select all
' PIC 18 GLOBAL AND HI/LO-PRIORITY INTERRUPT MANAGEMENT
'===========================Vulkan_Logik===================================
' Define symbols for Global-Interrupt-Enable/Disable control and State Flag.
' (Or Hi-level Interrupt enable control)
Symbol IRQ_GIE = TestBit(INTCON, GIE_bit) ' Checks GIE State
' Global Mode versions
Symbol GLOBAL_ENABLED = SetBit(INTCON, GIE_bit) ' 1 = enables all
Symbol GLOBAL_DISABLED = ClearBit(INTCON, GIE_bit) ' 0 = Disable all
' Hi-Priority Mode versions
Symbol HI_IRQ_ENABLED = SetBit(INTCON, GIE_bit) ' 1 = enable HI Priority
Symbol HI_IRQ_DISABLED = ClearBit(INTCON, GIE_bit) ' 0 = Disable HI Priority
' PIC PERIPHIAL AND LO-PRIORITY INTERRUPT MANAGEMENT
'===========================Vulkan_Logik===================================
' Define symbols for Interrupt-Enable/Disable Control
' (Or lo-level Interrupt enable control) unmasked Peripheral interrupts
Symbol IRQ_PEIE = TestBit(INTCON, PEIE_bit) ' Checks PEIE State
' Periphial Mode versions
Symbol PERIPH_ENABLED = SetBit(INTCON, PEIE_bit) ' 1 = enables all
Symbol PERIPH_DISABLED = ClearBit(INTCON, PEIE_bit) ' 0 = Disable all
' LO-Priority Mode versions
Symbol LO_IRQ_ENABLED = SetBit(INTCON, PEIE_bit) ' 1 = enables LO Priority
Symbol LO_IRQ_DISABLED = ClearBit(INTCON, PEIE_bit) ' 0 = Disable LO Priority
' PIC INTERRUPT PRIORITY ENABLE Bit (RCON.IPEN) MANAGEMENT
'===========================Vulkan_Logik===================================
' Define symbols for Interrupt priority Enable/Disable Control
Symbol PRIORITY_ENABLED = SetBit(RCON, IPEN_bit) ' Enable Interrupt Priorities
Symbol PRIORITY_DISABLED = ClearBit(RCON, IPEN_bit) ' Disable Interrupt Priorities
Symbol IRQ_PRI = TestBit(RCON, IPEN_bit) ' Check Priority state
' PIC PORT-B INTERNAL PULL-UPS Bit (INTCON2.RBPU) MANAGEMENT
'===========================Vulkan_Logik===================================
Symbol PULLUP_ENABLED = SetBit(INTCON2, RBPU_bit) ' Enables Port-B Pull-Ups
Symbol PULLUP_DISABLED = ClearBit(INTCON2, RBPU_bit) ' Disables Port-B Pull-Ups
Symbol PULLUP_B = TestBit(INTCON2, RBPU_bit) ' Check set state
' PIC PORT-B PINS RB4, RB5, RB6, RB7 IRQ-ON-CHANGE MANAGEMENT
'===========================Vulkan_Logik===================================
' Define symbols for Interrupt-on-change Enable/Disable Control
' RB4:5:6:7
Symbol RBCHG_ENABLED = SetBit(INTCON, RBIE) ' 1 = Enables Interrupts
Symbol RBCHG_DISABLED = ClearBit(INTCON, RBIE) ' 0 = Disables Interrupts
Symbol IRQ_RBCHG = TestBit(INTCON, RBIE_bit) ' RBIE Control State
' Controls for setting RBIE Interrupt Priority
Symbol RBCHG_HIPRI = SetBit(INTCON2, RBIP_bit) ' Port Change IRQ HIGH
Symbol RBCHG_LOPRI = ClearBit(INTCON2, RBIP_bit) ' Port Change IRQ LOW
Symbol RBCHG_Pri = TestBit(INTCON2, RBIP_bit) ' State of Priority
' Define symbol for PORTB pin change FLAG (Must be cleared after read PORTB)
' 1 = one of the 4 pins (RB4:7) has changed state.
Symbol RBCHG_FLAG = TestBit(INTCON, RBIF_bit) ' H/W Flag Register
Symbol Clear_RBCHG = ClearBit(INTCON, RBIF_bit) ' Clears INT BPIN_CHG_FLAG
' Controls for RB4:7 Flags
' Change the INTRB4, INTRB5, INTRB6, INTRB7 in the Symbol names to whatever you need for better clarity.
Symbol Set_INTRB4 = SetBit(FLAGSB, B4) ' sets flag
Symbol IRQ_INTRB4 = TestBit(FLAGSB, B4) ' Flag for IRQ RB4 Pin state change
Symbol Clear_INTRB4 = ClearBit(FLAGSB, B4) ' Clears Flag
Symbol Set_INTRB5 = SetBit(FLAGSB, B5) ' sets Flag
Symbol IRQ_INTRB5 = TestBit(FLAGSB, B5) ' Flag for IRQ RB5 Pin state change
Symbol Clear_INTRB5 = ClearBit(FLAGSB, B5) ' Clears Flag
Symbol Set_INTRB6 = SetBit(FLAGSB, B6) ' sets Flag
Symbol IRQ_INTRB6 = TestBit(FLAGSB, B6) ' Flag for IRQ RB6 Pin state change
Symbol Clear_INTRB6 = ClearBit(FLAGSB, B6) ' Clears Flag
Symbol Set_INTRB7 = SetBit(FLAGSB, B7) ' sets Flag
Symbol IRQ_INTRB7 = TestBit(FLAGSB, B7) ' Flag for IRQ RB7 Pin state change
Symbol Clear_INTRB7 = ClearBit(FLAGSB, B7) ' Clears Flag
' PIC PORT-B EXTERNAL INT0, INT1, INT2 INPUTS MANAGEMENT
'===========================Vulkan_Logik===================================
' Define symbols for controlling Interrupt INT0 -(RB0) functions
' Change the "INT0" in each Symbol name to what ever function your hardware is set to monitor.
Symbol INT0_ENABLED = SetBit(INTCON, INT0IE_bit) ' Enables INT0 interrupts
Symbol INT0_DISABLED = ClearBit(INTCON, INT0IE_bit) ' Disables INT0 interrupts
Symbol IRQ_INT0 = TestBit(INTCON, INT0IE_bit) ' Checks state of INT0
' Define controls to set Active Edge Logic detection IRQ trigger
Symbol INT0_TRIG_HI = SetBit(INTCON2, INTEDG0_bit) ' Set Active HIGH Logic
Symbol INT0_TRIG_LO = ClearBit(INTCON2, INTEDG0_bit) ' Set Active LOW Logic
Symbol INT0_TRIG = TestBit(INTCON2, INTEDG0_bit) ' Checks set state
' Define INT0 Flag management
Symbol INT0_FLAG = TestBit(FLAGSB, B0) ' Checks Flag state
Symbol _INT0_FLAG = TestBit(INTCON, INT0IF_bit) ' H/W FLAG SFR
Symbol Clear_INT0 = ClearBit(INTCON, INT0IF_bit) ' Clears INT0 Flag
Symbol Set_INT0 = SetBit(FLAGSB, B0) ' Sets S/W INT0 Flag
' PIC interrupt management ( RB1: INT1)
'===========================Vulkan_Logik===================================
' Define symbols for RB1-Ext. INT1 IRQ Enable/Disable control.
' Change the "INT1" in each Symbol name to what ever function your hardware is set to monitor.
Symbol INT1_ENABLED = SetBit(INTCON3, INT1IE_bit) ' 1=Enabled
Symbol INT1_DISABLED = ClearBit(INTCON3, INT1IE_bit)' 0=Disabled
Symbol INT1_IRQ = TestBit(INTCON3, INT1IE_bit)
' Define controls to set Active Edge Logic detection IRQ trigger
Symbol INT1_TRIG_HI = SetBit(INTCON2, INTEDG1) ' External Interrupt on low->Hi
Symbol INT1_TRIG_LO = Clearbit(INTCON2, INTEDG1) ' Ext. Int. on Hi -> Lo going
Symbol INT1_TRIG = TestBit(INTCON2, INTEDG1) ' Check state
' Define controls for setting RB1-ext. INT1 IRQ Priority HIGH/LOW
Symbol INT1_HIPRI = SetBit(INTCON3, INT1IP_bit) ' Set to HIGH Priority
Symbol INT1_LOPRI = ClearBit(INTCON3, INT1IP_bit) ' Set to LOW Priority
Symbol INT1_Pri = TestBit(INTCON3, INT1IP_bit) ' Check state
' Define symbol for External-INT1 FLAG. (RB1)
Symbol INT1_FLAG = TestBit(FLAGSB, B1) ' Test for S/W Flag IRQ INT1
Symbol _INT1_FLAG = TestBit(INTCON3, INT1IF_bit) ' H/W Flag Register
' 1 = Interrupt happened, 0 = No Event. (Clear before enabling)
Symbol Clear_INT1 = ClearBit(INTCON3, INT1IF_bit) ' Clears INT _INT1_FLAG
Symbol Set_INT1 = SetBit(FLAGSB, B1)
' PIC INTERRUPT MANAGEMENT ( RB2 )
'===========================Vulkan_Logik===================================
' Define symbols for External INT2 Enable/Disable control.
' Change the "INT2" in each Symbol name to what ever function your hardware is set to monitor.
Symbol INT2_ENABLED = SetBit(INTCON3, INT2IE_bit) ' 1 = Enabled
Symbol INT2_DISABLED = ClearBit(INTCON3, INT2IE_bit) ' 0 = Disabled
Symbol INT2_IRQ = TestBit(INTCON3, INT2IE_bit) ' check state
' Define controls to set Active Edge Logic detection IRQ trigger
Symbol INT2_TRIG_HI = SetBit(INTCON2, INTEDG2)' Ext. INT. trig on Lo - Hi.
Symbol INT2_TRIG_LO = ClearBit(INTCON2, INTEDG2)' Ext. INT. Trig on Hi - Lo
Symbol INT2_Trig = TestBit(INTCON2, INTEDG2) ' State of Active Logic
' Define controls for setting RB2-ext. INT2 IRQ Priority
Symbol INT2_HIPRI = SetBit(INTCON3, INT2IP) ' Set to HIGH IRQ Priority
Symbol INT2_LOPRI = ClearBit(INTCON3, INT2IP) ' Set to LOW IRQ Priority
Symbol INT2_PRI = TestBit(INTCON3, INT2IP) ' check state IRQ Priority
' Define symbol for External-INT2 FLAG. (RB2)
Symbol INT2_FLAG = TestBit(FLAGSB, B2) ' Test for S/W Flag IRQ INT2
Symbol _INT2_FLAG = TestBit(INTCON3, INT2IF_bit) ' H/W Flag Register
' 1 = Interrupt happened, 0 = No Event. (Clear before enabling)
Symbol Clear_INT2 = ClearBit(INTCON3, INT2IF_bit) ' Clears INT _INT2_FLAG
Symbol Set_INT2 = SetBit(FLAGSB, B2) ' Set S/W Flag
dim PORTB_BUFFER as Byte
FLAGSB as Byte
TEMP_BUFFER as Byte
' example interrupt routine: not complete or fully functional as is!!!
sub procedure interrupt()
....
....
....
' test for portB IRQ on Change event: if so, which pins
if ( (RBCHG_FLAG = 1) and (IRQ_RBCHG = 1) ) Then
TEMP_BUFFER = PORTB
if (TEMP_BUFFER.4 <> PORTB_BUFFER.4) Then
Set_INTRB4 ' set IRQ Flag for CS line in state change
PORTB_BUFFER.4 = TEMP_BUFFER.4
end if
if (TEMP_BUFFER.5 <> PORTB_BUFFER.5) Then
Set_INTRB5 ' set IRQ Flag for input DHV1 state change
PORTB_BUFFER.5 = TEMP_BUFFER.5
end if
if (TEMP_BUFFER.6 <> PORTB_BUFFER.6) Then
Set_INTRB6 ' set IRQ Flag for input DHV2 state change
PORTB_BUFFER.6 = TEMP_BUFFER.6
end if
if (TEMP_BUFFER.7 <> PORTB_BUFFER.7) Then
Set_INTRB7 ' set IRQ Flag for input DHV3 state change
PORTB_BUFFER.7 = TEMP_BUFFER.7
end if
Clear_RBCHG ' CLEAR HardWare FLAG RBIF
end if
...
....
...
end sub
Hope this is useful for everyone and if you use it and like/dislike, let me know, MHz. B^)