ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Понедельник
8 июля
263138 Топик полностью
fk0, легенда (21.07.2011 18:21, просмотров: 106) ответил silver на Подскажите насчет обработки сигнала от энкодера.
Принцип работы уже не вспомнить. Идея, если вкратце, в том, что или шаг вперёд можно, или два назад. Шаг -- это от любого фронта, любой из двух (сдвинутых на 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]