Подключаем энкодер с помощью таймера
Описание процесса работы с энкодером с помощью таймера в режиме захвата для микроконтроллеров STM32

На этот раз рассмотрим подключение к микроконтроллеру STM32F205
(на остальных аналогично) энкодер.
Есть несколько вариантов считывания информации с энкодера. Но так как микроконтроллер у нас имеет таймеры работающие в режиме захвата и способные обрабатывать сигналы с энкодера, будем пользоваться именно ими.
Подключение выполним к выводам 6 и 7 порта A (это входы/выходы таймера TIM3
) вот по схеме на рисунке выше.
В принципе тут всё понятно, А и В подключаются к ногам 6 и 7, а Общий провод - к земле. В моём случае есть ещё кнопка, но она нам не нужна.
Первое что нам нужно сделать, это инициализировать выводы микроконтроллера, которые участвуют в нашем мануале (если конечно можно так сказать). Инициализировать будем с помощью библиотек SPL
.
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
//--------- Включаем клоки ---------------------------------
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
// ------- Энкодер -------
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_TIM3);
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
Далее приступаем к инициализации таймера. Тут всё максимально просто.
void TIM_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE );
// ----------------- Таймер для Энкодера -----------------
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 1000; // это то значение до которого будет считать таймер
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* Считать будем все переходы лог. уровня с обоих каналов */
TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_BothEdge, TIM_ICPolarity_BothEdge);
// -----------------
TIM_Cmd(TIM3, ENABLE); // Энкодер
}
Сразу оговорюсь, данный способ имеет свои недостатки, то есть, как только таймер досчитает до максимума, то начнет считать с начала (с нуля), в обратную сторону аналогично. Если такое поведение критично можно обработать прерывание по обновлению счетного регистра таймера, даю намёк - TIM_IT_Update
.
Считанные данные хранятся в регистре CNT
таймера TIM3
. получить их можно так
TIM3->CNT
или с помощью SPL функции
uint32_t TIM_GetCounter(TIM_TypeDef* TIMx);
В принципе и всё. Как видите, всё довольно просто, но если что-то не получается, попробуйте более внимательно прочитать даташит.