Code:
@ __config _HS_OSC & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _FCMEN_OFF & _BOR_OFF
'************************ DEFINES HERE *************************************
DEFINE OSC 20 ' set to 20mhz
INCLUDE "MODEDEFS.BAS"
clear ' clear out variables
DEFINE DEBUG_REG PORTC
DEFINE DEBUG_BIT 6
DEFINE DEBUG_BAUD 19200
DEFINE DEBUG_MODE 0
'********************** PIC16F690 setup ************************************
ADCON0 = 0
ADCON1 = 0
ANSEL = 0
ANSELH = 0
CM1CON0 = 0
CM2CON0 = 0
TrisA = %00000000
TrisB = %11000000
TrisC = %00000000
'*********************** ASSEMBLY INTERUPT VARIABLES ***********************
wsave var byte $20 system
wsave1 var byte $a0 system ' Necessary for devices with RAM in bank1
wsave2 var byte $120 system ' Necessary for devices with RAM in bank2
ssave var byte bank0 system
psave var byte bank0 system
'***************************************************************************
enc_old VAR BYTE
enc_new VAR BYTE
enc_tmp var byte
enc_counter VAR BYTE
enc_counter_old VAR BYTE
enc_scaler var BYTE
Display Var Byte
INTCON = %10001000 ' Enable PortB Change Interupts
IOCB = %11000000
pause 5500 ' wait for LCD to start
goto start 'skip over interupt handler
'*********************** ASSEMBLY INTERUPT HANDLER *************************
define INTHAND myint
Asm
myint
;====== BEGINNING OF THE ROTARY ENCODER CODE ========
;The Rotary Encoder is connected to PORTB
;The A signal of the encoder connected to the PIN portB.7
;The B signal of the encoder connected to the PIN portB.6
;
;The 4 variables used are declared in the PicBasic code.
;
; enc_new VAR BYTE
; enc_old VAR BYTE
; enc_tmp VAR BYTE
; enc_counter VAR WORD
;
;================================================
;Read latest input from PORTB & put the value in enc_new.
movf PORTB,W
movwf _enc_new
;Strip off all but the 2 MSBs in enc_new.
movlw 0xc0 ;Create bit mask (bits 7 & 6). b'11000000' ?
andwf _enc_new,F ;Zero bits 5 thru 0.
;check to see if encoder has moved
movf _enc_old,W ;move enc_old to W
movwf _enc_tmp ;put W to enc_tmp
movf _enc_new,W ;move enc_new to W for XOR
xorwf _enc_tmp,F ;XOR enc_tmp to detect encoder movement
btfsc _enc_tmp,7 ;if bit is clear, encoder moved.
goto Continue ;no movement exit isr
;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.
;bsf _led ;turn on led
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.
;bsf _led2 ; turn on led
Continue
; Assign the latest encoder inputs (in enc_new) to _enc_old.
movf _enc_new,W
movwf _enc_old
; Restore saved registers
movf psave, W
movwf PCLATH
swapf ssave, W
movwf STATUS
swapf wsave, F
swapf wsave, W
bcf INTCON, RABIF ; Clear the Interupt Flag
RETFIE ; Return from interrupt
endasm
'***************************************************************************
'************************* PROGRAM STARTS HERE *****************************
'***************************************************************************
START: ' Main Program starts here
enc_counter = 0 ' set default encoder value
enc_counter_old = 0
' DEBUG 254,2, "ENCODER " ' change display
' DEBUG 254,192,#Display," "
' DEBUG 254,148," " ' clear display
' DEBUG 254,212," "
MAIN: 'see if value has changed
if enc_counter <> enc_counter_old then enc_counter_old = enc_counter
Display = (enc_counter/2)
DEBUG 254,2,"ENCODER " ' change display
DEBUG 254,192,#Display," "
DEBUG 254,148," " ' clear display
DEBUG 254,212," " ' display enc_counter value
sound portC.7,[display,1]
goto MAIN
Got it here, more or less:
Bookmarks