| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- #include <MyProject.h>
- MotStaM McStaSet;
- /**
- @brief 电机控制状态机
- @warning 电机的状态只能在电机状态控制中切换,禁止在其他地方切换电机状态
- @date 2022-07-14
- */
- void Motor_Control_State(void)
- {
- if (FaultSource != SYS_NO_FAULT)
- { sysState = MOTOR_FAULT; }
- else if ((isCtrlPowOn == false) && (sysState != SYS_READY))
- {
- sysState = MOTOR_STOP;
-
- if (sysState == MOTOR_RUN)
- { mcFocCtrl.State_Count = 1000; }
- }
-
- switch (sysState)
- {
- case SYS_READY:
- if (McStaSet.SetFlag.CalibFlag == 0)
- {
- McStaSet.SetFlag.CalibFlag = 1;
- MOE = 0;
- ClrBit(DRV_CR, FOCEN);
- ClrBit(DRV_CR, DRVEN);
- mcCurOffset.OffsetFlag = 0;
- mcCurOffset.OffsetCount = 0;
- #if ( Shunt_Resistor_Mode == Single_Resistor)
- SetBit(ADC_MASK, CH4EN | CH2EN);
- #else
- SetBit(ADC_MASK, CH4EN | CH2EN | CH1EN | CH0EN);
- #endif
- }
-
- if ((mcCurOffset.OffsetFlag == 1) && isCtrlPowOn)
- { sysState = SYS_INIT; }
-
- break;
-
- case SYS_INIT:
- #if ( Shunt_Resistor_Mode == Single_Resistor)
- ClrBit(ADC_MASK, CH4EN );
- #else
- ClrBit(ADC_MASK, CH4EN | CH1EN | CH0EN);
- #endif
- memset(&mcFocCtrl, 0, sizeof(FOCCTRL));
- memset(&faultCheck, 0, sizeof(Fault_Check_t));
- memset(&estData, 0, sizeof(Estimated_Data_t));
- memset(&loopCtrl, 0, sizeof(Loop_Control_t));
- //缺相变量清零
- McStaSet.SetMode = 0;
- Power_Currt = 0;
- #if (CHARGE_EN)
- mcFocCtrl.State_Count = CHARGE_TIME;
- sysState = PRE_DRIVER_CHARGE;
- #else
- {
- #if (ALIGN_MOME != ALIGN_DSIABLE)
- mcFocCtrl.mcPosCheckAngle = Align_Angle1;
- sysState = MOTOR_ALIGN;
- mcFocCtrl.State_Count = AlignAll_Time;
- #else
- sysState = MOTOR_START;
- #endif
- }
- #endif
- break;
-
- case PRE_DRIVER_CHARGE:
- Motor_Charge();
-
- if (mcFocCtrl.State_Count == 0)
- {
- MOE = 0;
- #if (ALIGN_MOME != ALIGN_DSIABLE)
- mcFocCtrl.mcPosCheckAngle = Align_Angle1;
- sysState = MOTOR_ALIGN;
- mcFocCtrl.State_Count = AlignAll_Time;
- #else
- sysState = MOTOR_START;
- #endif
- }
-
- break;
-
- case MOTOR_ALIGN:
- Motor_Align();
- #if (ALIGN_MOME == ALIGN_TEST)
-
- while (1);
-
- #else
-
- if (mcFocCtrl.State_Count > (Align_Time1 + Align_Time2 + Align_Time3) )
- {
- mcFocCtrl.CurrentAlignStatus = 0;
- FOC__THETA = Align_Angle1;
- FOC_IQREF = IQ_Align_CURRENT * ((float)(AlignAll_Time - mcFocCtrl.State_Count) / AlignRamp_Time);
- }
- else if (mcFocCtrl.State_Count > (Align_Time2 + Align_Time3))
- {
- mcFocCtrl.CurrentAlignStatus = 1;
- FOC__THETA = Align_Angle2;
- FOC_IQREF = IQ_Align_CURRENT;
- }
- else if (mcFocCtrl.State_Count > (Align_Time3))
- {
- mcFocCtrl.CurrentAlignStatus = 2;
- mcFocCtrl.AngleProcess = Angle_AngleK * (Align_Time2 + Align_Time3 - mcFocCtrl.State_Count);
- mcFocCtrl.AngleStart = Align_Angle2 + mcFocCtrl.AngleProcess;
- FOC__THETA = mcFocCtrl.AngleStart;
- }
- else
- {
- mcFocCtrl.CurrentAlignStatus = 2;
- sysState = MOTOR_START;
- }
-
- #endif
- break;
-
- case MOTOR_START:
- Motor_Static_Open();
- sysState = MOTOR_RUN;
- break;
-
- case MOTOR_STOP:
- if ((estData.ActSpeedFlt < MOTOR_SPEED_STOP_RPM) && (mcFocCtrl.State_Count == 0))
- {
- sysState = SYS_READY;
- ClrBit(DRV_CR, FOCEN);
- ClrBit(DRV_CR, DRVEN);
- MOE = 0;
- }
-
- break;
-
- case MOTOR_FAULT:
- if (FaultSource == SYS_NO_FAULT)
- { sysState = SYS_READY; }
- else
- {
- DRV_CMR &= 0xFFC0;
- ClrBit(DRV_CR, FOCEN);
- MOE = 0;
- }
-
- break;
- }
- }
- /**
- @function Get_LPF_Value
- @brief 数据滤波处理
- @date 2025-12-23
- */
- void Get_LPF_Value(void)
- {
- // 开启AD转换 等待转换结束
- SetBit(ADC_CR, ADCBSY);
-
- while (ReadBit(ADC_CR, ADCBSY));
-
- // 读取AD转换数据
- Power_Currt = (ADC7_DR);
- Power_Currt = Abs_F16(Power_Currt - mcCurOffset.Iw_busOffset);
- estData.ActBusCurr = LPF_Zero_Update(Power_Currt << 2, estData.ActBusCurr, 20);
-
- if (sysState != MOTOR_RUN)
- { estData.BusVoltage = LPF_Zero_Update(ADC2_DR, estData.BusVoltage, LPF_FC(20)); }
- else
- { estData.BusVoltage = FOC__UDCFLT; }
-
- // estData.BusVoltage = LPF_Zero_Update(ADC2_DR, estData.BusVoltage, LPF_FC(20));
- estData.AlongVoltage = LPF_Zero_Update(ADC3_DR, estData.AlongVoltage, LPF_FC(100));
- estData.NTCTemper = LPF_Zero_Update(ADC9_DR, estData.NTCTemper, LPF_FC(20));
-
- // 读取观测器数据
- if ((sysState != SYS_INIT) && (sysState != SYS_READY))
- {
- estData.ActSpeedFlt = LPF_Zero_Update(FOC__EOME, estData.ActSpeedFlt, LPF_FC(30.0));
- estData.UDFlt = LPF_Zero_Update(FOC__UD, estData.UDFlt, LPF_FC(20.0));
- estData.UQFlt = LPF_Zero_Update(FOC__UQ, estData.UQFlt, LPF_FC(20.0));
- estData.IDFlt = LPF_Zero_Update(FOC__ID, estData.IDFlt, LPF_FC(20.0));
- estData.IQFlt = LPF_Zero_Update(FOC__IQ, estData.IQFlt, LPF_FC(20.0));
- }
- else
- { estData.ActSpeedFlt = 0; }
-
- if ((sysState == MOTOR_RUN) || (sysState == MOTOR_STOP))
- {
- estData.Power = LPF_Zero_Update(FOC__POW, estData.Power, LPF_FC(5.0));
- estData.BackEMF = FOC__EMF;
- estData.BusCurr = Sqrt_alpbet(FOC__IA, FOC__IBET);
- }
- else
- { estData.Power = 0; }
-
- // 保护参数更新
- faultCheck.ActualSpeed = estData.ActSpeedFlt;
- faultCheck.BusVoltage = estData.BusVoltage;
- faultCheck.NTCTemper = estData.NTCTemper;
- faultCheck.Power = estData.Power;
- faultCheck.BackEMF = estData.BackEMF;
- faultCheck.BusCurr = estData.BusCurr;
- }
- /**
- @function Loop_Control
- @brief 环路响应
- @date 2025-12-23
- */
- void Loop_Control(void)
- {
- switch (loopCtrl.LoopState)
- {
- case OPEN_MODE:
- {
- if (estData.ActSpeedFlt > MOTOR_LOOP_RPM)
- {
- // 切入闭环并直接开始第一次运算
- loopCtrl.LoopState = CLOSE_MODE;
- // 切换电流环KPKI
- FOC_QKP = QKP;
- FOC_QKI = QKI;
- FOC_DKP = DKP;
- FOC_DKI = DKI;
- // 禁用D轴PI
- // ClrBit(FOC_CR2,UDD);
- // 参数配置
- loopCtrl.ActualRef = _Q15(2000.0 / MOTOR_SPEED_BASE);
- loopCtrl.Inc = MOTOR_SPEED_INC;
- loopCtrl.Dec = MOTOR_SPEED_DEC;
- // PI计算初始化
- HW_Zero_PI_Init();
- // 弱磁初始化
- #if (Filed_Weaken_En)
- Filed_Weaken_Init();
- #endif
- PI0_UKH = FOC_IQREF;
- }
- }
- break;
-
- case CLOSE_MODE:
- {
- if (++loopCtrl.CalcTime > SPEED_LOOP_TIME)
- {
- loopCtrl.CalcTime = 0;
-
- // 控制命令爬坡 用于实现调速信号之间平滑过渡
- if (loopCtrl.TargetRef > (loopCtrl.ActualRef + loopCtrl.Inc))
- { loopCtrl.ActualRef += loopCtrl.Inc; }
- else if (loopCtrl.TargetRef < (loopCtrl.ActualRef - loopCtrl.Dec))
- { loopCtrl.ActualRef -= loopCtrl.Dec;}
- else
- { loopCtrl.ActualRef = loopCtrl.TargetRef ;}
-
- // 环路计算
- estData.ISRef = HW_Zero_Calc(loopCtrl.ActualRef - estData.ActSpeedFlt);
- // 弱磁控制
- #if (Filed_Weaken_En)
- fieldWeaken.ISRef = estData.ISRef;
- File_Weaken_Control();
- estData.IDRef = fieldWeaken.IDRef;
- estData.IQRef = fieldWeaken.IQRef;
- #else
- estData.IDRef = 0;
- estData.IQRef = estData.ISRef;
- #endif
- // 电流给定
- FOC_IQREF = estData.IQRef;
- FOC_IDREF = estData.IDRef;
- }
- }
- break;
- }
- }
- /**
- @brief 对变量取16位的绝对值
- @param[in] value
- @return 绝对值
- @date 2022-07-13
- */
- uint16_t Abs_F16(int16_t value)
- {
- if (value < 1)
- { return (-value); }
- else
- { return (value); }
- }
- /**
- @brief 启动ATO爬坡函数,用于静止启动时候对ATO进行爬坡,提高启动可靠性
- @date 2022-07-14
- */
- void ATORamp(void)
- {
- if (mcFocCtrl.State_Count == (ATO_RAMP_PERIOD << 2))
- {
- FOC_EKP = OBSW_KP_GAIN_RUN1; // 估算器里的PI的KP
- FOC_EKI = OBSW_KI_GAIN_RUN1; // 估算器里的PI的KI
- }
- else if (mcFocCtrl.State_Count == ((ATO_RAMP_PERIOD << 1) + ATO_RAMP_PERIOD))
- {
- FOC_EKP = OBSW_KP_GAIN_RUN2; // 估算器里的PI的KP
- FOC_EKI = OBSW_KI_GAIN_RUN2; // 估算器里的PI的KI
- }
- else if (mcFocCtrl.State_Count == (ATO_RAMP_PERIOD << 1))
- {
- FOC_EKP = OBSW_KP_GAIN_RUN3; // 估算器里的PI的KP
- FOC_EKI = OBSW_KI_GAIN_RUN3; // 估算器里的PI的KI
- }
- else if (mcFocCtrl.State_Count <= ATO_RAMP_PERIOD && mcFocCtrl.Flg_ATORampEnd == 0)
- {
- FOC_EKP = OBSW_KP_GAIN_RUN4; // 估算器里的PI的KP
- FOC_EKI = OBSW_KI_GAIN_RUN4; // 估算器里的PI的KI
- mcFocCtrl.Flg_ATORampEnd = 1; // ATO 爬坡结束
- }
- }
|