| 
 | 
 
路线栈欢迎您!
您需要 登录 才可以下载或查看,没有帐号?立即注册 
 
 
 
x
 
 本帖最后由 一路上 于 2024-1-13 22:16 编辑  
 
一、有感BLDC为什么要做启动检测? 
 
1.做启动检测主要是为了防止霍尔传感器有故障或电路异常。 
 
2.做启动检测也是为了整个程序的鲁棒性和健壮性。 
 
二、启动检测的软件实现 
 
1.如下图所示,如果霍尔传感器工作正常,则霍尔值的U、V、W三相中的某一相值为1,另外2相值为0。U相值为bit2,V相值为bit1,W相值为bit0,如果霍尔值等于0或霍尔值大于6,则霍尔输入值检测异常。 
 
 
2.在循环中连续读取霍尔传感器的值,如果值每次都相等,则到了一定次数后直接退出循环,表示启动检测正常。示例代码如下: 
 
- ReadHallCnt = 0;
 
 - ReadLast = 0;
 
 - ReadOverTime=100 ;
 
 - do
 
 - {
 
 - Hall- >HallData = (PINA>>3)&0x7; //读取霍尔传感器的值
 
  复制代码 
启动检测正常后,进行相关换向和速度控制功能。 
 
三、电机运行过程中的堵转检测 
 
1.电机在运行过程中有可能电机加载负载过大,或者系统供电不足,导致电机停止转动,如果长时间堵转,很可能会导致电机过热损毁。 
 
2.检测堵转方法是:在换向的方法里,做换向超时检测,如果在规定时间内没有换向,霍尔传感器的采集值始终无变化,那么就发生了堵转。堵转异常处理一般有时间指标,如果超过这个时间指标,就停止电机工作。 
 
四、启动方法 
 
在使用hall传感器的情况下可以直接获取到转子的位置,不需要对齐,但要加一个最大转矩启动状态,在此阶段使电机输出最大转矩(通过电流环实现),为了防止启动过冲给电流启动加一个斜坡。当电机速度达到设定的启动速度后自动切换到速度闭环模式。 
 
1.状态机 
 
 
  
2.Calib2Aligment 
 
在Calib完成后执行C2A(AppStopToAlignment())函数,初始化电流PI环参数、电流斜坡函数,通过霍尔传感器获取转子所在扇区,开启相应驱动桥臂。然后跳转到Aligment状态。 
 
- void AppStopToAlignment(void)
 
 - {
 
 -         uint8_t i;
 
  
-     driveStatus.B.Alignment = 1; //状态更新,在LPIT0中进行电流PI环计算和更新
 
 -     driveStatus.B.EnableCMT = 1; //开启换相,只有开启才能在FTM2的捕获中断中自动换相
 
 -     driveStatus.B.CloseLoop = 0;
 
 -     driveStatus.B.Calib = 0;
 
 -         driveStatus.B.Sensorless = 0;
 
 -         driveStatus.B.NewZC = 0;
 
  
-     /* Torque ramp initialization */
 
 -     torqueRampPrms.fltState = 0.0F; //力矩斜坡的初始值
 
  
-     alignmentTimer = mcat_alignDuration;//启动时间=20000,1s
 
 -     duty_cycle = MLIB_Mul(MLIB_Div(mcat_alignVoltage, U_PH_NOM), 100.0F); //mcat_alignVoltage=1.5F 启动占空比=1.5/12*100 
 
  
-     /* Current PI controller initialization */
 
 -         currentPIPrms.fltInK_1 = 0;//初始误差
 
 -         currentPIPrms.fltIntegPartK_1 = duty_cycle;//初始积分项
 
  
-     /* Update PWM duty cycle*/
 
 -         ACTUATE_SetDutycycle(duty_cycle, HW_INPUT_TRIG1);
 
 -         /*根据三个霍尔引脚的电平计算所在扇区,更新到SensorHall.Sector*/ 
 
 -         HALL_GetSector(&SensorHall);
 
 -         /* 开启相关桥臂,相当于第一次换相在此手动开启 */
 
 -         ACTUATE_SetPwmMask(ui8FTM3OutmaskVal[rotationDir][SensorHall.Sector],
 
 -                                                   ui16FTM3SwOctrlVal[rotationDir][SensorHall.Sector], HW_INPUT_TRIG0);
 
 -         
 
 -         /*在电机转动起来之前无法测量电机转速,因此需要先手动初始化一个转速*/
 
 -         for( i=0;i<6;i++)
 
 -                 {
 
 -                         SensorHall.Period[i] =60000  ;/*将扇区时间设为最大,这样初始转速约等于0*/
 
 -                 }
 
 -     appState = APP_ALIGNMENT; /*跳转到Aligment*/
 
 - }
 
 
  复制代码 
3.力矩闭环 
 
进入Aligment后,通过driveStatus.B.Alignment=1在LPIT0中断每1ms进行1次电流环计算: 
 
- void LPIT0_Ch0_IRQHandler(){
 
 - if(driveStatus.B.Alignment == 1)
 
 -     {
 
 -             /*更新当前速度,用于状态跳转判断*/
 
 -             actualSpeed = MLIB_Mul(MLIB_ConvertPU_FLTF32(MLIB_Div_F32(SPEED_SCALE_CONST, period6ZC)), N_MAX);
 
 -             /*
 
 -              GFLIB_Ramp斜坡函数,使电流目标值按照设定的斜率从0增加到I_DCB_LIMIT
 
 -              计算电流误差:电流目标值-滑动滤波后的电流值(torque_filt)
 
 -                 */
 
 -             torqueErr = MLIB_Sub(GFLIB_Ramp(I_DCB_LIMIT, &torqueRampPrms), torque_filt);
 
 -             /*计算PI输出*/
 
 -             currentPIOut = GFLIB_ControllerPIpAW(torqueErr, ¤tPIPrms);
 
 -                   /*更新PWM占空比*/
 
 -                   duty_cycle = currentPIOut;
 
 -             ACTUATE_SetDutycycle(duty_cycle, HW_INPUT_TRIG0);
 
 -     }
 
 - }
 
  复制代码- void AppAlignment(void)
 
 - {
 
 - /*alignmentTimer每1/20000秒自减1*/
 
 -         if((alignmentTimer == 0)||(actualSpeed >= 300))
 
 -             {
 
 -                     if(actualSpeed < 300)
 
 -                     {
 
 -                             AppAlignmentToFault();/*启动时间到了但速度每上来,启动失败*/
 
 -                     }else
 
 -                     {
 
 -                             AppAlignmentToStart();/*启动成功*/
 
 -                     }                  
 
 -             }
 
 - }
 
  
- void AppAlignmentToStart(void)
 
 - {
 
 -     driveStatus.B.Alignment = 0;/*关闭电流环*/
 
 -     driveStatus.B.EnableCMT = 1;
 
 -         driveStatus.B.AfterCMT  = 0;
 
 -         appState = APP_START;/*跳转至Start*/
 
 - }
 
 
  复制代码 
4.Start2Run 
 
电机到达启动速度后切换到运行状态,对运行状态参数初始化后进入速度电流双闭环运行状态。 
 
- void AppStartToRun(void)
 
 - {
 
 -     /* 速度PI控制参数初始化 */
 
 -     speedPIPrms.fltInK_1 = 0;/*初始误差*/
 
 -     speedPIPrms.fltIntegPartK_1 = duty_cycle;/*直接将启动阶段计算的占空比作为初始积分结果*/
 
  
-     /* 电流PI控制参数初始化 */
 
 -     currentPIPrms.fltInK_1 = 0;
 
 -     currentPIPrms.fltIntegPartK_1 = speedPIPrms.fltIntegPartK_1;
 
  
-     /* 速度斜坡参数初始化 */
 
 -     speedRampPrms.fltState = mcat_NMin;/*初始输入速度设为0*/        
 
 -         /*状态跳转*/
 
 -     appState = APP_RUN;
 
 -     stallCheckCounter = 0; /*清除失速检测计数*/
 
 -     faultStatus.B.StallError = 0;
 
 -     // Reset FTM2 counter
 
 -         FTM2->CNT = 0;
 
 -     // Clear FTM counter overflow flag
 
 -         FTM2->SC &= (~FTM_SC_TOF_MASK);
 
 -     driveStatus.B.CloseLoop = 1;/*进入速度力矩双闭环模式*/
 
 - }
 
 
  复制代码 
五、结果运行 
 
如下图,电机以一个比较平滑的速度启动,并且启动负载增大后可以自动增加启动力矩。 
 
 |   
 
 
 
 |