前言
电机的定位控速都离不开对于转子位置的检测。采用霍尔传感器的是电机控制的常用方法。
本文就笔者学习霍尔传感器的使用尝试自己写这部分算法的一些心得与各位大神交流。
2025/11/16 更新发布HALL传感器的中间层代码,供大家交流学习。
1 电机霍尔状态
我们知道,一个周期有6个霍尔状态,而霍尔状态的数值顺序与霍尔安装角度和霍尔传感器的型号、安装方式都有关系。
以120°相位差安装为例,霍尔状态依次5(101)、4(100)、6(110)、2(010)、3(011)、1(001)。
关于霍尔传感器状态的顺序测量可以参见以下两篇文章:
链接: 【电机控制】霍尔传感器和反电动势的关系分析
链接: 【电机控制】无刷电机基础算法
以下通过伪代码简要说明实现方式。
/* 锁定HU HV HW与GPIO的对应关系 */
hall_u_status = Get_PinLevel(real_hall_u_port&pin);
hall_v_status = Get_PinLevel(real_hall_v_port&pin);
hall_w_status = Get_PinLevel(real_hall_w_port&pin);
/* 根据对应关系获取霍尔状态 */
hall_status = hall_u_status<<2 | hall_v_status<<1 | hall_w_status<<0;
如果MCU具备PWDT模块,且有HALL检测封装函数,可以直接调用。如AC780X系列:
g_hall.pData->hall_status_buff = PWDT_GetHallStatus(PWDT) & 0x07;
当然,其实现算法与伪代码类似,更为简洁的方式是直接按模块IO读取霍尔组合状态。
2 霍尔检测的基本目标
2.1 位置(电角度)初始化
对于一个确定的电极,霍尔状态分为6种,即每次霍尔状态更新我们可以校正一次电角度,显然,根据霍尔状态测量得到的电角度精度为60°。
以下代码摘自ST的开源算法库中的估算方式,依据霍尔状态对应的电角度中值进行设定。该方法的优点是不管正转反转,其误差都是±30°。需要注意的是,初始电角度只是给整个运行提供一个初始状态,并不需要一个特别精确的值。后面的电角度会根据前面的运行信息得到更精确的估算。
/**
* @brief Read the logic level of the three Hall sensors and individuates in this
* way the position of the rotor (+/- 30°). Electrical angle is then
* initialized.
* @param pHandle: handler of the current instance of the hall_speed_pos_fdbk component
* @retval none
*/
static void HALL_Init_Electrical_Angle(HALL_Handle_t *pHandle)
{
if (pHandle->SensorPlacement == DEGREES_120)
{
pHandle->HallState = LL_GPIO_IsInputPinSet(pHandle->H3Port, pHandle->H3Pin)<<2
| LL_GPIO_IsInputPinSet(pHandle->H2Port, pHandle->H2Pin)<<1
| LL_GPIO_IsInputPinSet(pHandle->H1Port, pHandle->H1Pin);
}
else {
pHandle->HallState = (LL_GPIO_IsInputPinSet(pHandle->H2Port, pHandle->H2Pin)^1)<<2
| LL_GPIO_IsInputPinSet(pHandle->H3Port, pHandle->H3Pin)<<1
| LL_GPIO_IsInputPinSet(pHandle->H1Port, pHandle->H1Pin);
}
switch(pHandle->HallState)
{
case STATE_5:
pHandle->_Super.hElAngle = (int16_t)(pHandle->PhaseShift+S16_60_PHASE_SHIFT/2);
break;
case STATE_1:
pHandle->_Super.hElAngle =(int16_t)(pHandle->PhaseShift+S16_60_PHASE_SHIFT+
S16_60_PHASE_SHIFT/2);
break;
case STATE_3:
pHandle->_Super.hElAngle =(int16_t)(pHandle->PhaseShift+S16_120_PHASE_SHIFT+
S16_60_PHASE_SHIFT/2);
break;
case STATE_2:
pHandle->_Super.hElAngle =(int16_t)(pHandle->PhaseShift-S16_120_PHASE_SHIFT-
S16_60_PHASE_SHIFT/2);
break;
case STATE_6:
pHandle->_Super.hElAngle =(int16_t)(pHandle->PhaseShift-S16_60_PHASE_SHIFT-
S16_60_PHASE_SHIFT/2);
break;
case STATE_4:
pHandle->_Super.hElAngle =(int16_t)(pHandle->PhaseShift-S16_60_PHASE_SHIFT/2);
break;
default:
/* Bad hall sensor configuration so update the speed reliability */
pHandle->SensorIsReliable = false;
break;
}
/* Initialize the measured angle */
pHandle->MeasuredElAngle = pHandle->_Super.hElAngle;
}
2.2 估算当前转速
基本思路:通过FIFO数组来记录通过六区的时间。
(1)启动时,电机速度尚未稳定,FIFO数组尚未被填满,当前转速用最近一次更新的数组数据来进行估算;
(2)FIFO数组填满后,电机处于变动过程中,可以使用最近一次的分区的时间进行估算;当电机转速相对稳定时,FIFO数组的值会在目标转速附近,其极差取决于转速稳定区间。
(3)每当霍尔状态更新时,校正当前霍尔角度。注意,不同转向的校正计算是不一样的。
2.3 霍尔相序的自学习
注:以下是笔者的思路,未参考成熟库的代码,不确保逻辑中没有漏洞。
(1) 通过VF定向方式,将转子按照10°间隔将转子锁定依次锁定在0°,10°,20°。。。350°,360°。。。(根据角度分解到Uq、Ud再分解到Ua,Ub,Uc)。
(2)获取不同角度下的霍尔状态,对于霍尔状态变化的角度区间,进一步缩小角度定向间隔为2°,获取更精确的霍尔状态切换角度,用于角度对齐。
2.4 代码实现
笔者的思路是创建6个霍尔分区节点并按照切换顺序构建循环列表。
核心的操作是每当霍尔状态切换时更新当前节点指针。
对于已知霍尔节点状态的中点角度估算的代码实现就非常方便,用当前节点对齐角度和下一个节点对齐角度求中值即可。
速度估算根据进入当前节点的方向前推或后推各节点的持续时间,对于入口方向和出口方向不同的节点,是转子的换向区(正反转切换)。
当节点切换后,电角度估算 = 对齐角度(依据转向设置) + 计数时间 * 估计角速度。

