Мне хочется получить от этого энкодера импульсы и посчитать, но возникла фундаментальная проблема, если подключить только первый канал энкодера - счетчик считает только вверх, если второй канал - только вниз, это означает энкодер не работает, он не должен реагировать на один из каналов, только на оба вместе или никак.
Два канала вместе считают в обоих направлениях, но возникает много ошибок, около 20-30% шагов пропускаются или считают лишнего, фильтры есть программные и физические, информацию вывожу на дисплей ST7796 320x480, перечитал несколько раз Reference manual раздел Advanced-control timers (TIM1 and TIM8), пока больше ничего не читал, мануал крайне сложен для понимания. Использую кубы MX и IDE.
Опыта в программировании у меня нет, совсем, ни в микроконтроллерах, ни в языках Си и прочих, но я почти понимаю что я делаю. Ткните носом почему режим энкодера не работает, перещелкал все возможные настройки, до которых дотянулся мой мозг, моя не понимать где искать.
Основной код прикладываю под спойлер, я смотрю только на него.
код: рабочий цикл while (1)
Спойлер
Код: Выделить всё
HAL_TIM_Encoder_Start(&htim1, TIM_CHANNEL_ALL);
while (1)
{
if (TIM1->SR & TIM_SR_CC1IF) //Если бит первого канала 1
{
PulseDIR1 = TIM1->CNT; //читаем значение
snprintf(DIRi, sizeof(DIRi), "%d", PulseDIR1); //конвертируем PulseDIR1 в массив символов DIRi[16]
str_dot_out(10, 100, DIRi, strlen(DIRi), 0, 0, SystemFont); //выводим на экран
TIM1->SR &= ~TIM_SR_CC1IF; //обнуляем
szDIRi0 = strlen(DIRi); //считаем количество символов
}
if (TIM1->SR & TIM_SR_CC2IF) //Если бит второго канала 1
{
PulseDIR2 = TIM1->CNT;
snprintf(DIRi, sizeof(DIRi), "%d", PulseDIR2);
str_dot_out(10, 100, DIRi, strlen(DIRi), 0, 0, SystemFont);
TIM1->SR &= ~TIM_SR_CC2IF;
szDIRi1 = strlen(DIRi);
}
if (szDIRi1!=szDIRi0) //если количество символов меняется,
{
lcd_fill_rect(10, 99, 70, 114, 0x001F); //...очищаем область, иначе цифры накладываются друг на друга
str_dot_out(10, 100, DIRi, strlen(DIRi), 0, 0, SystemFont);
szDIRi0=0;
szDIRi1=0;
}
}
Спойлер
Код: Выделить всё
htim1.Instance = TIM1;
htim1.Init.Prescaler = 5;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP; // регистр CR1 бит CMS=00 - в какую сторону считает счетчик
htim1.Init.Period = 1000; // регистр ARR
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; // регистр CR1 бит CKD - коэф. деления
htim1.Init.RepetitionCounter = 0; // регистр RCR - указывает сколько раз пропустить обновление регистров (UEV)
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
sConfig.EncoderMode = TIM_ENCODERMODE_TI12; // регистр SMCR бит SMS
sConfig.IC1Polarity = TIM_ICPOLARITY_RISING; // регистр CCER бит CC1P
sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI; // регистр CCMR1 бит CC1S
sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
sConfig.IC1Filter = 0xf;
sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
sConfig.IC2Filter = 0xf;
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
- Вложения
-
- STM32-Timer-Encoder-Mode.jpg
- картинка из Reference manual глава 17.3.16
- (28.42 КБ) 18 скачиваний


