Выделил специально из "хитросплетений" обработчик прерываний по любому фронту от сигналов с валкодера (при работе по опросу ничего не меняется).
Код:
// dimensions are:
// old_bits new_bits
static const int_fast8_t graydecoder [4][4] =
{
{
+0, /* 00 -> 00 stopped */
-1, /* 00 -> 01 rotate left */
+1, /* 00 -> 10 rotate right */
+0, /* 00 -> 11 invalid combination */
},
{
+1, /* 01 -> 00 rotate right */
+0, /* 01 -> 01 stopped */
+0, /* 01 -> 10 invalid combination */
-1, /* 01 -> 11 rotate left */
},
{
-1, /* 10 -> 00 rotate left */
+0, /* 10 -> 01 invalid combination */
+0, /* 10 -> 10 stopped */
+1, /* 10 -> 11 rotate right */
},
{
+0, /* 11 -> 00 invalid combination */
+1, /* 11 -> 01 rotate right */
-1, /* 11 -> 10 rotate left */
+0, /* 11 -> 11 stopped */
},
};
static uint_fast8_t old_val;
void spool_encinterrupt(void)
{
const uint_fast8_t new_val = hardware_get_encoder_bits(); /* Состояние фазы A - в бите с весом 2, фазы B - в бите с весом 1 */
position1 += graydecoder [old_val][new_val];
old_val = new_val;
}
То есть, то же самое что и в виде case у Вас. Начальное состояние old_val должно соотвтствовать тому что в валкодере сейчас (чтобы при включении ложных шагов не возникало). Вам надо аналогично с EncState поступить - при инициализации прочитать в него состояние валкодера.
ps: Александр далее тоже неплохой вариант предложил - для всех 16 комбинаций старого и нового состояний есть четыре приращения и четыре уменьшения - можно и в виде единственного switch с восемью case написать.