Not the best programming techniques but uses interrupts and is fast enough for x4 encoders like ALPS with push switch used to reset the position counter.
Based on Henrik's example and tested on 16F886.
IoannisCode:intcon=%10001000 iocb=7 Encoder VAR BYTE Old_Enc VAR BYTE Test VAR BYTE Dir VAR WORD ' Must be same size as Position variable position var word ch_a var portb.0 ch_b var portb.1 detent var byte flag var bit clear INCLUDE "DT_INTS-14.bas" ' Base Interrupt System INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts wsave var byte $70 system '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _rotary, PBP, yes endm INT_CREATE ENDASM @ INT_ENABLE RBC_INT ; Enable PortB.0 interrupt for signal reception goto main rotary: '------------------------------------------------------------- '--------------Poll encoder and keep count ------------------- '-------------Alternative routine with 4x decoding------------ '------------------------------------------------------------- Encoder.0 = Ch_A Encoder.1 = Ch_B Test = Encoder ^ Old_Enc Dir = 0 If Test = 1 THEN If Old_Enc = 0 THEN Dir = 1 IF Old_Enc = 1 THEN DIR = -1 IF Old_Enc = 2 THEN Dir = -1 If Old_Enc = 3 Then Dir = 1 ENDIF IF Test = 2 THEN IF Old_Enc = 0 THEN DIR = -1 IF Old_Enc = 1 THEN Dir = 1 IF Old_Enc = 2 THEN Dir = 1 IF Old_Enc = 3 THEN Dir = -1 ENDIF if !portb.2 then 'Reset counter position=0 flag=1 endif if Old_Enc <> Encoder then Old_Enc = Encoder detent=detent+1 'Increment position after 4 pulses (one detent on ALPS encoder) if detent = 4 then Position = Position + Dir detent=0 flag=1 endif endif @ INT_RETURN main: while 1 if flag then hserout [#position,13,10] flag=0 endif 'other code stuff here wend END




Bookmarks