第一步:可以看出当只有一对级时,旋转一圈霍尔输出一个完整脉冲(一N一S)
第二步:计算其中高电平的持续时间,即:t = C / Ft (其中Ft是计数频率,C为计数次数
第三步:所以旋转一圈,需要的总时间为T = 2*C/Ft
所得出的结果就为:s/圈 ,倒数就为:圈/s ,转化为RPM即:Ft/(2*C) *60 即可
值得注意的是,转子由N到S,就是经历了电角度180度,这个是关键,在根据上文说到的公式:
电角度 = 机械角度 * 极对数
可以知道,一极对下,电机转一圈霍尔信号就是一高一低(一次高电平,一次低电平为一个周期,此时刚好转一圈)因为此时电角度等于机械角度。
由此,我们可以推导出,在n极对数下,电机转一圈霍尔信号就是n高n低,一圈机械角度为360度,那么电角度 = n*360
在代码实现上,我们重点关注一个霍尔信号即可,通过这个信号告诉mcu此时霍尔信号跳变情况。
/**
* @brief 获取霍尔传感器引脚状态
* @param motor_id :无刷接口编号
* @retval 霍尔传感器引脚状态
*/
u32 hallsensor_get_state(u8 motor_id)
{
__IO static u32 state;
state = 0;
if(motor_id == MOTOR_1)
{
if(HAL_GPIO_ReadPin(HALL1_TIM_CH1_GPIO,HALL1_TIM_CH1_PIN) != GPIO_PIN_RESET) /* 霍尔传感器状态获取 */
{
state |= 0x01U;
}
if(HAL_GPIO_ReadPin(HALL1_TIM_CH2_GPIO,HALL1_TIM_CH2_PIN) != GPIO_PIN_RESET) /* 霍尔传感器状态获取 */
{
state |= 0x02U;
}
if(HAL_GPIO_ReadPin(HALL1_TIM_CH3_GPIO,HALL1_TIM_CH3_PIN) != GPIO_PIN_RESET) /* 霍尔传感器状态获取 */
{
state |= 0x04U;
g_bldc_motor1.hall_single_sta = 1; //检测单次霍尔电平信号,做速度计算
}
else g_bldc_motor1.hall_single_sta = 0;
}
else if(motor_id == MOTOR_2)
{
if(HAL_GPIO_ReadPin(HALL2_TIM_CH1_GPIO,HALL2_TIM_CH1_PIN) != GPIO_PIN_RESET) /* 霍尔传感器状态获取 */
{
state |= 0x01U;
}
if(HAL_GPIO_ReadPin(HALL2_TIM_CH2_GPIO,HALL2_TIM_CH2_PIN) != GPIO_PIN_RESET) /* 霍尔传感器状态获取 */
{
state |= 0x02U;
}
if(HAL_GPIO_ReadPin(HALL2_TIM_CH3_GPIO,HALL2_TIM_CH3_PIN) != GPIO_PIN_RESET) /* 霍尔传感器状态获取 */
{
state |= 0x04U;
}
}
return state;
}
/**
* @brief 检测输入信号是否发生变化
* @param val :输入信号
* @note 测量速度使用,获取输入信号状态翻转情况,计算速度
* @retval 0:计算高电平时间,1:计算低电平时间,2:信号未改变
*/
u8 uemf_edge(u8 val)
{
static u8 old_val;
if(old_val != val)
{
old_val = val;
if(val == 1) return 0; //上升沿
else return 1; //下降沿
}
return 2;
}
/******************************* 速度计算 *******************************/
g_bldc_motor1.count_tim++; /* 计算速度专用计数值,也就是"C",计算定时器计数次数 */
g_bldc_motor1.hall_sta_edge = uemf_edge(g_bldc_motor1.hall_single_sta); //输入第三个霍尔信号的电平状态
if(g_bldc_motor1.hall_sta_edge == 0) //上升沿
{
/*计算速度*/
if(g_bldc_motor1.dir == CW)//顺时针旋转
{
temp_speed = (SPEED_COEFF / g_bldc_motor1.count_tim);
}
else
{
temp_speed = -(SPEED_COEFF / g_bldc_motor1.count_tim);
}
FirstOrderRC_LPF(g_bldc_motor1.speed,temp_speed,0.2379f); /* 一阶滤波 */
g_bldc_motor1.hall_no_single_time = 0;
g_bldc_motor1.count_tim = 0;
}
if(g_bldc_motor1.hall_sta_edge == 1) //下降沿
{
g_bldc_motor1.hall_no_single_time = 0;
g_bldc_motor1.count_tim = 0;
}
if(g_bldc_motor1.hall_sta_edge == 2) //电平无变化,即电机停止工作
{
g_bldc_motor1.hall_no_single_time++; /* 不换相时间累计 超时则判定速度为0 */
if(g_bldc_motor1.hall_no_single_time > 800) //800ms
{
g_bldc_motor1.hall_no_single_time = 0;
g_bldc_motor1.speed = 0; /* 超时换向 判定为停止 速度为0 */
}
}
标签:PIN,bldc,motor1,TIM,无刷,GPIO,测速,hall
From: https://blog.csdn.net/m0_74424600/article/details/142347229