ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Воскресенье
7 июля
213098 Топик полностью
fk0, легенда (28.09.2010 18:22, просмотров: 200) ответил fk0 на Да и с твоим триггером только импульсы тупо считаются, а фаза не учитывается. В итоге если на диске 2400 рисок, то можно иметь 9600 позиций на оборот, а у тебя 2400 и останется.
Показываю пример говнокода  #include <avr/interrupt.h> #include <avr/io.h> #include <avr/sfr_defs.h> #include "encoder.h" struct s_encoder { int_least16_t step; /*!< шагов на шаг енкодера * 256 */ long pos; /*!< позиция по енкодеру * 256 */ }; struct s_encoder enc_s; static uint8_t enc_code; /* last read value */ /*! прямое чтение кода энкодера n */ uint_least8_t enc_getcode(void) { 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 каналу */ static inline void enc_wait_a(void) { EIMSK = _BV(INT0); EIFR = _BV(INTF1) | _BV(INTF0); } /*! ожидание прерывания по 1 каналу */ static inline void enc_wait_b(void) { EIMSK = _BV(INT1); EIFR = _BV(INTF1) | _BV(INTF0); } /* NOTE: в один момент времени разрешено только одни прерывание. */ ISR(INT0_vect) { register uint_least8_t delta, ncode; ncode=enc_getcode(); delta=((ncode^enc_code) & 2 ) ? 1 : 0; if ( ncode==2 || ncode==1) { enc_s.pos += enc_s.step; if (delta) enc_s.pos += enc_s.step; } else { enc_s.pos -= enc_s.step; if (delta) enc_s.pos -= enc_s.step; } enc_code=ncode; enc_wait_b(); } ISR(INT1_vect) { register uint_least8_t delta, ncode; ncode=enc_getcode(); delta=((ncode^enc_code) & 1 ) ? 1 : 0; if ( ncode==2 || ncode==1) { enc_s.pos -= enc_s.step; if (delta) enc_s.pos -= enc_s.step; } else { enc_s.pos += enc_s.step; if (delta) enc_s.pos += enc_s.step; } enc_code=ncode; enc_wait_a(); } /*! требуется однократный вызов после подачи питания */ void enc_init(void) { enc_init_hw(); enc_code = enc_getcode(); enc_s.pos = 0; enc_wait_a(); } }
[ZX]