FU6812做高压无感FOC吊扇控制,怎么在上电后快速检测是否有插电机?缺相是启动后检测,但不插电机需要报故障怎么检测?
/*---------------------------------------------------------------------------*/
/* Name : void Fault_Detection(void)
/* Input : NO
/* Output : NO
/* Description: 保护函数,因保护的时间响应不会很高,采用分段处理,每5个定时器中断执行一次对应的保护
常见保护有过欠压、过温、堵转、启动、缺相等保护,调试时,可根据需求,一个个的调试加入。
/*---------------------------------------------------------------------------*/
void Fault_Detection(void)
{
mcFaultDect.segment++;
if(mcFaultDect.segment>=5)
{
mcFaultDect.segment=0;
}
if(mcFaultDect.segment==0)
{
if(CurrentRecoverEnable)//过流保护恢复使能
{
Fault_OverCurrentRecover(&mcFaultDect);
}
}
else if(mcFaultDect.segment==1)
{
if(VoltageProtectEnable==1)//过压保护使能
{
Fault_OverUnderVoltage(&mcFaultDect);
}
}
else if(mcFaultDect.segment==2)
{
if(StartProtectEnable==1)//启动保护使能
{
Fault_Start(&mcFaultDect);
}
}
else if(mcFaultDect.segment==3)
{
if(StallProtectEnable==1)//堵转保护使能
{
Fault_Stall(&mcFaultDect);
}
}
else if(mcFaultDect.segment==4)
{
if(PhaseLossProtectEnable==1)//缺相保护使能
{
Fault_phaseloss(&mcFaultDect);
}
}
else
{
}
}
/*****************************************************************************
* Function: void Fault_phaseloss(mcFaultVarible *h_Fault)
* Description: 缺相保护函数,当电机运行状态下,10ms取三相电流的最大值,
1.5s判断各相电流最大值,若存在两相电流值大于一定值,而第三相电流值却非常小,则判断为缺相保护,电机停机;
* Parameter: mcFaultVarible *h_Fault
* Return: no
*****************************************************************************/
void Fault_phaseloss(FaultVarible *h_Fault)
{
if(mcState == mcRun)
{
h_Fault->Lphasecnt++;
if(h_Fault->Lphasecnt>100)//100*5=500ms
{
h_Fault->Lphasecnt=0;
if((mcCurVarible.Max_ia<PhaseLossLowCurrent)&&(mcCurVarible.Max_ib>PhaseLossHighCurrent)&&(mcCurVarible.Max_ic>PhaseLossHighCurrent))
{
h_Fault->AOpencnt++;
}
else
{
h_Fault->AOpencnt =0;
}
if((mcCurVarible.Max_ib<PhaseLossLowCurrent)&&(mcCurVarible.Max_ia>PhaseLossHighCurrent)&&(mcCurVarible.Max_ic>PhaseLossHighCurrent))
{
h_Fault->BOpencnt++;
}
else
{
if(h_Fault->BOpencnt>0)
h_Fault->BOpencnt --;
}
if((mcCurVarible.Max_ic<PhaseLossLowCurrent)&&(mcCurVarible.Max_ib>PhaseLossHighCurrent)&&(mcCurVarible.Max_ia>PhaseLossHighCurrent))
{
h_Fault->COpencnt++;
}
else
{
if(h_Fault->COpencnt>0)
h_Fault->COpencnt --;
}
mcCurVarible.Max_ia = 0;
mcCurVarible.Max_ib = 0;
mcCurVarible.Max_ic = 0;
if(h_Fault->AOpencnt > 1|| h_Fault->BOpencnt > 1 || h_Fault->COpencnt > 1)
{
mcProtectTime.LossPHTimes++;
mcFaultSource=FaultLossPhase;
FaultProcess();
SetBuzzer(1, 1, 2); //蜂鸣器响两声
}
}
}
#if (!StartONOFF_Enable)
{
/*******缺相保护恢复*********/
if((mcFaultSource==FaultLossPhase)&&(mcState == mcFault)&&
(mcProtectTime.LossPHTimes<5))//可重启5次
{
h_Fault->mcLossPHRecCount++;
if(h_Fault->mcLossPHRecCount>=PhaseLossRecoverTime)
{
h_Fault->AOpencnt=0;
h_Fault->BOpencnt=0;
h_Fault->COpencnt=0;
mcState = mcReady;
mcFaultSource=FaultNoSource;
}
}
else
{
h_Fault->mcLossPHRecCount=0;
}
}
#endif
}
/*---------------------------------------------------------------------------*/
/* Name : void MC_Control(void)
/* Input : NO
/* Output : NO
/* Description: 电机状态机函数,包括初始化、预充电、顺风逆风判断、预定位、启动、运行、故障等
/*---------------------------------------------------------------------------*/
void MC_Control(void)
{
switch(mcState)
{
case mcReady: // 关闭输出,上电会对电流进行采集校准,当采样校准结束标志置1且启动指令置1后,才跳转到mcInit
Motor_Ready();
if((mcCurOffset.OffsetFlag == 1) && (mcSpeedRamp.FlagONOFF == 1)) mcState = mcInit;
break;
case mcInit: // 初始化状态,进入mcCharge状态
Motor_Init();
FOC_Init();
mcState = mcCharge;
mcFocCtrl.State_Count = 0;
// mcState = mcCharge; // 跳入mcCharge状态
// mcFocCtrl.State_Count = Charge_Time;
break;
case mcCharge: // 预充电状态,MCU输出固定频率占空比,预充电结束后,跳入mcTailWind
Motor_Charge();
#if (IPMState == NormalRun) // 正常按电机状态机运行
if( mcFocCtrl.State_Count == 0)
{
//顺逆风检测
if(mcFocCtrl.mcChargeStep == 0)
{
MOE = 0; // 关闭输出
mcState = mcTailWind;
mcFocCtrl.State_Count = 40;
}
//初始位置检测启动
else if(mcFocCtrl.mcChargeStep == 1)
{
MOE = 0;
mcState = mcPosiCheck;
}
// GP07 = 0;
}
#endif
break;
case mcTailWind:
#if (TailWind_Mode == NoTailWind) // 无顺逆风处理的,直接跳入下一个状态
mcState = mcPosiCheck;
McStaSet.SetFlag.PosiCheckSetFlag = 0;
mcFocCtrl.mcPosCheckAngle = 0xffff; // 角度赋初值
#elif (TailWind_Mode == TailWind)
Motor_TailWind();
#endif
break;
case mcPosiCheck:
#if (PosCheckEnable==0) //初始位置检测不使能时初始角度为预定位角度
mcFocCtrl.mcPosCheckAngle = Align_Angle;
mcState = mcAlign;
mcFocCtrl.State_Count = Align_Time;
#else
RPD();
#endif
break;
case mcAlign: // 预定位时间结束后,直接启动; AlignTestMode=1用于初始位置检测调试用
Motor_Align();
#if (AlignTestMode==1)
while(1);
#else
if(mcFocCtrl.State_Count == 0) mcState = mcStart;
#endif
break;
case mcStart: // 配置电机启动参数,进入mcRun状态。
Motor_Open();
break;
case mcPllTect: // 配置电机启动参数,进入mcRun状态。
#if (EstimateAlgorithm == PLL)
Motor_PllStart();
#endif
break;
case mcRun: // 运行状态,若运行状态的给定变为0,进入mcStop状态。
if(mcSpeedRamp.TargetValue == 0)
{
mcState = mcStop;
mcFocCtrl.State_Count = 6000;
// FOC_IQREF = 0;
}
break;
case mcStop:
if((mcFocCtrl.SpeedFlt<Motor_Min_Speed)||(mcFocCtrl.State_Count==0))
{
#if (StopBrakeFlag == 0)
if(mcFocCtrl.mcIqref > POWER_OFF_CURRENT) //小于最小电流
{
mcFocCtrl.mcIqref-= 5;
FOC_IQREF = mcFocCtrl.mcIqref;
PI_UK = mcFocCtrl.mcIqref;
}
else
{
//直接关闭,自由停止
mcState = mcReady;
MOE=0;
FOC_CR1 = 0x00;
/*关闭FOC*/
ClrBit(DRV_CR, FOCEN);
//刹车后再关闭
// MOE = 0;
// FOC_CR1 = 0x00;
// ClrBit(DRV_CR, FOCEN);
// DRV_DR = DRV_ARR+1;
// DRV_CMR &= 0xFFC0;
// DRV_CMR |= 0x015; // 三相下桥臂通,刹车
// ClrBit(DRV_CR, OCS); // OCS = 0, DRV_COMR;OCS = 1, FOC/SVPWM/SPWM
// MOE = 1;
// mcState = mcBrake;
// mcFocCtrl.State_Count = StopWaitTime;
}
#else
if(mcFocCtrl.SpeedFlt < Motor_Stop_Speed) //小于最低速度刹车
{
MOE = 0;
FOC_CR1 = 0x00;
ClrBit(DRV_CR, FOCEN);
DRV_DR = DRV_ARR+1;
DRV_CMR &= 0xFFC0;
DRV_CMR |= 0x015; // 三相下桥臂通,刹车
ClrBit(DRV_CR, OCS); // OCS = 0, DRV_COMR;OCS = 1, FOC/SVPWM/SPWM
MOE = 1;
mcState = mcBrake;
mcFocCtrl.State_Count = StopWaitTime;
}
#endif
}
else if(mcSpeedRamp.TargetValue > 0)
{
mcState = mcRun;
mcFocCtrl.State_Count = 0;
// mcFocCtrl.CtrlMode = 0;
}
break;
case mcBrake:
if(mcFocCtrl.State_Count == 0)
{
mcState = mcReady;
MOE=0;
ClrBit(DRV_CR, FOCEN);
}
break;
case mcFault:
break;
}
}
更多回帖