Вот слегка переработанный код
#define HALLS_CHANNELS_QTY 2
#define HALL_DU3 0
#define HALL_DU4 1
#define START_HALL_POSITION 4000
typedef struct
{ unsigned char cspeed;
unsigned int period;
unsigned int timer;
unsigned char error;
unsigned char change;
} ext_hall_type;
typedef struct
{ int position;
unsigned char cur; //current_inputs;
unsigned char prev; //previous_inputs
unsigned char prev_prev; //before previous inputs
unsigned char init;
} hall_type;
enum { State0, StateA, StateB, StateAB }; //состояния энкодера
enum { HallBitA, HallBitB };
enum { NO_HALL_ERROR, HALL_ERROR_SIGNAL, HALL_ERROR_UP, HALL_ERROR_DOWN, HALL_BIG_DIFFERENCE };
ext_hall_type e_hall[HALLS_CHANNELS_QTY]; // not for eeprom
__no_init hall_type hall[HALLS_CHANNELS_QTY]; // for eeprom
hall_type old_hall[HALLS_CHANNELS_QTY];
void InitHalls(void )
{ hall[HALL_DU3].prev=hall[HALL_DU3].cur;
hall[HALL_DU3].prev_prev=hall[HALL_DU3].cur;
hall[HALL_DU4].prev=hall[HALL_DU3].cur;
hall[HALL_DU4].prev_prev=hall[HALL_DU4].cur;
hall[HALL_DU3].init=YES;
hall[HALL_DU3].position=START_HALL_POSITION;
hall[HALL_DU4].init=YES;
hall[HALL_DU4].position=START_HALL_POSITION;
e_hall[HALL_DU3].error=NO;
e_hall[HALL_DU4].error=NO;
}
//#define BACKWARD
<c>#define PLUS 1
#define MINUS 2
#define ERROR 4
/*
const char hall_table[4][4] = // cur, prev
{//prev 0 a b ab cur:
{ 0 , MINUS , PLUS , ERROR }, // 0
{ PLUS , 0 , ERROR , MINUS }, // A
{ MINUS , ERROR , 0 , PLUS }, // B
{ ERROR , PLUS , MINUS , 0 } }; // AB
*/
const char hall_table[4][4] = // cur, prev
{//prev 0 a b ab cur:
{ 0 , PLUS , MINUS , ERROR }, // 0
{ MINUS , 0 , ERROR , PLUS }, // A
{ PLUS , ERROR , 0 ,MINUS }, // B
{ ERROR , MINUS , PLUS , 0 } }; // AB
#pragma inline=forced
static void HallService(char ch)
{
char prev=hall[ch].prev;
char prev_prev=hall[ch].prev_prev;
char cur;
char change=0;
if (ch==HALL_DU3)
cur=GET_HALL_DU3();
else
cur=GET_HALL_DU4();
if (cur != prev_prev)
change=hall_table[cur][prev];
if (change & ERROR)
e_hall[ch].error=HALL_ERROR_SIGNAL;
if (change &PLUS)
{ hall[ch].position++;
/* if (mo[ch+2]->last_power<-moMAX_POWER/2)
e_hall[ch].error=HALL_ERROR_DOWN;
*/
}
if (change & MINUS)
{ hall[ch].position--;
/*
if (mo[ch+2]->last_power>moMAX_POWER/2)
e_hall[ch].error=HALL_ERROR_UP;
*/
}
if (change&(PLUS|MINUS))
{ e_hall[ch].period=e_hall[ch].timer;
e_hall[ch].timer=0;
}
else
{ if (e_hall[ch].timer<50000)
e_hall[ch].timer++;
if (e_hall[ch].timer>e_hall[ch].period)
e_hall[ch].period=e_hall[ch].timer;
}
hall[ch].prev_prev = prev;
hall[ch].prev = cur;
hall[ch].cur = cur;
if (change)
e_hall[ch].change=change;
}