Исходные данные:
МК PWM3A, 11.592MHz внешний кварц.
Имеется два механических энкодера, подключены так:
#define CHA PIND.6 //пин19, кан.А
#define CHB PIND.7 //пин18, кан.Б
#define CHP PIND.5 //пин17, кнопка энкодера 1
#define CHA2 PINC.4 //пин21, канал А энкодера 2
#define CHB2 PINB.2 //пин20, канал Б энкодера 2
#define CHP2 PINC.5 //пин22, кнопка энкодера 2
Порты настроены на вход, тут все в порядке.
Опрос энкодера производится в прерыванию по переполнению таймера0 (1024 делитель)
Задействованы переменные:
unsigned int g_nEncoderCount=0;
unsigned int m_bLastEncoderState=0;
unsigned int bCurrentState;
Для второго энкодера:
unsigned int g_nEncoderCount2=0;
unsigned int m_bLastEncoderState2=0;
signed int bCurrentState2;
Код
bCurrentState = CHA << 1;
if (CHB) bCurrentState |= 1;
////////////// ENCODER1 SW
switch (((m_bLastEncoderState<<2) | bCurrentState) & 0xF) {
// CCW (counter clockwise) rotation cases...
case 0x1: // 00 -> 01
case 0x7: // 01 -> 11
case 0x8: // 10 -> 00
case 0xE: // 11 -> 10
if (g_nEncoderCount != 0) --g_nEncoderCount; break;
// CW (clockwise) rotation cases...
case 0x2: /* 00 -> 10 */
case 0x4: /* 01 -> 00 */
case 0xB: /* 10 -> 11 */
case 0xD: /* 11 -> 01 */
if (g_nEncoderCount != 256) ++g_nEncoderCount; break;
// No change (i.e. new state == old state) cases...
case 0x0: /* 00 -> 00 */
case 0x5: /* 01 -> 01 */
case 0xA: /* 10 -> 10 */
case 0xF: /* 11 -> 11 */
break;
// And illegal (two bits changed) cases...
case 0x3: /* 00 -> 11 */
case 0x6: /* 01 -> 10 */
case 0x9: /* 10 -> 01 */
case 0xC: /* 11 -> 00 */
break;
}
// And now save the current state for next time around..
m_bLastEncoderState = bCurrentState;
bCurrentState2 = CHA2 << 1;
if (CHB2) bCurrentState2 |= 1;
////////////// ENCODER2 SW
switch (((m_bLastEncoderState2<<2) | bCurrentState2) & 0xF) {
// CW (clockwise) rotation cases...
case 0x1: // 00 -> 01
case 0x7: // 01 -> 11
case 0x8: // 10 -> 00
case 0xE: // 11 -> 10
if (g_nEncoderCount2 != 127) ++g_nEncoderCount2; break;
// CCW (counter clockwise) rotation cases...
case 0x2: /* 00 -> 10 */
case 0x4: /* 01 -> 00 */
case 0xB: /* 10 -> 11 */
case 0xD: /* 11 -> 01 */
if (g_nEncoderCount2 != -127) --g_nEncoderCount2; break;
// No change (i.e. new state == old state) cases...
case 0x0: break;/* 00 -> 00 */
case 0x5: break;/* 01 -> 01 */
case 0xA: break;/* 10 -> 10 */
case 0xF: break;/* 11 -> 11 */
break;
// And illegal (two bits changed) cases...
case 0x3: break;/* 00 -> 11 */
case 0x6: break;/* 01 -> 10 */
case 0x9: break;/* 10 -> 01 */
case 0xC: break;/* 11 -> 00 */
break;
}
m_bLastEncoderState2 = bCurrentState2;
Проблема:
первый энкодер обрабатывается нормально, как в сторону увеличения значения g_nEncoderCount, так и уменьшения.
второй же, со счетчиком g_nEncoderCount2 - только в сторону уменьшения.
Если в #define перекинуть местами определения выводов с одного энкодера на другой, то ситуация меняется, g_nEncoderCount2 начинает считаться нормально, первый - только уменьшение, из чего вывод - с платой и разводкой все в порядке, имеет место быть программная ошибка.