Mosaic
Well-Known Member
Here is some code I tested in Proteus (using the motor encoder for the signal)
It is full quadrature with a variable debounce. Uses 3 GPR bytes.
Commented.
It is full quadrature with a variable debounce. Uses 3 GPR bytes.
Commented.
Code:
ScanEncoderPort ;_________ Eg. Bourns PEC11 series_________________________________________________________________________________________________________
; Quadrature (full or detent) rotary encoder signals (A=RA0,B=RA1) , debounced. R_dbcount is an interrupt increment variable, used to tgt a >4ms debounce period.
; If rapidly turning the encoder causes a lack of response, try reducing the debounce time a bit. Use 10 - 47K weak pullups on pulse lines.
; R_Dbstate tracks the valid debounced condition of the encoder bits RA0,1.
; If the encoder bits cannot be placed on the matching portA bits as coded here, read the bits & map them into a RAM byte (bits 0,1) and replace the below PORTA read with the RAM byte read.
; Returns W-register = 0 for no change, .255 for CCW and 1 for CW changes per pulse. Simple to add W-reg to any integer variables afterward.
;______________________________________________________________________________________________________________________________
movf PORTA,w ; replace with the mapped RAM byte as mentioned if required..
andlw d'3' ; filter bit 0,1 for a change.
xorwf LastSample,w ; set changed bits
xorwf LastSample,f ; lastsample=currentsample. Affects zero flag.
andlw d'3' ; w-reg filter bit 0,1 for a change. Refresh zero flag
skpz
clrf R_dbcount ; start the debounce countdown.
btfss R_dbcount,2 ;Debounce period in this example. Depends on particular interrupt speed. (suggest this: >4 ms by choosing an appropriate R_dbcount bit)
retlw 0
;______________________________________________________________________________________________________________________________
; debounce time has passed. Processing validated changes.
;______________________________________________________________________________________________________________________________
movf LastSample,w ; fetch the recent encoder bits sample.
xorwf R_Dbstate,w ; get changes bet. current state and debounced state.
xorwf R_Dbstate,f ; apply them to DB state
andlw d'3' ; w-reg filter bit 0,1 for any change.
skpnz
retlw 0 ; no debounced change.
;______________________________________________________________________________________________________________________________
;Else Test each Encoder bit to determine change direction.
;______________________________________________________________________________________________________________________________
clrc
andlw d'2' ; filter bit 1
skpnz
;---------------------------------------------------------------------------------------------------------------------------------------------------
;********************QUADRATURE MODE CODE: No Detent (full) or Detent mode (1/4)
;---------------------------------------------------------------------------------------------------------------------------------------------------
;goto Testbit0 ; ************* Enable this line for full quadrature, AND ALSO,
;--------comment out this block for full quadrature--------------
retlw 0
movf R_Dbstate,w;
andlw d'2';
skpnz;
retlw 0
;---------------block end -----------------
rlf R_Dbstate,w ; align encoder debounced bits
xorwf R_Dbstate,w ; compare bits
andlw d'2' ; filter bit 1
skpnz
retlw 1 ; 1=> 1 clockwise pulse
retlw d'255' ; 255=> 1 anticlockwise pulse.
Testbit0
rrf R_Dbstate,w ; align encoder debounced bits
xorwf R_Dbstate,w ; compare bits
andlw d'1' ; filter bit 0
skpz
retlw 1 ; 1=> 1 clockwise pulse
retlw d'255' ; 255=> 1 anticlockwise pulse.
;______________________________________________________________________________________________________________________________
Last edited: