in message
bsf PORTB, 7 ; poll switches
movf PORTB, W ; read the whole shebang in
bcf PORTB, 7 ; clear poll bit
movwf CurrentPORTBState
xorwf LastPORTBState, W
movwf PORTBPinsGoneLow ;Contains a bitwise pin change mask right now
andwf LastPORTBState, W
movwf PORTBPinsGoneHigh ;Contains all pins which went high. Bit 7 is not
meaningful.
comf CurrentPORTBState, W
andwf PORTBPinsGoneLow, F ;Contains all pins which went low. Bit 7 is
not meaningful.
movf CurrentPORTBState, W
movwf LastPORTBState
return
The above code can be simplified by 1 instruction and 1 register if it is
assumed that the value of PORTB changes so slowly (human times) while the
code executes almost instantaneously, and it is permissible to have an
inconsistent report from (rare) time to time. The very first time the
routine is called will naturally return unknown data. Your code frag may be
simplified by 2 instructions if bit 7 was always asserted or hardware tied
to Vdd. The hardware may be simplified by using internal PORTB weak pull
ups and throwing away those diodes and resistors (although that natrually
decreases the ESD protection).
Howard Henry Schlunder
hi Howard:
that's a nice tight solution. i see i can eliminate 2 intructions
if i get rid of the check for a change marked ** below which could
cause an endless loop, anyway. maybe i can whittle it down more if
i could understand what you mean about the slow change time. and
that comf insrtruction may help too.
here hx refers to switch history or prior states. interesting how
this works even though status and history are negative logic. i
worked it out with positive logic and the only difference is that
colsure info becomes release info and vice-versa.
this was the second routine i wrote:
; hx = history
_poll_switches ; negative logic. 0 = closed; 1 = open
movf switch_hx, W ; save hx in closures
movwf switch_closures ; hx x chg will = closures
_no_change
bsf PORTB, 0 ; poll switches
movf PORTB, W ; read the whole shebang in
bcf PORTB, 0 ; clear poll bit
movwf switch_hx ; current status will be history
; save current status in releases
movwf switch_releases ; status x chg will = releases
xorwf switch_closures, W ; get hx back. chg info is in W
btfsc STATUS, Z ; **chk 4 chg.
goto _no_change ; **no change
_switch_event
andwf switch_closures, F ; hx x change -> closures
andwf switch_releases, F ; status x change -> release
goto _poll_switches
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
the first routine i wrote. 1 extra instruction. big deal. it's
easier to read and would exit faster if the no change goto were a
return.
_poll_switches ; negative logic. 0 = closed; 1 = open
bsf PORTB, 0 ; poll switches
movf PORTB, W ; read the whole shebang in
bcf PORTB, 0 ; clear poll bit
movwf switch_status ; save current switch status
xorwf switch_history, W ; change info in W
btfsc STATUS, Z ; **chk 4 chg. chg info in W
goto _poll_switches ; no change
_switch_event
movwf switch_releases ; stash chg info in switch_releases register
movwf switch_closures ; stash chg info in switch_closures register
movf switch_status, W
andwf switch_closures, F ; status x change -> closures
movf switch_history, W
andwf switch_releases, F ; history x change -> releases
goto _poll_switches
maybe you or someone can find further improvements.
brs,
mike