[i=s] 本帖最后由 lc115647 于 2025-8-15 21:52 编辑 [/i]
一、霍尔传感器与电机转动的本质关系
- 3个霍尔元件呈120°电角度分布(下图可看出相位差120°),检测转子磁极位置
- 电机每旋转60°电角度,霍尔组合状态变化一次
- 完整电周期(360°电角度)产生6次状态变化
给出了三个传感器的输出和每相的相应反电动势( BEMF)电压波形。


二、速度计算公式的完整推导
设:
l Δt:两次霍尔变化的时间间隔(秒)
l P:电机极对数(磁极数/2)
l f_m:机械转速(转/秒)
推导过程:
每个Δt对应60°电角度
l 完整电周期(360°)时间:T_e = 6 × Δt
l 机械转速:f_m = 1/(P × T_e) = 1/(P × 6 × Δt)
l RPM(转/分):RPM = 60 × f_m = 60/(6PΔt) = 10/(PΔt)
三、软件实现
1、定时器初始化,配置为输入捕获模式
void Drv_Hall_Init(u32 arr, u16 psc)
{
TMR_TimeBase_T TIM_TimeBaseStructure;
TMR_ICConfig_T TIM_ICInitStructure;
TMR_Reset(TMR2);
TMR_ConfigTimeBaseStruct(&TIM_TimeBaseStructure);
/* Sets the value of the automatic reload register Period for the next update event load activity
* Set the Prescaler value used as the divisor of the TIMx clock frequency
* Set clock split :TDTS = TIM_CKD_DIV1
* Up counting mode
*/
TIM_TimeBaseStructure.period = arr;
TIM_TimeBaseStructure.div = psc;
TIM_TimeBaseStructure.clockDivision = TMR_CKD_DIV1;
TIM_TimeBaseStructure.counterMode = TMR_COUNTER_MODE_UP;
TIM_TimeBaseStructure.repetitionCounter = 0;
TMR_ConfigTimeBase(TMR2, &TIM_TimeBaseStructure);
/**
* Initialize TIM2 input capture parameters
* CC1S=01 selects the input terminal IC1 to be mapped to TI1
* Set to double edge capture
* Map to TI1
* Configure input frequency division, no frequency division
* Configure input filter IC1F to 8
*/
TIM_ICInitStructure.channel = TMR_CHANNEL_1;
TIM_ICInitStructure.ICpolarity = TMR_IC_POLARITY_BOTHEDGE;
TIM_ICInitStructure.ICselection = TMR_IC_SELECTION_DIRECT_TI;
TIM_ICInitStructure.ICprescaler = TMR_ICPSC_DIV1;
TIM_ICInitStructure.ICfilter = 0x0f;
TMR_ICConfig(TMR2, &TIM_ICInitStructure);
/** Enable the Hall sensor interface of TIM2 */
TMR_EnableHallSensor(TMR2);
/** Input trigger source selection TI1 Edge Detector */
TMR_SelectInputTrigger(TMR2, TMR_TS_TI1F_ED);
/** Select from mode to reset mode */
TMR_SelectSlaveMode(TMR2, TMR_SLAVEMODE_RESET);
TMR_EnableMasterSlaveMode(TMR2);
/** Allow interrupts to be triggered */
TMR_EnableInterrupt(TMR2, TMR_INT_UPDATE);
TMR_EnableInterrupt(TMR2, TMR_INT_CH1);
TMR_ClearIntFlag(TMR2, TMR_INT_FLAG_UPDATE);
TMR_ClearIntFlag(TMR2, TMR_INT_FLAG_CH1);
TMR_ICConfigStructInit(&TIM_ICInitStructure);
// NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);
TMR_Enable(TMR2);
}
2、定时器输入捕获中断,获取时间差,计算速度
void TMR2_IRQHandler(void)
{
static uint8_t i = 0;
uint8_t j = 0;
if(TMR_ReadIntFlag(TMR2, TMR_INT_FLAG_CH1) != RESET)
{
i++;
if(i >= 6)
{
i = 0;
}
/*Hall change time capture*/
Motor_1st.HALL.HallTime[i] = TMR2->CC1;
/*Read HALL value*/
ReadHallValue = HALL_JudgeState();
Motor_1st.HALL.RunHallValue = ReadHallValue;
Motor_1st.HALL.HallTimeSum = 0;
for(j=0;j<6;j++)
{
Motor_1st.HALL.HallTimeSum += Motor_1st.HALL.HallTime[j];
}
/*Motor speed calculation*/
Motor_1st.HALL.SpeedTemp = SPEEDX/Motor_1st.HALL.HallTimeSum;
if(SpeedFdk.Out >= 200)
{
if(Motor_1st.BLDC.RPValue.s16Act < 100)
{
PWMH_OFF_PWML_OFF
}
else
{
MotorDrive(ReadHallValue);
}
}
TIMFlag.HallDelay = 0;
TMR_ClearIntFlag(TMR2, TMR_INT_FLAG_CH1);
}
if(TMR_ReadIntFlag(TMR2, TMR_INT_FLAG_UPDATE) != RESET)
{
TIMFlag.HallDelay++;
if(TIMFlag.HallDelay >= 10)
{
TIMFlag.HallDelay = 0;
Motor_1st.HALL.SpeedTemp = 0;
SpeedFdk.Out = 0;
MovingAvgInit(&SpeedFdk);
}
TMR_ClearIntFlag(TMR2,TMR_INT_FLAG_UPDATE);
}
}
四、总结
通过定时器输出捕获,获取每次HALL状态时间差,从而计算出电机的速度,只可简单实现电机运行功能。实际应用中任存在一些问题,比如电机霍尔角度安装本身就会存在偏差,导致实际的角度并不是60度电角度;同时电机负载突变也会导致某段时间速度波动大,导致速度估算出现错误。