STM32旋转编码器应用实例_旋转编码器原理及使用方法
STM32旋转编码器应用实例
- 前言
- 一、旋转编码器原理
-
- 1.1 旋转编码器简介
- 1.2 增量式编码器的工作原理
- 二、STM32定时器编码器模式原理
-
- 2.1 定时器编码器模式简介
- 2.2 定时器编码器模式配置
- 2.3 读取编码器值&清零编码器
- 三、STM32驱动旋转编码器的应用实例
-
- 3.1 应用场景
- 3.2 实例:基于STM32的旋钮控制
-
- 3.2.1 硬件连接
- 3.2.2 软件实现
前言
旋转编码器是一种常用的机械式传感器,广泛应用于需要精确测量角度或位置的场景,如电机控制、人机界面等。STM32单片机提供了多种方式来驱动和读取旋转编码器的信号,本文将详细介绍旋转编码器的工作原理、STM32定时器编码器模式的原理、应用实例以及总结。
一、旋转编码器原理
1.1 旋转编码器简介
旋转编码器是一种将机械旋转转换为电信号的传感器,通常用于测量旋转角度或速度。根据输出信号的形式,旋转编码器分为绝对式编码器和增量式编码器。在嵌入式系统中,增量式编码器更为常见,因为它输出的是脉冲信号,适合实时测量。
1.2 增量式编码器的工作原理
增量式编码器输出两路脉冲信号(通常称为A相和B相),这两路信号在相位上相差90°(即四分之一周期)。通过检测A相和B相的电平变化,可以确定旋转方向和速度。
• 旋转方向:当A相超前B相90°时,编码器正转;当B相超前A相90°时,编码器反转。
• 速度测量:通过测量单位时间内脉冲的数量,可以计算出旋转速度。
1.3 四相位状态
A相和B相的组合可以形成四种状态,通过检测状态的变化顺序,可以判断旋转方向。例如:
• 正转:状态顺序为00->01->11->10->00。
• 反转:状态顺序为00->10->11->01->00。
二、STM32定时器编码器模式原理
2.1 定时器编码器模式简介
STM32单片机的定时器支持编码器模式,可以直接与旋转编码器连接,通过硬件捕获A相和B相的信号,从而实现对旋转方向和速度的测量。这种方式的优点是精度高、响应快,并且可以减轻CPU的负担。
2.2 定时器编码器模式配置
在STM32中,定时器的编码器模式需要配置以下参数:
• 定时器时钟源:选择定时器的时钟源。
• 输入捕获通道:将A相和B相连接到定时器的输入捕获通道。
• 编码器模式:配置定时器为编码器模式。
• 滤波器:配置输入信号的滤波器,以减少噪声干扰。
以下是定时器编码器模式的典型配置代码:
/* TIM2 init function */void MX_TIM2_Init(void){ /* USER CODE BEGIN TIM2_Init 0 */ /* USER CODE END TIM2_Init 0 */ TIM_Encoder_InitTypeDef sConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; /* USER CODE BEGIN TIM2_Init 1 */ /* USER CODE END TIM2_Init 1 */ htim2.Instance = TIM2; htim2.Init.Prescaler = 0; htim2.Init.CounterMode = TIM_COUNTERMODE_DOWN; htim2.Init.Period = 40000; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; sConfig.EncoderMode = TIM_ENCODERMODE_TI12; sConfig.IC1Polarity = TIM_ICPOLARITY_RISING; sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI; sConfig.IC1Prescaler = TIM_ICPSC_DIV1; sConfig.IC1Filter = 5; sConfig.IC2Polarity = TIM_ICPOLARITY_RISING; sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI; sConfig.IC2Prescaler = TIM_ICPSC_DIV1; sConfig.IC2Filter = 5; 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(); } /* USER CODE BEGIN TIM2_Init 2 */HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL); /* USER CODE END TIM2_Init 2 */}
2.3 读取编码器值&清零编码器
通过定时器的计数值可以获取编码器的旋转信息:
/******************************************************************************* Function: Bsp_Encoder_GetValue* Parameter:* * Return: Void * Description:*******************************************************************************/uint32_t Bsp_Encoder_GetValue(TIM_HandleTypeDef *htim){uint32_t value = 0, ret = 0;value = __HAL_TIM_GET_COUNTER(htim);//ret = (40000-value)/4;ret = (value)/2;return ret;}/******************************************************************************* Function: Bsp_Encoder_Clear* Parameter:* * Return: Void * Description:*******************************************************************************/void Bsp_Encoder_Clear(TIM_HandleTypeDef *htim){__HAL_TIM_SET_COUNTER(htim,0);//计数清零}
三、STM32驱动旋转编码器的应用实例
3.1 应用场景
• 人机界面:作为旋钮输入,用于调节电压、电流、功率等参数、用于目录前翻后翻。
3.2 实例:基于STM32的旋钮控制
3.2.1 硬件连接
3.2.2 软件实现
• 获取编码值
typedef struct{uint32_t value;int Ec11_direct;//-1-减小 1-增大}EC11ValueDef;
EC11ValueDef Drv_Encoder_GetValue(TIM_HandleTypeDef *htim){EC11ValueDef data;static uint32_t LastVale;static int direct = 0;data.value = Bsp_Encoder_GetValue(htim);if((LastVale<2000)&&(data.value>8000)){Bsp_Encoder_SetVal(htim, 0);direct = -1;data.value = 0;return data;}else if((LastVale>8000)&&(data.value<2000)){Bsp_Encoder_SetVal(htim, 10000);direct = 1;data.value = 10000;return data;}else if(LastVale>data.value){direct = -1;}else if(LastVale<data.value){direct = 1;}data.Ec11_direct = direct;LastVale = data.value;return data;}
限定防止数值翻转
typedef enum{PLACE_ZERO = 0, PLACE_ONES = 1, /*!< 个位数 */ PLACE_TENS = 10, /*!< 十位数 */ PLACE_HUNDREDS = 100, /*!< 百位数 */ PLACE_THOUSANDS = 1000, /*!< 千位数 */ PLACE_TEN_THOUS = 10000, /*!< 万位数 */} EnCoder_Places_e;
/******************************************************************************* Function: Api_Encoder_GetPara* Parameter: * * Return: Void * Description: 输出范围为 0-10000,则上下限允许设置范围为 0-10000, 按位数进行修改,注意位数不超过上下限范围*******************************************************************************/void Api_Encoder_GetPara(uint16_t *outVal,uint16_t minVal, uint16_t maxVal, EnCoder_Places_e places){int detla = 0;static EC11ValueDef data;EC11ValueDef temp;temp.value = Bsp_Encoder_GetValue(&htim2);if(temp.value != data.value){detla = temp.value - data.value;if((detla>0)||((detla<0)&&(detla+20000)<1000)){temp.Ec11_direct = 1;}else{temp.Ec11_direct = -1;}if((*outVal >= (-1*(int)(detla*(int)places))) && (abs(detla)<100)){*outVal += (int)(detla*places);}else if((*outVal>minVal) && (detla<0) && (abs(detla)<100)){*outVal = minVal;}data = temp;}if((int)*outVal>maxVal){*outVal = maxVal;}if((int)*outVal<minVal){*outVal = minVal;}}
• 应用旋转获取0-5的数值,每次步进1:
Api_Encoder_GetPara(uint16_t *outVal,uint16_t minVal, uint16_t maxVal, EnCoder_Places_e places)
Api_Encoder_GetPara(&index, 0, 5, 1);
四、总结
本文介绍了旋转编码器的工作原理、STM32定时器编码器模式的配置方法以及基于STM32的旋转编码器应用实例。通过定时器的硬件支持,STM32可以高效地读取旋转编码器的信号,实现对旋转方向和速度的精确测量。旋转编码器在电机控制、人机界面等地方具有广泛的应用前景,掌握其使用方法对于嵌入式系统开发人员来说是非常有价值的。
参考:旋转编码器数值获取单片机/STM32代码:旋转编码器限定上下范围,按十位、百位、千位、万位为单位步进调整数值