plus I would rearrange the code like this , the way you have it the interrupt is enabled before its created
which may not be a good thing
Code:INCLUDE "DT_INTS-14.bas" ; Base Interrupt System INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts ' PIC 16F628A ' PicBasic program to demonstrate operation of an LCD in 4-bit mode ' and reading an optical encoder in quadrature ' ' LCD should be connected as follows: ' LCD PIC ' DB4 PortA.0 ' DB5 PortA.1 ' DB6 PortA.2 ' DB7 PortA.3 ' RS PortA.4 (add 4.7K pullup resistor to 5 volts) ' E PortB.0 ' RW Ground ' Vdd 5 volts ' Vss Ground ' Vo 20K potentiometer (or ground) ' DB0-3 No connect ; encoder ch A PortB.6 ; encoder ch B PortB.7 Define LCD_DREG PORTA Define LCD_DBIT 0 Define LCD_RSREG PORTA define LCD_RSBIT 4 define LCD_EREG PORTB define LCD_EBIT 0 define LCD_BITS 4 define LCD_LINES 2 define LCD_COMMANDUS 2000 define LCD_DATAUS 50 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 Lcdout $fe, 1 ' Clear LCD screen Lcdout "Encoder test" ' Display message Pause 500 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 Flag = 0 enc_new = 0 enc_old= 0 enc_counter = 0 @ INT_ENABLE RBC_INT ; enable external (INT) interrupts Main_Loop: if Flag = 1 then Lcdout $fe, 1 Lcdout Dec enc_counter ; display counter value on LCD Flag = 0 endif goto Main_Loop end 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. 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,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