Or a much more efficient routine would be (in parallax mnemonics): ChkEncoder mov new,encoder ;move the ra port the new var and new,#00000011 ;clear all but encoder bits mov temp, new xor temp,old ;is old and new same? jz :Return ;if so quit clc ;clear carry rl old ;shift old to align old.0 with new.1 bit xor old,new ;xor bits to determine direction jb old.1,:up ;if bit is 1 then up (CW,etc), if bit is 0 then down (ccw,etc) In a message dated 10/1/99 4:59:48 PM Eastern Daylight Time, morgans.rt@TELIA.COM writes: > Generally, > > Get the two phase bits > > Together with the two bits from the last read form a 4-bit word > > Use this for a 16 entry goto table > > The table will contain 4 each of gotos for count up, count down, no change ( > glitch) and error (both phase changed, probably overspeed). > > An easy way of getting the bits right is to left rotate them into a register, > then mask using andlw 1111b before addwf PCL. Save the register until next > call to this routine. > > Interrupt on change is excellent for getting an interrupt on any change. > > But the routine can also be called anytime as it will handle no change too. > > I did this on a F877 this week, using interrupt on change :) > > It did reach 13kHz+ count and at the same time 4kHz timer 0 int driving some > software timers etc, using 4,096 MHz xtal and 2-level interrupt structure. > (Interrupt get what happened / Interrupt post service with interrupt re- > enabled (soft timers, safety checks, buffers, etc) / Main prog) > > ...wait I'll dump the 2-phase decoder right here... there is some macros, i. > e ifc=if clear then execute next instruction = Mchip btfss. there are also > some debug macros DEBUGsomething, 16-bit count variable is named W_something.. > . > > But I think you will get the idea. > I«ll threw in a few english words... > Enjoy! > > ----8<---- > > ifc INTCON,RBIF ;Har porttillstŒndet > Šndrats? > goto isrP_NoRBIF ;Om inte: hoppa till nŠsta > kollrutin > > ;LŠs in nya tillstŒndet > movf PORTB,w ; *** Ingen annanstans fŒr PORTB > lŠsas dierkt! *** > c INTCON,RBIF ;Kvittera att vi har lŠst > movwf B_PORTBIN ;lagra fšr denna samt andra rutiner > pŒ port B > > ;Bearbeta tvŒfassignal genast! > ;HŠmta fasbitarna frŒn B_PORTBIN till B_2phState 1:0, de fšrra i 3:2... > cc ;Rotate the new bits in... > ifs B_PORTBIN,5 > sc > rlf B_2phState,f > cc > ifs B_PORTBIN,4 > sc > rlf B_2phState,f > movf B_2phState,w > andlw b'1111' > addwf PCL,F ;Before Now don«t care this below > > goto isrBchange_NO ; 0 0 0 0 00 00 > goto isrBchange_UP ; 0 0 0 1 01 10 > goto isrBchange_DN ; 0 0 1 0 10 01 > goto isrBchange_ERR ; 0 0 1 1 11 11 > > goto isrBchange_DN ; 0 1 0 0 01 01 > goto isrBchange_NO ; 0 1 0 1 00 11 > goto isrBchange_ERR ; 0 1 1 0 11 00 > goto isrBchange_UP ; 0 1 1 1 10 10 > > goto isrBchange_UP ; 1 0 0 0 10 10 > goto isrBchange_ERR ; 1 0 0 1 11 00 > goto isrBchange_NO ; 1 0 1 0 00 11 > goto isrBchange_DN ; 1 0 1 1 01 01 > > goto isrBchange_ERR ; 1 1 0 0 11 11 > goto isrBchange_DN ; 1 1 0 1 10 01 > goto isrBchange_UP ; 1 1 1 0 01 10 > ; goto isrBchange_NO ; 1 1 1 1 00 00 > isrBchange_NO > ; DEBUGIND_const 4 ; TEST <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< > < > s F_2phGlitch ;Indikera "glitch" GLITCH? > ;ev godkŠnna glitch? NŠe; lšs ut = prioritera sŠkerhet > isrBchange_ERR > DEBUGIND_const 5 ; TEST <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< > << > s F_2phSpeed ;Indikera "šverfart" OVERSPEED > goto isrP_2phEnd > > isrBchange_UP > INC2 W_2phcnt > ifzc > goto isrP_2phEnd > s F_2phRange ;Indikera "utanfšr skala" > comf W_2phcnt,f ;€ndra 0000h till FFFFh > comf W_2phcnt+1,f > ; DEBUGIND_const 7 ; TEST <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< > < > goto isrP_2phEnd > > isrBchange_DN > FDEC2 W_2phcnt > comf W_2phcnt+1,W ;€r hšgbyten annat Šn FF sŒ Šr det OK > ifzc ;AlltsŒ: Šr ettkomplementet > annat Šn 0? > goto isrP_2phEnd ;I sŒ fall OK! > comf W_2phcnt,W ;Annars kolla lŒgbyten likadant... > ifzc > goto isrP_2phEnd > ;Om wrappade till FFFF: > s F_2phRange ;Indikera "utanfšr skala" > clrf W_2phcnt ;nollstŠll rŠknaren.. > clrf W_2phcnt+1 ; > > ; DEBUGIND_const 6 ; TEST <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< > < > > isrP_2phEnd > > ; DEBUGIND_low4 W_2phcnt ; TEST <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< > < > > isrP_NoRBIF > > DEBUGIND_const 4;Int on change klar