; ;******************************************************************* ; ; Experimental quadrature decoder for 12F508/12F509 ; Input: Quadrature signals on GP0, GP1. "Reverse" control on GP3 ; Output: Low going pulse on on GP5, Direction indicator on GP4 ; ; Connect low going quadrature pair to pins 6 and 7 ; 15uS low going pulse output on pin 2, direction output on pin3 ; connect pin4 to 0V and reboot to reverse direction ; ; V1.0 CMS 29/02/2008 ; ;******************************************************************* ; #include __config (_MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC) ; #define CLKBIT GPIO,5 #define DIRBIT GPIO,4 #define REVBIT GPIO,3 MSKBYT equ 3 ; quadrature input bit mask ; ; reserve some space for variables ; cblock 0x08 ; temp1 temp2 ; endc ; cblock 0x10 ; ; reserve 16 bytes for a state table. do not move or edit ; none1 ;0 ;0000 cw1 ;1 ;0001 ccw1 ;2 ;0010 inv1 ;3 ;0011 ccw2 ;4 ;0100 none2 ;5 ;0101 inv2 ;6 ;0110 cw2 ;7 ;0111 cw3 ;8 ;1000 inv3 ;9 ;1001 none3 ;a ;1010 ccw3 ;b ;1011 inv4 ;c ;1100 ccw4 ;d ;1101 cw4 ;e ;1110 none4 ;f ;1111 ; endc ; org 0 ; osccal value in w on power up movwf OSCCAL ; ; movlw B'10000111' ; no wake on pin change, weak pull-ups on option ; internal timer clock, prescale 256 ; movlw B'00001011' ; bit0, bit1 and bit3 are inputs tris GPIO ; ; clrf GPIO ; all outputs off bsf CLKBIT ; clock pulse active lo ; ; load up the jump-table and curse Harvard ; movlw grab ; start address of grab routine ; movwf 0x10 ; into all "no change" movwf 0x15 ; locations movwf 0x1a ; movwf 0x1f ; ; movlw inv ; start address of inv routine ; movwf 0x13 ; into all "non valid" movwf 0x16 ; locations movwf 0x19 ; movwf 0x1c ; ; movlw cw ; start address of cw routine ; btfsc REVBIT ; normal or reverse output required? movlw ccw ; start address of ccw routine ; movwf 0x11 ; into all "clockwise" locations movwf 0x17 ; movwf 0x18 ; movwf 0x1e ; ; movlw ccw ; start address of ccw routine ; btfsc REVBIT ; normal or reverse output required? movlw cw ; start address of cw routine ; movwf 0x12 ; into all "anticlockwise" locations movwf 0x14 ; movwf 0x1b ; movwf 0x1d ; ; goto grab ; ; ; process input bits ; grab equ $ ; movf temp1,w ; save previous movwf temp2 ; input ; movf GPIO,w ; grab data andlw MSKBYT ; mask movwf temp1 ; save ; bcf STATUS,C ; not necessary but tidier rlf temp2,f ; rotate previous data right twice rlf temp2,w ; ; iorwf temp1,w ; form four-bit transition code ; iorlw 0x10 ; form table offset address ; movwf FSR ; get jump vector movf INDF,w ; ; bsf CLKBIT ; clock signal to inactive (hi) ; movwf PCL ; and go ; cw equ $ ; bcf DIRBIT ; clockwise increment bcf CLKBIT ; clock to active (lo) goto grab ; ; ccw equ $ ; bsf DIRBIT ; anti-clockwise increment bcf CLKBIT ; clock to active (lo) goto grab ; ; inv equ $ ; bcf CLKBIT ; this should never happen so we goto grab ; assume overspeed and no direction swap ; end