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