I need to monitor five pins simultaniosly for counting purposes. I would like to use interrupts. I'm using a 16F876A which has five pins on PORTB which can be used as interrrupts. I'm not sure how to implement this. Any help on the synyax would be appreciated
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Here's one possible way of writing it - depends a lot on your application though.
'Chip settings
#chip 16F876A, 4
#config OSC = XT, PWRT = ON, WDT = OFF
' Setup interrupt service routines
PortB_Last = 0xF0
CounterFlags = 0
on interrupt ExtInt0 call ISRPin0
on interrupt PORTBChange call ISRPin4_7
#define CountChangeFlag CounterFlags.0
#define ClearCountFlag set CounterFlags.0 off
#define SetCountFlag set CounterFlags.0 on
#define CountersChanged CounterFlags.0 on
' Uncomment the next line if you want to enable weak pullups on PortB
'set not_rbpu off
' Counters from 0 to 255 then rollover back to 0
Count0 = 0
Count4 = 0
Count5 = 0
Count6 = 0
Count7 = 0
' You're main loop code
do
if CountersChanged then
ClearCountFlag
'do something with the counts
end if
' Do other stuff
loop
' Interrupt service routine for External Int0
sub ISRPin0
Count0 ++ ' Increase Count0 by 1 on every rising edge of INT0
SetCountFlag
end sub
' Interrupt service routine for PORTB Interrupt on Change
' Don't read Port B or use Read/Modify/Write instructions on PortB anywhere else
' in the program
sub ISRPin4_7
PortB_Now = PORTB & 0xF0 ' Read PortB and mask off unwanted bits
PortB_Last = (!PortB_Last) & PortB_Now ' Bit change from 0 to 1 will produce a 1 output
if PortB_Last <> 0 then SetCountFlag ' Any 1's indicate a rising edge so flag it
if PortB_Last.4 on then Count4 ++ ' Test for rising edges between current and last -
if PortB_Last.5 on then Count5 ++ ' PORTB reads and increment counters that need it
if PortB_Last.6 on then Count6 ++
if PortB_Last.7 on then Count7 ++
PortB_Last = PortB_Now ' Save Port B pins for next change
end sub
The five counters are incremented on every rising edge of the respective pin.
I've set a flag in the interrupt service routines to indicate to the main loop when the count has changed - you may not need that or you might want a flag for each counter. You could in that case have the counters incremented in your main loop and just set flags in the interrupts.
You might also want to increase the size of the counters to words by using -
dim Count0 as word
Hope that gives you some ideas to work with.
Frank
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This gives me a lot to work with. Though I might have a problem in using the interrupts in my real world setting.
I'm monitoring a window with several laser emitters and detectors wired in series to count items as they pass through the window. I'm finding the irregular shapes of the items are causing multiple input signals which are in turn giving me two, sometimes three signals on one item going through the window.
I might have to abandon the interrrupt idea in order to smooth out the false signals by delaying the reading of the inputs somehow.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I need to monitor five pins simultaniosly for counting purposes. I would like to use interrupts. I'm using a 16F876A which has five pins on PORTB which can be used as interrrupts. I'm not sure how to implement this. Any help on the synyax would be appreciated
Here's one possible way of writing it - depends a lot on your application though.
'Chip settings
#chip 16F876A, 4
#config OSC = XT, PWRT = ON, WDT = OFF
' Setup interrupt service routines
PortB_Last = 0xF0
CounterFlags = 0
on interrupt ExtInt0 call ISRPin0
on interrupt PORTBChange call ISRPin4_7
#define CountChangeFlag CounterFlags.0
#define ClearCountFlag set CounterFlags.0 off
#define SetCountFlag set CounterFlags.0 on
#define CountersChanged CounterFlags.0 on
' Uncomment the next line if you want to enable weak pullups on PortB
'set not_rbpu off
' Counters from 0 to 255 then rollover back to 0
Count0 = 0
Count4 = 0
Count5 = 0
Count6 = 0
Count7 = 0
' You're main loop code
do
if CountersChanged then
ClearCountFlag
'do something with the counts
end if
' Do other stuff
loop
' Interrupt service routine for External Int0
sub ISRPin0
Count0 ++ ' Increase Count0 by 1 on every rising edge of INT0
SetCountFlag
end sub
' Interrupt service routine for PORTB Interrupt on Change
' Don't read Port B or use Read/Modify/Write instructions on PortB anywhere else
' in the program
sub ISRPin4_7
PortB_Now = PORTB & 0xF0 ' Read PortB and mask off unwanted bits
PortB_Last = (!PortB_Last) & PortB_Now ' Bit change from 0 to 1 will produce a 1 output
if PortB_Last <> 0 then SetCountFlag ' Any 1's indicate a rising edge so flag it
if PortB_Last.4 on then Count4 ++ ' Test for rising edges between current and last -
if PortB_Last.5 on then Count5 ++ ' PORTB reads and increment counters that need it
if PortB_Last.6 on then Count6 ++
if PortB_Last.7 on then Count7 ++
PortB_Last = PortB_Now ' Save Port B pins for next change
end sub
The five counters are incremented on every rising edge of the respective pin.
I've set a flag in the interrupt service routines to indicate to the main loop when the count has changed - you may not need that or you might want a flag for each counter. You could in that case have the counters incremented in your main loop and just set flags in the interrupts.
You might also want to increase the size of the counters to words by using -
dim Count0 as word
Hope that gives you some ideas to work with.
Frank
Thnaks,
This gives me a lot to work with. Though I might have a problem in using the interrupts in my real world setting.
I'm monitoring a window with several laser emitters and detectors wired in series to count items as they pass through the window. I'm finding the irregular shapes of the items are causing multiple input signals which are in turn giving me two, sometimes three signals on one item going through the window.
I might have to abandon the interrrupt idea in order to smooth out the false signals by delaying the reading of the inputs somehow.