tried your code on a 500 ppr opto encoder, it seems to be good
modified to run on 16f1825, full quad decode [2000 edges / rev]
Code:#CONFIG __config _CONFIG1, _FOSC_INTOSC & _CP_OFF & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CLKOUTEN_OFF __config _CONFIG2, _PLLEN_ON & _LVP_OFF #ENDCONFIG OSCCON=$70 DEFINE OSC 32 INCLUDE "DT_INTS-14.bas" ; Base Interrupt System INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts ' PIC 16F1825 ; encoder ch A Porta.4 ; encoder ch B Porta.5 enc_new VAR BYTE bank0 enc_old VAR BYTE bank0 enc_counter VAR WORD bank0 Flag var BYTE bank0 TRISA = %111111 ' Make all pins Input trisc = %11111111 ;Make all pins Input ANSELA=0 ANSELC=0 ;SETUP IOC REGS IOCAP = %110000 ;POS EDGE IOCAN = %110000 ;NEG EDGE IOCAF = 0 ;CLR INT FLAG intcon.3 = 1 ;iocie asm INT_LIST macro ; IntSource, Label, Type, Resetflag? INT_Handler IOC_INT, _enc, ASM, NO endm INT_CREATE ; Creates the interrupt processor endasm ;debug -------------------------- TRISA.0 = 0 lata.0=1 pause 2000 ;debug serout2 PORTa.0,84, ["ready v3",13,10 ] ;debug ;debug ------------------------------------ ; Set variable value @ startup Flag = 0 enc_new = 0 enc_old= 0 enc_counter = 0 @ INT_ENABLE IOC_INT Main_Loop: if Flag = 1 then serout2 PORTa.0,84, [#enc_counter,13,10 ] Flag = 0 endif goto Main_Loop end enc: asm ;Read latest input from PORTA & put the value in _enc_new. MOVE?CB 1,_Flag CHK?RP PORTA movf PORTA,W RST?RP movwf _enc_new ;Strip off all but the 2 MSBs in _enc_new. movlw B'00110000' ;Create bit mask (bits 7 & 6). andwf _enc_new,F ;Zero bits 5 thru 0. ;Determine the direction of the Rotary encoder. rlf _enc_old,F ;left shift it into _enc_old to align bit 6 of ;_enc_old with bit 7 of _enc_new. movf _enc_new,W ;Move the contents of _enc_new to W in order to XOR. xorwf _enc_old,F ;XOR previous inputs (in _enc_old) with latest ;inputs (in W) to determine CW or CCW. btfsc _enc_old,5 ;Test bit 5 of result (in _enc_old). Skip next line ;if it is 0 (direction is CCW). goto Up ;Bit is 1 (direction is CW). Go around Down ;and increment counter. Down ;Decrements _enc_counter because the rotary encoder moved CCW. ;Decrements _enc_counter (16 bit value), sets Z on exit. decf _enc_counter,F ; Decrement low byte incfsz _enc_counter,W ; Check for underflow incf _enc_counter+1,F ; Update decf _enc_counter+1,F ; Fixup movf _enc_counter,W iorwf _enc_counter+1,W ; Set Z bit ;Add here code for the CCW LED if needed. goto Continue ;Branch around UP. Up ;Increments _enc_counter because the rotary encoder moved CW. ;Increments _enc_counter (16 bit value), sets Z on exit. incfsz _enc_counter,W ; Add one to low byte decf _enc_counter+1,F ; No carry (negates next step) incf _enc_counter+1,F ; Add one to high byte movwf _enc_counter ; Store updated low byte back. iorwf _enc_counter+1,W ; Set Z flag ;Add here code for the CW LED if needed. Continue ;Assign the latest encoder inputs (in _enc_new) to _enc_old. movf _enc_new,W movwf _enc_old CHK?RP IOCAF CLRF IOCAF INT_RETURN ;============ END OF THE ROTARY ENCODER CODE ===== endasm




Bookmarks