Reystlin 0 22 апреля, 2016 Опубликовано 22 апреля, 2016 (изменено) · Жалоба Доброго времени суток ув. форумчане кто как обрабатывает данные снятые с таймера, который включен в режиме обработки энкодера? у меня затык с тем, как определить направление вращения, что-бы прибавлять/вычитать значение к переменной таймер инициализирую вот так: //Encoder TIM3 Init RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_Time_user.TIM_Prescaler = 0; TIM_Time_user.TIM_CounterMode = TIM_CounterMode_Up; TIM_Time_user.TIM_Period = 256; TIM_Time_user.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM3, &TIM_Time_user); TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI1, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); TIM_Cmd(TIM3, ENABLE); TIM3->CNT=0; //Encoder TIM2 Init RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_Time_user.TIM_Prescaler = 0; TIM_Time_user.TIM_CounterMode = TIM_CounterMode_Up; TIM_Time_user.TIM_Period = 256; TIM_Time_user.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM2, &TIM_Time_user); TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI2, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); TIM_Cmd(TIM2, ENABLE); //TIM2->CCMR1 = TIM_CCMR1_CC2S_0 | TIM_CCMR1_CC1S_0; TIM2->CCER |= TIM_CCER_CC1P; TIM3->CCER |= TIM_CCER_CC1P; TIM2->CNT=0; Изменено 22 апреля, 2016 пользователем Reystlin Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
viakon 0 22 апреля, 2016 Опубликовано 22 апреля, 2016 (изменено) · Жалоба Доброго времени суток ув. форумчане кто как обрабатывает данные снятые с таймера, который включен в режиме обработки энкодера? у меня затык с тем, как определить направление вращения, что-бы прибавлять/вычитать значение к переменной таймер инициализирую вот так: Зачем Вам таймер? все делается на прерываниях от ножек. key2buf созраняет результат поворота на 1 деление. void EXTI15_10_IRQHandler(void) { if(EXTI->PR & EXTI_PR_PR14) // прерывание канал А энкодера { EXTI->PR = EXTI_PR_PR14; // сбросить прерывание if(GPIOB->IDR & ENC1) // определение направления импульса { if(GPIOB->IDR & ENC2) { ENCState = 0; } } else { switch(ENCState) { case 0: { if(GPIOB->IDR & ENC2) { ENCState = 1; } break; } case 2: { key2buf(18); ENCState = 0; break; } } } } if(EXTI->PR & EXTI_PR_PR15) { EXTI->PR = EXTI_PR_PR15; // сбросить прерывание if(GPIOB->IDR & ENC2) { if(GPIOB->IDR & ENC1) { ENCState = 0; } } else { switch(ENCState) { case 0: { if(GPIOB->IDR & ENC1) { ENCState = 2; } break; } case 1: { key2buf(17); ENCState = 0; break; } } } } } Изменено 22 апреля, 2016 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 123 22 апреля, 2016 Опубликовано 22 апреля, 2016 (изменено) · Жалоба Зачем Вам таймер? все делается на прерываниях от ножек.Это смотря зачем энкодер нужен. Если на каждый шаг требуется действие - можно и на прерываниях. А если пользователь с помощью энкодера вводит какое-то число на экране и он физически не может реагировать на изменения на экране быстрее, чем за 20-30 мс, а экран физически не может обновляться чаще, то какой смысл грузить процессор прерываниями? Достаточно повесить энкодер на таймер и раз в эти 20 мс считывать накопленный результат. Я не использую библиотеки, поэтому инициализация таймера у меня несколько короче: TIM3->PSC = 0; // TIM3CLK = PCLK/1 TIM3->ARR = 0xFFFF; // 16-bit resolution TIM3->CNT = 0; TIM3->CR1 = 0 | 0 * (TIM_CR1_CKD & -TIM_CR1_CKD) // Dead-time clock = timer clock | 0 * TIM_CR1_ARPE // ARR not buffered | 0 * (TIM_CR1_CMS & -TIM_CR1_CMS) // Unidirectional, not used | 0 * TIM_CR1_DIR // Counting up, not used | 0 * TIM_CR1_OPM // Counter not stopped at update event | 0 * TIM_CR1_URS // Update request source, not used | 1 * TIM_CR1_UDIS // Update event generation, 0 - enabled, 1 - disabled | 1 * TIM_CR1_CEN // Counter enable ; TIM3->SMCR = 0 | 0 * TIM_SMCR_ETP // External trigger polarity, not used | 0 * TIM_SMCR_ECE // External clock mode 2 disabled | 0 * (TIM_SMCR_ETPS & -TIM_SMCR_ETPS) // External trigger prescaler, not used | 0 * (TIM_SMCR_ETF & -TIM_SMCR_ETF) // External trigger filter, not used | 0 * TIM_SMCR_MSM // Master/slave mode, not used | 0 * (TIM_SMCR_TS & -TIM_SMCR_TS) // Trigger selection, not used | 3 * (TIM_SMCR_SMS & -TIM_SMCR_SMS) // Encoder mode, both edges ; TIM3->CCMR1 = 0 // CC2 capture mode settings | 1 * (TIM_CCMR1_IC2F & -TIM_CCMR1_IC2F) // IC2 Filter | 0 * (TIM_CCMR1_IC2PSC & -TIM_CCMR1_IC2PSC) // IC2 Prescaler | 1 * (TIM_CCMR1_CC2S & -TIM_CCMR1_CC2S) // Capture, TI1 // CC1 capture mode settings | 1 * (TIM_CCMR1_IC1F & -TIM_CCMR1_IC1F) // IC1 Filter | 0 * (TIM_CCMR1_IC1PSC & -TIM_CCMR1_IC1PSC) // IC1 Prescaler | 1 * (TIM_CCMR1_CC1S & -TIM_CCMR1_CC1S) // Capture, TI1 ; значение TIM3->CNT достаточно явно привести к int16_t, оно уже будет со знаком. Изменено 22 апреля, 2016 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Reystlin 0 22 апреля, 2016 Опубликовано 22 апреля, 2016 · Жалоба to Сергей Борщ сделал вот так: int16_t leftEnc = (int16_t)TIM3->CNT/2; при кручении в обратную сторону в переменную leftEnc записывается значение 126 вместо -1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Шаманъ 0 22 апреля, 2016 Опубликовано 22 апреля, 2016 · Жалоба to Сергей Борщ сделал вот так: int16_t leftEnc = (int16_t)TIM3->CNT/2; при кручении в обратную сторону в переменную leftEnc записывается значение 126 вместо -1 А сколько там изначально было? Может у Вас CNT у таймера было 127 :) Второй вопрос, а что в ARR? Ибо: Encoder interface mode acts simply as an external clock with direction selection. This means that the counter just counts continuously between 0 and the auto-reload value in the TIMx_ARR register (0 to ARR or ARR down to 0 depending on the direction). So you must configure TIMx_ARR before starting. in the same way, the capture, compare, prescaler... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Reystlin 0 22 апреля, 2016 Опубликовано 22 апреля, 2016 · Жалоба изначально там было 0 ARR =0x00000100 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Шаманъ 0 22 апреля, 2016 Опубликовано 22 апреля, 2016 (изменено) · Жалоба ARR =0x00000100 Ну так, а что Вы хотите при ARR = 256 минус 1 в этом выражении int16_t leftEnc = (int16_t)TIM3->CNT/2; Вы никак не получите. Чтобы оно работало ARR должно быть 0xFFFF; Изменено 22 апреля, 2016 пользователем Шаманъ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Reystlin 0 22 апреля, 2016 Опубликовано 22 апреля, 2016 · Жалоба Помогло, благодарю:) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться