Есть еще неплохой алгоритм по прерываниям с портов: signed char states[] = {0,-1,1,0, 1,0,0,-1, -1,0,0,1, 0,1,-1,0};//Encoder directions
ENC_AB = (ENC_A >> 1) | (ENC_B >> 2);
POSITION += states[((ENC_AB_LAST<<2) | ENC_AB)];
ENC_AB_LAST = ENC_AB;
но уменьшает разрешение в 2 раза.