Принцип работы уже не вспомнить. Идея, если вкратце, в том, что или шаг вперёд можно, или два назад. Шаг -- это от любого фронта, любой из двух (сдвинутых на 90 град.) фаз. Следовательно "учетверение" происходит. Так что потеря шага назад не страшна.
struct s_encoder {
int_least16_t step; /*!< микрошагов на шаг енкодера * 256 */
long pos; /*!< позиция по енкодеру * 256 */
};
/* signal change on ENC_A, encoder number N, s_encoder -- S */
#define ENC_ISR_A(N, S) { \
register uint_least8_t delta, ncode; \
ncode=enc_getcode(N); \
delta=((ncode^enc_code[N]) & 2 /* bit mask */) ? 1 : 0; \
if (/*ENC_A_VAL ^ ENC_B_VAL*/ ncode==2 || ncode==1) { \
S.pos += S.step; \
if (delta) S.pos += S.step; \
} else { \
S.pos -= S.step; \
if (delta) S.pos -= S.step; \
} \
enc_code[N]=ncode; \
enc_wait_b(N); \
}
/* signal change on ENC_B */
#define ENC_ISR_B(N, S) { \
register uint_least8_t delta, ncode; \
ncode=enc_getcode(N); \
delta=((ncode^enc_code[N]) & 1 /* bit mask */) ? 1 : 0; \
if (/*ENC_A_VAL ^ ENC_B_VAL*/ ncode==2 || ncode==1) { \
S.pos -= S.step; \
if (delta) S.pos -= S.step; \
} else { \
S.pos += S.step; \
if (delta) S.pos += S.step; \
} \
enc_code[N]=ncode; \
enc_wait_a(N); \
}
/*! прямое чтение кода энкодера n */
inline uint_least8_t enc_getcode(uint_least8_t n)
{
return (PIND & (_BV(PD2) | _BV(PD3))) >> 2;
}
/*! инициализация портов и прерываний для всех энкодеров,
* прерывания изначально запрещены */
static inline void enc_init_hw(void)
{
DDRD &= ~(_BV(ENC_A) | _BV(ENC_B) | _BV(ENC_IDX));
PORTD |= _BV(ENC_A) | _BV(ENC_B) | _BV(ENC_IDX);
EICRA = _BV(ISC00) | _BV(ISC10);
EIMSK = 0;
}
/*! разрешение прерывания по 0 каналу, для энкодера n */
static inline void enc_wait_a(uint_least8_t n)
{
EIMSK = _BV(INT0);
EIFR = _BV(INTF1) | _BV(INTF0);
}
/*! разрешение прерывания по 1 каналу, для энкодера n */
static inline void enc_wait_b(uint_least8_t n)
{
EIMSK = _BV(INT1);
EIFR = _BV(INTF1) | _BV(INTF0);
}
[ZX]
-
- Учетверение происходит при отсутствии реверса, при реверсе подавление дребезга делает из учетверения удвоение. - Vladimir Ljaschko(21.07.2011 18:24)