Таймеры TIM2-TIM5 умеют аппаратно работать с поворотным энкодером. То есть вращение энкодера будет вызывать изменение регистра-счётчика (который TIMx->CNT). На самой плате энкодера нема, потому нужен свой. Если нема своего, то можно вовсе не смотреть.
читать дальшеНапример, возьмём любой таймер, хотя бы и тот же TIM4. У него выводы PB6 (канал 1) и PB7 (канал 2) выведены на штыри. Энкодер имеет четыре вывода, два из которых отвечают за питание, а два - за полезный сигнал. Называются они A и B. Они симметричны, в общем-то, даже если перепутать их местами, изменится лишь направление вращения (воспринимаемое таймером). Но, следуя алфавиту, подключим сигнал A к первому каналу (PB6), а B ко второму (PB7).
Напомню, альтернативная функция таймера TIM4 для выводов: 2.
Теперь, имея подключённый энкодер, можно и код писать. Таймер включается обычным образом.
Специфика для энкодера:
1. Выбор режима энкодера осуществляется флагами SMS в регистре TIMx_SMCR:
0b001 — счёт только по фронтам на втором канале (состояние другого определяет направление);
0b010 — счёт только по фронтам на первом канале (состояние другого определяет направление);
0b011 — счёт по фронтам на обоих каналах;
2. Полярность фронтов (и направление счёта при вращении) определяются флагами CC1P/CC2P в регистре TIMx_CCER. При изменении любого в противоположное состояние — направление меняется.
3. Предел счёта всё так же определяется регистром TIMx_ARR, потому надо бы не забыть его настроить. По превышении его, счёт начнётся с нуля (с возникновением соответствующих событий и прерываний). В обратную сторону аналогично.
4. Далее настраивается режим захвата: в регистре TIMx_CCMR1 есть два поля: CC1S и CC2S, которые определяют режим работы канала (вход/выход), и если вход, то откуда. Чтобы он брал сигнал с соответствующей ножки, надо в каждое поле единицу (CC1 channel is configured as input, IC1 is mapped on TI1). Там же можно настроить цифровую фильтрцию входного сигнала.
5. И последний штрих: включение первого и второго каналов захвата флагами CC1E и CC2E в регистре TIMx_CCER.
Из интересного: в регистре TIM_CR1 есть флаг DIR, который автоматически показывает направление счёта последнего.
После такой настройки можно запустить выполнение и в режиме отладки, в View->System Viewer->TIM->TIM4 поглядеть, как содержимое регистра TIM4_CNT меняется. Оно всегда будет привязано к текущему положению счётчика.
Если интересует перемещение, на сколько повернули ручку между вызовами, то можно сделать функцию, которая будет помнить состояние переменной на момент последнего вызова и смотреть разницу:
Этому коду всё равно, было переполнение регистра-счётчика или же не было его, разница будет верной. Правда, такое будет только если TIMx_ARR = 0xFFFF. В ином случае придётся учитывать программно, что переход через ноль идёт в другое крайнее значение.
Да и вообще, программный интерфейс энкодера можно сделать интересным, с фильтрацией, масштабированием перемещения согласно скорости вращения, генерацией событий и так далее.
Прилагаемый проект работает следующим образом: 100 раз в секунду код смотрит, был ли повёрнут энкодер. Если счётчик увеличился, зажигается левый светодиод, если уменьшился — правый. Если положение счётчика больше нуля ((int16_t)TIM4_CNT > 0), то светится верхний светодиод.
Для управления светодиодами, и для системного таймера код я взял из предыдущих проектов, для краткости логики:
Файлы:
encoder.c
Проект.<< Предыдущее Следующее >>
@темы:
arm,
программизмы,
электроника,
stm32f4discovery,
stm32