STM32 Подключение инкрементального энкодера

Автор: | 27.11.2018

Энкодер ужасно удобное устройство для управления, на мой взгляд гораздо удобнее обычных кнопок. Его можно сравнить с переменным резистором, но у энкодера больше преимуществ например:

  1. Может делать сколь угодно оборотов
  2. Быстро установить точное значение

У микроконтроллеров ST реализована аппаратная обработка сигналов энкодера, входит она в состав некоторых таймеров.

 

Энкодеры по конструкции бывают разных типов:

  • Механические (контакты)
  • Оптические (светодиод, фотоприемник, перфорированный диск)
  • Электромагнитные (можно сделать из шагового двигателя)

Я подключил вот такой:

Это механический энкодер с Aliexpress в виде модуля для ардуино. Этот энкодер еще в придачу, кнопкой.

Назначение выводов:

  • GND (Общая шина)
  • +        (Плюс питания)
  • SW    (Тактовая кнопка)
  • DT     (Сигнал направления вращения)
  • CLK   (Сигнал тактовый)

В datasheet написано, что все таймеры общего назначения могут обрабатывать сигналы квадратурных (инкрементальных) энкодеров. Выводы (CLK) и (DT) подключаются к входам таймера (TIMx_CH1) и (TIMx_CH2). Я свой энкодер подключил к TIM3 заработало без проблем.

Код инициализации таймера:

void Encoder_init(void)
{


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

GPIO_InitTypeDef encod;
encod.GPIO_Mode = GPIO_Mode_IPD;
encod.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
encod.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_StructInit(&encod);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

TIM_TimeBaseInitTypeDef TIMER_InitStructure;
TIM_TimeBaseStructInit(&TIMER_InitStructure);
TIMER_InitStructure.TIM_Period = 180;
//TIMER_InitStructure.TIM_CounterMode = TIM_CounterMode_Down|TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIMER_InitStructure);
TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI1, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
TIM_Cmd(TIM3, ENABLE);

}

 

Получение значения через функцию:

#include "main.h"

char lcd_buff[50];
uint16_t Y,X;


int main(void)
{
cconf_init();
delay_init();
I2C_Configuration();
LCD_init();
LCD_com(0x0C);
Encoder_init();
Timer_init();


while(1)
{

X = TIM_GetCounter(TIM3);

sprintf(lcd_buff,"%04u",X);
LCD_puts(lcd_buff);
LCD_gotoxy(0,0);

}
}

 

Использование прерывания:

#include "main.h"


char lcd_buff[50];
uint16_t Y,X;

void EXTI0_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line0) != RESET)
{
X = X+1;
EXTI_ClearITPendingBit(EXTI_Line0);
}
}


int main(void)
{
cconf_init();
delay_init();
I2C_Configuration();
LCD_init();
LCD_com(0x0C);
Encoder_init();
Timer_init();
Interrupt_init();


while(1)
{
sprintf(lcd_buff,"%04u",X);
LCD_puts(lcd_buff);
LCD_gotoxy(0,0);

}
}

 

Видео пример работы:

На этом на верное все, свои вопросы можете оставлять в комментариях. Всего наилучшего вам.

 

 

ПОДДЕРЖАТЬ ПРОЕКТ

Добавить комментарий