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

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相关的内容。

  • 41
    点赞
  • 216
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
霍尔编码器(Hall Encoder)是一种用于测量旋转位置和方向的传感器。它基于霍尔效应,利用磁场的变化来检测磁极的位置。在编码器中,通常使用两个霍尔传感器,分别称为A相和B相。 霍尔编码器通过检测A相和B相的不同状态变化来确定旋转方向和位置。A相和B相的状态变化可以表示为一个二进制码,通常被称为霍尔编码。根据不同的编码方式,霍尔编码器可以提供不同的分辨率和精度。 在Python中,可以使用各种库和模块来读取和解码霍尔编码器的输出。一种常用的方法是使用RPi.GPIO库来控制树莓派的GPIO引脚,并读取霍尔编码器的输出信号。以下是一个简单的示例代码: ```python import RPi.GPIO as GPIO # 设置GPIO引脚 channel_A = 18 channel_B = 23 # 初始化GPIO GPIO.setmode(GPIO.BCM) GPIO.setup(channel_A, GPIO.IN) GPIO.setup(channel_B, GPIO.IN) # 定义回调函数 def encoder_callback(channel): # 读取A相和B相的状态 state_A = GPIO.input(channel_A) state_B = GPIO.input(channel_B) # 根据状态变化判断旋转方向 if state_A == state_B: print("顺时针旋转") else: print("逆时针旋转") # 添加事件检测 GPIO.add_event_detect(channel_A, GPIO.BOTH, callback=encoder_callback) GPIO.add_event_detect(channel_B, GPIO.BOTH, callback=encoder_callback) # 主循环 while True: pass # 清理GPIO GPIO.cleanup() ``` 请注意,上述示例代码仅提供了一个基本的框架,具体的实现方式可能会因硬件和编码器类型的不同而有所差异。你需要根据实际情况进行适当的调整和修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北辰远_code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值