Как подключить энкодер к STM32.

Как подключить энкодер к STM32.

В одной из прошлых статей про энкодер описывался принцип его работы и способы обработки данных приходящих с него. Описанные способы можно реализовать на простых микроконтроллерах типа Atmega, у более продвинутых, типа STM32, для работы с энкодером предназначен специальный интерфейс, который сам обрабатывает данные, приходящие с энкодера и на основе этих данных увеличивает или уменьшает значение счётного регистра, в зависимости от того в какую сторону было вращение.
Как подключить энкодер к STM32.

Как подключить энкодер к STM32.

Этот интерфейс реализуется с помощью двух каналов(TI1 и TI2) выбранного таймера, у stm32f103vet6 получилось запустить его(энкодер) на третьем и восьмом таймере, также была попытка запустить его на первом таймере, но она не увенчалась успехом. Почитав интернет, выяснил, что есть люди которые то же сталкивались с таким же вопросом, то есть им удавалось запустить энкодер на одном таймере и не удавалось на другом, хотя таймеры были идентичные, как например в моём случае, первый и восьмой таймер.

Сигналы с входов проходят через цифровой фильтр, затем поступают в детектор фронтов. Входной цифровой фильтр нужен для устранения дребезга контактов и по сути представляет собой, декрементирующий(считающий вниз) счётчик, физически дребезг, конечно, не пропадает, но за счёт применения "специального" алгоритма система его не “чувствует”. Детектор фронтов, в зависимости от того возрастающий или спадающий сигнал, устанавливает 1 на соответствующем выводе, TI1F_Rising – возрастающий и TI1F_Falling – спадающий. Далее, сигналы попадают в мультиплексор, определяющий по какому фронту производится захват, а затем в мультиплексор выбора входа.
Как подключить энкодер к STM32.

Выше изображена картинка, отражающая алгоритм работы цифрового фильтра, предположим, что нам известно что сигнал нестабилен в течение 5 выборок, тогда после перехода в новое состояние, в течение 8 выборок(возьмём с запасом), микроконтроллер не должен реагировать на изменение состояния входа. Если через 8 выборок состояние сигнала подтверждается, он передаётся на выход TI1F. С логикой работы разобрались, давайте перейдём к настройке.

Для настройки входного фильтра предназначен регистр ICxF, кроме количества выборок, в течение которых микроконтроллер не будет реагировать на входные сигналы, также можно настроить частоту выборок. По сути мы настраиваем время задержки с момента прихода фронта до "подтверждающей" выборки.
Как подключить энкодер к STM32.

Fdts настраивается в регистре CKD, а CK_INT скорее всего TIMxCLK от RCC, N - количество выборок.
Как подключить энкодер к STM32.


В регистре SMCR биты SMS определяют по фронту какого из входов будет вестись подсчёт, а увеличиваться значение счётчика будет или уменьшаться зависит от состояния другого входа, это можно увидеть на картинке ниже.
Как подключить энкодер к STM32.

  • SMS=‘001’ — счёт ведётся по фронтам TI2FP2
  • SMS=‘010’ — счёт ведётся по фронтам TI1FP1
  • SMS=‘011’ — счёт ведётся по каждому из фронтов

В регистре CCER — биты CСxP определяет по какому фронту появиться сигнал TIxFP1.
  • 1 — по спадающему фронту
  • 0 — по возрастающему

В регистре CCMR1 биты ССxS отвечают за настройку мультиплексора выбора входа.

Значение в регистре ARR определяет до какого значения может изменяться счётчик, когда значение счётчика превысит ARR, счётчик обнуляется.

Узнать направление вращения можно считав значение бита DIR в регистре CR1.
  • 1 — значение счетчика уменьшается
  • 0 — значение счетчика увеличивается


Теперь давайте с помощью энкодера будем по очереди зажигать и гасить светодиоды расположенные на плате.

#include "stm32f10x.h"   

void init_tim8()
{	
        //разрешаем тактирование таймера №8
	RCC->APB2ENR |= RCC_APB2ENR_TIM8EN;

       //конфигурируем выводы к которым подключается энкодер как входы с подтяжкой к питанию
	GPIOC->CRL &= ~(GPIO_CRL_CNF6_0 | GPIO_CRL_CNF7_0);
	GPIOC->CRL |= GPIO_CRL_CNF6_1 | GPIO_CRL_CNF7_1;
	GPIOC->ODR |= GPIO_ODR_ODR6 | GPIO_ODR_ODR7;
	
         //настраиваем фильтр
        TIM8->CCMR1 |= TIM_CCMR1_IC1F | TIM_CCMR1_IC2F;
        //настраиваем мультиплексор
	TIM8->CCMR1| = TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
        //сигнал TIxFP1 появиться по возрастающему фронту
	TIM8->CCER &= ~(TIM_CCER_CC1P | TIM_CCER_CC2P);
        //счет по обоим фронтам 
	TIM8->SMCR |= TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1;
         //максимальное значение счетчика 11
	TIM8->ARR = 11;
        //включаем счетчик
	TIM8->CR1 |= TIM_CR1_CEN ;
	//обнуляем счетный регистр
	TIM8->CNT = 0;

}
	

int main(void)
{
        //настраиваем выводы к которым подключен светодиод
	RCC->APB2ENR |= RCC_APB2ENR_IOPEEN | RCC_APB2ENR_IOPCEN; 
	GPIOE->CRL = GPIO_CRL_CNF5_1 | GPIO_CRL_CNF6_1;
	GPIOE->ODR |= GPIO_ODR_ODR5 | GPIO_ODR_ODR6;
	
	init_tim8();
	
	while(1)
	{
                //если значение счетчика равно 4 зажигаем первый светодиод
		if(TIM8->CNT == 4)
		{
			GPIOE->BSRR = GPIO_BSRR_BR5;
		}
		else
		{
			 GPIOE->BSRR = GPIO_BSRR_BS5;
		}
		
		//если значение счетчика равно 8 зажигаем второй светодиод
		if(TIM8->CNT == 8)
		{
			GPIOE->BSRR = GPIO_BSRR_BR6;
		}
		else
		{
			 GPIOE->BSRR = GPIO_BSRR_BS6;
		}
	}

В приведенном примере при каждом щелчке энкодера значение счетчика будет изменяться на 4.
Энкодер покупал тут.
комментарии
0