STM32 Часть 11– Подключаем энкодер
Продолжаем разговор, сегодня очень кратенько о подключении энкодера к микроконтроллеру.
Экодер
Сложнее было купить энкодер, чем написать программу и подключить его. :)
После шуршания по магазинам электронных компонентов, был найден недорогой энкодер “PEC12-4220F-S0024 энкод.инкр.+выкл” по цене 85 рублей.
Полная документация: смотреть.
Подключение
Работать энкодер будет совместно с таймером 2, схему подключения рисовать не вижу смысла, опишу словами: вывод A подключаем к линии ввода-вывода PA0 (эта линия подключена к первому каналу таймера 2), вывод В подключаем к линии ввода-вывода PA1 (эта линия подключена ко второму каналу таймера 2), и последний вывод С подключаем к земле.
Настройка линий:
#define ENCODER_A A, 0, HIGH, INPUT_PULL_UP,
#define ENCODER_B A, 1, HIGH, INPUT_PULL_UP,
PIN_CONFIGURATION(ENCODER_A);
PIN_CONFIGURATION(ENCODER_B);
Настройка таймера 2 для работы с энкодером
Основная задача при настройке таймера “подать” сигналы от энкодера на счетный вход таймера.
Посмотрим на функциональную схему (рассмотрим один из входов):
Входной сигнал (выходной для одной из линий энкодера) проходя через входной фильтр, поступает на детектор фронтов выход которого подключен к последовательной цепочке мультиплексоров, выход последнего поступает на счетный вход таймера.
Полной схемы работы энкодера в документации я не нашел, да она особо и не нужна, всё и так предельно просто.
Рассмотрю самый просто режим работы.
Первым делом разрешаем тактирование таймера 2:
RCC->APB1ENR = RCC_APB1ENR_TIM2EN;
Настройку входного фильтра пропускаю, точнее просто не фильтруем сигнал IC1F=IC2F=0(см. биты ICF регистра CCMR1).
С детектора фронтов возьмем не инверсный, т.е. активный уровень высокий (для первого и второго входа):
TIM2->CCER = TIM_CCER_CC1P | TIM_CCER_CC2P;
Настраиваем второй мультиплексор (для первого и второго входа):
TIM2->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
и последний:
TIM2->SMCR = TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1;
Примечание: приведенный выше режим подразумевает “счет” по каждому из фронтов для двух входных линий, можно так же вести счет либо по первой, либо по второй линии (см. биты SMS регстр SMCR1).
Осталось задать модуль счета, для этого установить регистр автоперезагрузки TIMx_ARR (напомню этот регистр определяет значение при котором счетчик обнуляется):
TIM2->ARR = 100;
Всё, можно разрешать работу счетчика:
TIM2->CR1 = TIM_CR1_CEN;
Инициализация разом:
void mcu_tim2_init(void)
{
RCC->APB1ENR = RCC_APB1ENR_TIM2EN;
TIM2->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
TIM2->CCER = TIM_CCER_CC1P | TIM_CCER_CC2P;
TIM2->SMCR = TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1;
TIM2->ARR = 100;
TIM2->CR1 = TIM_CR1_CEN;
}
Для тестирования вывожу значения счетчика на ЖКИ дисплей:
int main(void)
{
PIN_CONFIGURATION(ENCODER_A);
PIN_CONFIGURATION(ENCODER_B);
lcd_2x16_init();
mcu_tim2_init();
while (1)
{
lcd_2x16_set_position(0, 0);
lcd_2x16_print_hex_xx((uint8_t)(TIM2->CNT >> 8));
lcd_2x16_print_hex_xx((uint8_t)TIM2->CNT);
}
}
Счет происходит согласно алгоритму:
Обращаю внимание в данном режиме один шаг дает 4 тактовых сигнала, т.е. счетчик инкрементируется или декрементируется на 4.
Дальнейшие хитрости настройки за вами.
comments powered by Disqus