For optical encoder I use this:
Code:; PIC18F4520 DEFINE OSC 4 INCLUDE "DT_INTS-14.bas" ; Base Interrupt System INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts TRISA = %00000000 ' Make all PortA pins output TRISB = %11001000 Define LCD_DREG PORTA Define LCD_DBIT 0 Define LCD_RSREG PORTA define LCD_RSBIT 4 define LCD_EREG PORTA define LCD_EBIT 6 define LCD_BITS 4 define LCD_LINES 2 define LCD_COMMANDUS 2000 define LCD_DATAUS 50 ; encoder ch A PortB.6 ; encoder ch B PortB.7 wsave VAR BYTE $70 SYSTEM ; alternate save location for W enc_new VAR BYTE bank0 enc_old VAR BYTE bank0 enc_counter VAR word bank0 Flag var BYTE bank0 asm INT_LIST macro ; IntSource, Label, Type, Resetflag? INT_Handler RBC_INT, _enc, ASM, yes endm INT_CREATE ; Creates the interrupt processor endasm ; Set variable value @ startup enc_new = 0 enc_old= 0 enc_counter = 0 Flag = 0 @ INT_ENABLE RBC_INT ; enable external (INT) interrupts Main_Loop: Lcdout $fe, 1 lcdout Dec enc_counter goto Main_Loop enc: asm ;Read latest input from PORTB & put the value in _enc_new. MOVE?CB 1,_Flag movf PORTB,W movwf _enc_new ;Strip off all but the 2 MSBs in _enc_new. movlw B'11000000' ;Create bit mask (bits 7 & 6). andwf _enc_new,F ;Zero bits 5 thru 0. ;Determine the direction of the Rotary encoder. rlcf _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,7 ;Test bit 7 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 INT_RETURN ;============ END OF THE ROTARY ENCODER CODE ===== endasm




Bookmarks