STM32Cube HAL库——霍尔编码器测速(电机转速测量)

一、测速原理

1.霍尔编码器概述

霍尔编码器(Hall Encoder)是一种用于测量旋转位置和方向的传感器。它通过感应磁场变化来测量旋转轴的位置和方向。
霍尔编码器通常由霍尔传感器、磁极和信号处理电路组成。磁极固定在旋转轴上,随着轴的旋转,磁场的变化被感应到,传感器可以测量这些变化并将它们转化为数字信号。这个数字信号表示旋转轴相对于一个参考位置的旋转角度和方向。
霍尔编码器具有高精度、高分辨率、可靠性高等特点,被广泛应用于机械、电子、自动化控制等领域。常见的应用场景包括机器人、工业自动化、医疗设备、汽车控制等。

2.霍尔编码原理

霍尔编码器是一种通过磁电转换将输出轴上的机械几何位移量转换成脉冲或数字量的传感器。由霍尔码盘和霍尔元件组成。霍尔码盘是在一定直径的圆板上等分地布置有不同的磁极。霍尔码盘与电动机同轴,电动机旋转时,霍尔元件检测输出若干脉冲信号,为判断转向,一般输出两组存在一定相位差的方波信号。
在这里插入图片描述
编码器有 AB 相输出,所以不仅可以测速,还可以辨别转向。根据接线说明可以看到,我们只需给编码器电源 5V 供电,在电机转动的时候即可通过 AB 相输出方波信号。编码器自带了上拉电阻,所以无需外部上拉,可以直接连接到单片机 IO 读取。
在这里插入图片描述

二、STM32CubeMX配置

本例中以电机MG513P3012V上的编码器为例,使用到的单片机为是STM32F405(主要讲过程,与单片机型号关系不大).

1.确定引脚

查看原理图,确定两个编码器的A引脚。(查看确定TIM2和TIM4的通道引脚(也可以选择其它TIM))
在这里插入图片描述
确定编码器 A 和编码器 B 对应的引脚分别为 PB6、PB7 和 PA0、PA1。
对应的定时器为 TIM4 和 TIM2,通道都为CH1和CH2。
接线如下图:
在这里插入图片描述
在这里插入图片描述

2.CubeMX配置

将定时器 TIM2 和 TIM4 均设置为计数器模式(引脚不需要手动选择,自动生成),
对于 TIM2:PA0 和 PA1 引脚分别复用为 TIM2_CH1 和 TIM2_CH2;
对于 TIM4:PB6 和 PB7引脚分别复用为 TIM4_CH1 和 TIM4_CH2。
在这里插入图片描述
在这里插入图片描述
打开基础定时器 6 (按照自己的单片机电路图自己选)全局中断。
在这里插入图片描述
最后生成代码。

三、STM32CubeIDE编程

首先,在代码中加入启用TIM2、TIM4、TIM6的代码(初始化时钟的代码自动生成)。

 //在int main和while之间定义,位置一定要对,在begain和end之间。
  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);//启
  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);//启
  HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_1);//启
  HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_2);//启

  __HAL_TIM_CLEAR_FLAG(&htim6,TIM_FLAG_UPDATE);
  HAL_TIM_Base_Start_IT(&htim6);

在主函数main.c中加入以下三个函数(就main中的普通函数,不在while循环中)。
getTIMx_DetaCnt 函数用于从计时器中获取差值计数,
Get_Motor_Speed 函数用于获取电机速度。使用回调函数,HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim),在
计时器周期结束时被触发。
具体代码如下:

/* USER CODE BEGIN 4 */
int getTIMx_DetaCnt(TIM_HandleTypeDef *htim)
{
    int cnt;
    cnt = htim->Instance->CNT - 0x7FFF;
    htim->Instance->CNT = 0x7FFF;
    return cnt;
}

void Get_Motor_Speed(int *leftSpeed, int *rightSpeed)
{
    *leftSpeed = getTIMx_DetaCnt(&htim2);
    *rightSpeed = getTIMx_DetaCnt(&htim4);
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim == &htim6)
    {
        Get_Motor_Speed(&leftSpeed, &rightSpeed);
    }
}
/* USER CODE END 4 */

为了反映编码器可以测出电机的正反转,这里需要在while()循环中加入判断leftspeed和rightspeed值的代码。代码如下:

	  if (leftSpeed>=0)
	  {
		  OLED_ShowString(15,40,"+");
		  OLED_ShowNumber(25,35,leftSpeed,4,16);
	  }
	  else
	  {
		  OLED_ShowString(15,40,"-");
		  OLED_ShowNumber(25,35,myabs(leftSpeed),4,16);
	  }

	 if(rightSpeed>=0)
	 {
		 OLED_ShowString(80,40,"+");
		 OLED_ShowNumber(90,35,rightSpeed,4,16);
	 }
	 else
	 {
		 OLED_ShowString(80,40,"-");
		 OLED_ShowNumber(90,35,myabs(rightSpeed),4,16);
	 }
	  HAL_Delay(100);
	  OLED_Refresh_Gram();

如果完成了PWM控制电机转速的项目,此时你可以控制电机的转动。
为了验证:将两个电机的PWM参数设为 3000 和 2000,一个正转一个反转。(这里看PWM控制电机转速的项目)。

	 //PWM值:
	  Set_Pwmb(3000);//取值只能在 -8400---+8400
	  Set_Pwma(2000);//取值只能在 -8400---+8400
	  //电机转向:
	  void Motor_Right()
		{
		HAL_GPIO_WritePin(AIN1_GPIO_Port,AIN1_Pin,GPIO_PIN_RESET);
		HAL_GPIO_WritePin(AIN2_GPIO_Port,AIN2_Pin,GPIO_PIN_SET);
		}
	  void Motor_Left()
		{
		HAL_GPIO_WritePin(BIN1_GPIO_Port,BIN1_Pin,GPIO_PIN_RESET);
		HAL_GPIO_WritePin(BIN2_GPIO_Port,BIN2_Pin,GPIO_PIN_SET);
		}

之后,运行代码,无错误。
烧录代码运行后效果如下(两种情况下):
在这里插入图片描述
屏幕中“+”表示正转,“-”表示反转,编码器脉冲数在合理的范围内波动显示,实现了编码器测速。

三、总结

本博客讲解了编码器测速的原理、展示了使用STM32Cube编程读取编码器原始数据的过程。该博客如遇到问题也将进一步完善,源码整理后会将上传。
大家一起学习一起进步,变得更强,希望大家点赞和关注,下期将带来MPU6050相关的内容。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