STM32F4 读取双相编码器(附源码)

本文介绍了STM32F4读取AB相编码器的原理与代码。AB相编码器有两路脉冲信号,通过脉冲计数可测转动角度。STM32系列定时器自带编码器功能,能自动判断正反转。代码流程包括GPIO口初始化、定时器编码器模式初始化和读取定时器计数值,并给出了源码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

STM32F4 读取AB相编码器(附源码)

1. 原理

1.1 AB相编码器

在这里插入图片描述
AB相编码器,简而言之,就是有两路输出的脉冲信号,通过对脉冲计数,可以知道转动了多少角度。

读取编码器的数据也就是要让单片机对脉冲计数。

1.2 定时器的编码器模式

下面是我从STM32F4的中文数据手册中 “通用定时器” 一节摘取出来的片段。
STM32系列的定时器自带有编码器的功能,并且还能通过TIMx_CR1的DIR位自动判断正反转,可以自动的递增计数或递减计数。
详细的编码器模式可以见下文中的图片。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2. 代码

代码的流程有三步:
  • GPIO口初始化
  • 定时器编码器模式初始化
  • 读取定时器计数值
源代码如下:
void encoder_tim3_init(void)
{
	// GPIO口初始化
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;  // GPIO口的输入模式配置很重要,不正确的话会读不到数据
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3);    
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_TIM3);
	
	// 定时器编码器模式初始化
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	
	TIM_DeInit(TIM3);
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
	TIM_TimeBaseStructure.TIM_Prescaler = 0;
	TIM_TimeBaseStructure.TIM_Period = 65535;
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	//TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 这里可以自己设置,或使用默认值
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
	
	TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising ,TIM_ICPolarity_Rising); // 这里配置了编码器模式
	
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICStructInit(&TIM_ICInitStructure);
	//TIM_ICInitStructure.TIM_ICFilter = 10; // 这里可以自己设置,或使用默认值
	TIM_ICInit(TIM3, &TIM_ICInitStructure);
	
	TIM_SetCounter(TIM3, 0);
	TIM_Cmd(TIM3, ENABLE);
}

// 读取定时器计数值
int read_encoder(void)
{
	int encoder_num;
	encoder_num = (int)((int16_t)(TIM3->CNT)); // 这里尤其需要注意数据类型
	TIM_SetCounter(TIM3, 0);
	return encoder_num;
}


int main(void)
{
	u32 t=0;
	uart_init(115200);
	encoder_tim3_init();
	delay_init(84);
	int encoder;
    while(1){
		encoder = read_encoder();
        printf("t:%d\r\n",encoder);
		delay_ms(1000);
		t++;
	}
}

### STM32 控制双相霍尔编码器减速电机 #### 初始化配置 为了使STM32能够有效地控制带有双相霍尔编码器的减速电机,初始化阶段至关重要。这涉及到设置GPIO端口、启用外设时钟以及配置定时器以进入编码器模式。 ```c // 启用所需外设时钟并初始化 GPIO 和 TIMx 外设 __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_TIM2_CLK_ENABLE(); static void MX_GPIO_Init(void) { __HAL_RCC_GPIOA_CLK_ENABLE(); } void HAL_MspInit(void){ /* Configure the system clocks */ SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); } ``` #### 定时器配置 针对特定应用需求调整定时器参数,确保其工作于四倍频模式下,以便更精确地捕捉位置变化信号[^5]。 ```c TIM_HandleTypeDef htim2; void MX_TIM2_Init(void) { TIM_Encoder_InitTypeDef sConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; htim2.Instance = TIM2; htim2.Init.Prescaler = 0; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 65535; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; sConfig.EncoderMode = TIM_ENCODERMODE_TI12; sConfig.IC1Polarity = TIM_ICPOLARITY_RISING; sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI; sConfig.IC1Prescaler = TIM_ICPSC_DIV1; sConfig.IC1Filter = 0; sConfig.IC2Polarity = TIM_ICPOLARITY_RISING; sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI; sConfig.IC2Prescaler = TIM_ICPSC_DIV1; sConfig.IC2Filter = 0; if (HAL_TIM_Encoder_Init(&htim2, &sConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { Error_Handler(); } } ``` #### 获取当前位置数据 编写函数用于获取当前的位置信息,并处理溢出情况,保证返回值始终处于合理范围内。 ```c short Read_Encoder(void) { short Encoder_TIM; //定义编码器读数为short类型 Encoder_TIM = (short)(__HAL_TIM_GET_COUNTER(&htim2)); __HAL_TIM_SET_COUNTER(&htim2, 0); // 计数器清零 return Encoder_TIM; } ``` #### PWM速度调节 通过改变PWM占空比来调控电机的速度,实现对运动状态的有效管理[^4]。 ```c #define MOTOR_PWM_CHANNEL TIM_CHANNEL_1 #define MOTOR_PWM_PIN GPIO_PIN_8 #define MOTOR_PWM_PORT GPIOB uint16_t SetMotorSpeed(uint16_t speed) { uint32_t duty_cycle = (speed * 100 / 65535); __HAL_TIM_SET_COMPARE(&htim2, MOTOR_PWM_CHANNEL, duty_cycle); return duty_cycle; } ```
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值