*/
#ifndef __HALL_SENSOR_H__
#define __HALL_SENSOR_H__
/*!
* @file hall_sensor.h
*
* @brief This file provides hall electric theta and hall self-learn functions interfaces.
*
*/
/* =========================================== Includes =========================================== */
#include "stdint.h"
/* ============================================ Define ============================================ */
#define ZERO_ORDER_FORCE_COMP (0) /*!< define force degree compensation mode */
#define ZERO_ORDER_DISPERSE_COMP (1) /*!< define dispere degree compensation mode */
#define PHASE_SHIFT_05 (PHASE_SHIFT_1 >> 1) /*!< define 0.5 degree in Q16 format */
#define PHASE_SHIFT_1 (uint16_t)(65535 * 1 / 360) /*!< define 1 degree in Q16 format */
#define PHASE_SHIFT_2 (uint16_t)(65535 * 2 / 360) /*!< define 2 degree in Q16 format */
#define PHASE_SHIFT_5 (uint16_t)(65535 * 5 / 360) /*!< define 5 degree in Q16 format */
#define PHASE_SHIFT_10 (uint16_t)(65535 * 10 / 360) /*!< define 10 degree in Q16 format */
#define PHASE_SHIFT_30 (uint16_t)(65535 * 30 / 360) /*!< define 30 degree in Q16 format */
#define PHASE_SHIFT_60 (uint16_t)(65535 * 60 / 360) /*!< define 60 degree in Q16 format */
#define PHASE_SHIFT_90 (uint16_t)(65535 * 90 / 360) /*!< define 90 degree in Q16 format */
#define SELF_LEARN_START (0) /*!< define hall self-learn zero stage*/
#define SELF_LEARN_10DEGREE_FINISHED (1) /*!< define hall self-learn first stage*/
#define SELF_LEARN_2DEGREE_FINISHED (2) /*!< define hall self-learn second stage*/
#define SELF_LEARN_HALL_WIDTH (3) /*!< define hall self-learn third stage*/
#define IF_RUN_FREQ (20ul) /*!< define hall sector width self-learn IF run frequency */
#define HALL_060DEGREE_DISPLACEMENT (0)

本文介绍了霍尔传感器在电机定位和转速控制中的关键作用,包括霍尔状态的转换、电角度的初始化方法,以及如何通过自学习确定霍尔相序。作者分享了霍尔状态的处理策略和转速估算的基本思路,以及自定义的霍尔相序学习方案。
最低0.47元/天 解锁文章
3万+

被折叠的 条评论
为什么被折叠?



