MotorControl.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. #include <MyProject.h>
  2. MotStaM McStaSet;
  3. /**
  4. @brief 电机控制状态机
  5. @warning 电机的状态只能在电机状态控制中切换,禁止在其他地方切换电机状态
  6. @date 2022-07-14
  7. */
  8. void Motor_Control_State(void)
  9. {
  10. if (FaultSource != SYS_NO_FAULT)
  11. { sysState = MOTOR_FAULT; }
  12. else if ((isCtrlPowOn == false) && (sysState != SYS_READY))
  13. {
  14. sysState = MOTOR_STOP;
  15. if (sysState == MOTOR_RUN)
  16. { mcFocCtrl.State_Count = 3000; }
  17. }
  18. switch (sysState)
  19. {
  20. case SYS_READY:
  21. if (McStaSet.SetFlag.CalibFlag == 0)
  22. {
  23. McStaSet.SetFlag.CalibFlag = 1;
  24. MOE = 0;
  25. ClrBit(DRV_CR, FOCEN);
  26. ClrBit(DRV_CR, DRVEN);
  27. mcCurOffset.OffsetFlag = 0;
  28. mcCurOffset.OffsetCount = 0;
  29. #if ( Shunt_Resistor_Mode == Single_Resistor)
  30. SetBit(ADC_MASK, CH4EN | CH2EN);
  31. #else
  32. SetBit(ADC_MASK, CH4EN | CH2EN | CH1EN | CH0EN);
  33. #endif
  34. }
  35. if ((mcCurOffset.OffsetFlag == 1) && isCtrlPowOn)
  36. { sysState = SYS_INIT; }
  37. break;
  38. case SYS_INIT:
  39. #if ( Shunt_Resistor_Mode == Single_Resistor)
  40. ClrBit(ADC_MASK, CH4EN );
  41. #else
  42. ClrBit(ADC_MASK, CH4EN | CH1EN | CH0EN);
  43. #endif
  44. memset(&mcFocCtrl, 0, sizeof(FOCCTRL));
  45. memset(&faultCheck, 0, sizeof(Fault_Check_t));
  46. memset(&estData, 0, sizeof(Estimated_Data_t));
  47. memset(&loopCtrl, 0, sizeof(Loop_Control_t));
  48. //缺相变量清零
  49. McStaSet.SetMode = 0;
  50. Power_Currt = 0;
  51. #if (CHARGE_EN)
  52. mcFocCtrl.State_Count = CHARGE_TIME;
  53. sysState = PRE_DRIVER_CHARGE;
  54. #else
  55. {
  56. #if (ALIGN_MOME != ALIGN_DSIABLE)
  57. mcFocCtrl.mcPosCheckAngle = Align_Angle1;
  58. sysState = MOTOR_ALIGN;
  59. mcFocCtrl.State_Count = AlignAll_Time;
  60. #else
  61. sysState = MOTOR_START;
  62. #endif
  63. }
  64. #endif
  65. break;
  66. case PRE_DRIVER_CHARGE:
  67. Motor_Charge();
  68. if (mcFocCtrl.State_Count == 0)
  69. {
  70. MOE = 0;
  71. #if (ALIGN_MOME != ALIGN_DSIABLE)
  72. mcFocCtrl.mcPosCheckAngle = Align_Angle1;
  73. sysState = MOTOR_ALIGN;
  74. mcFocCtrl.State_Count = AlignAll_Time;
  75. #else
  76. sysState = MOTOR_START;
  77. #endif
  78. }
  79. break;
  80. case MOTOR_ALIGN:
  81. Motor_Align();
  82. #if (ALIGN_MOME == ALIGN_TEST)
  83. while (1);
  84. #else
  85. if (mcFocCtrl.State_Count > (Align_Time1 + Align_Time2 + Align_Time3) )
  86. {
  87. mcFocCtrl.CurrentAlignStatus = 0;
  88. FOC__THETA = Align_Angle1;
  89. FOC_IQREF = IQ_Align_CURRENT * ((float)(AlignAll_Time - mcFocCtrl.State_Count) / AlignRamp_Time);
  90. }
  91. else if (mcFocCtrl.State_Count > (Align_Time2 + Align_Time3))
  92. {
  93. mcFocCtrl.CurrentAlignStatus = 1;
  94. FOC__THETA = Align_Angle2;
  95. FOC_IQREF = IQ_Align_CURRENT;
  96. }
  97. else if (mcFocCtrl.State_Count > (Align_Time3))
  98. {
  99. mcFocCtrl.CurrentAlignStatus = 2;
  100. mcFocCtrl.AngleProcess = Angle_AngleK * (Align_Time2 + Align_Time3 - mcFocCtrl.State_Count);
  101. mcFocCtrl.AngleStart = Align_Angle2 + mcFocCtrl.AngleProcess;
  102. FOC__THETA = mcFocCtrl.AngleStart;
  103. }
  104. else
  105. {
  106. mcFocCtrl.CurrentAlignStatus = 2;
  107. sysState = MOTOR_START;
  108. }
  109. #endif
  110. break;
  111. case MOTOR_START:
  112. Motor_Static_Open();
  113. sysState = MOTOR_RUN;
  114. break;
  115. case MOTOR_STOP:
  116. if ((estData.ActSpeedFlt < MOTOR_SPEED_STOP_RPM) && (mcFocCtrl.State_Count == 0))
  117. {
  118. sysState = SYS_READY;
  119. ClrBit(DRV_CR, FOCEN);
  120. ClrBit(DRV_CR, DRVEN);
  121. MOE = 0;
  122. }
  123. break;
  124. case MOTOR_FAULT:
  125. if (FaultSource == SYS_NO_FAULT)
  126. { sysState = SYS_READY; }
  127. else
  128. {
  129. DRV_CMR &= 0xFFC0;
  130. ClrBit(DRV_CR, FOCEN);
  131. MOE = 0;
  132. }
  133. break;
  134. }
  135. }
  136. /**
  137. @function Get_LPF_Value
  138. @brief 数据滤波处理
  139. @date 2025-12-23
  140. */
  141. void Get_LPF_Value(void)
  142. {
  143. // 开启AD转换 等待转换结束
  144. SetBit(ADC_CR, ADCBSY);
  145. while (ReadBit(ADC_CR, ADCBSY));
  146. // 读取AD转换数据
  147. Power_Currt = (ADC7_DR);
  148. Power_Currt = Abs_F16(Power_Currt - mcCurOffset.Iw_busOffset);
  149. estData.ActBusCurr = LPF_Zero_Update(Power_Currt << 2, estData.ActBusCurr, 20);
  150. if (sysState != MOTOR_RUN)
  151. { estData.BusVoltage = LPF_Zero_Update(ADC2_DR, estData.BusVoltage, LPF_FC(20)); }
  152. else
  153. { estData.BusVoltage = FOC__UDCFLT; }
  154. // estData.BusVoltage = LPF_Zero_Update(ADC2_DR, estData.BusVoltage, LPF_FC(20));
  155. estData.AlongVoltage = LPF_Zero_Update(ADC3_DR, estData.AlongVoltage, LPF_FC(100));
  156. estData.NTCTemper = LPF_Zero_Update(ADC9_DR, estData.NTCTemper, LPF_FC(20));
  157. // 读取观测器数据
  158. if ((sysState != SYS_INIT) && (sysState != SYS_READY))
  159. {
  160. estData.ActSpeedFlt = LPF_Zero_Update(FOC__EOME, estData.ActSpeedFlt, LPF_FC(30.0));
  161. estData.UDFlt = LPF_Zero_Update(FOC__UD, estData.UDFlt, LPF_FC(20.0));
  162. estData.UQFlt = LPF_Zero_Update(FOC__UQ, estData.UQFlt, LPF_FC(20.0));
  163. estData.IDFlt = LPF_Zero_Update(FOC__ID, estData.IDFlt, LPF_FC(20.0));
  164. estData.IQFlt = LPF_Zero_Update(FOC__IQ, estData.IQFlt, LPF_FC(20.0));
  165. }
  166. else
  167. { estData.ActSpeedFlt = 0; }
  168. if ((sysState == MOTOR_RUN) || (sysState == MOTOR_STOP))
  169. {
  170. estData.Power = LPF_Zero_Update(FOC__POW, estData.Power, LPF_FC(5.0));
  171. estData.BackEMF = FOC__EMF;
  172. estData.BusCurr = Sqrt_alpbet(FOC__IA, FOC__IBET);
  173. }
  174. else
  175. { estData.Power = 0; }
  176. // 保护参数更新
  177. faultCheck.ActualSpeed = estData.ActSpeedFlt;
  178. faultCheck.BusVoltage = estData.BusVoltage;
  179. faultCheck.NTCTemper = estData.NTCTemper;
  180. faultCheck.Power = estData.Power;
  181. faultCheck.BackEMF = estData.BackEMF;
  182. faultCheck.BusCurr = estData.BusCurr;
  183. }
  184. /**
  185. @function Loop_Control
  186. @brief 环路响应
  187. @date 2025-12-23
  188. */
  189. void Loop_Control(void)
  190. {
  191. switch (loopCtrl.State)
  192. {
  193. case OPEN_MODE:
  194. {
  195. if (estData.ActSpeedFlt > MOTOR_LOOP_RPM)
  196. {
  197. // 切入闭环并直接开始第一次运算
  198. loopCtrl.State = CLOSE_MODE;
  199. // 切换电流环KPKI
  200. FOC_QKP = QKP;
  201. FOC_QKI = QKI;
  202. FOC_DKP = DKP;
  203. FOC_DKI = DKI;
  204. // 禁用D轴PI
  205. // ClrBit(FOC_CR2,UDD);
  206. // 参数配置
  207. loopCtrl.ActualRef = _Q15(2000.0 / MOTOR_SPEED_BASE);
  208. loopCtrl.Inc = MOTOR_SPEED_INC;
  209. loopCtrl.Dec = MOTOR_SPEED_DEC;
  210. // PI计算初始化
  211. HW_Zero_PI_Init();
  212. // 弱磁初始化
  213. #if (Filed_Weaken_En)
  214. Filed_Weaken_Init();
  215. #endif
  216. PI0_UKH = FOC_IQREF;
  217. }
  218. }
  219. break;
  220. case CLOSE_MODE:
  221. {
  222. if (++loopCtrl.CalcTime > SPEED_LOOP_TIME)
  223. {
  224. loopCtrl.CalcTime = 0;
  225. // 控制命令爬坡 用于实现调速信号之间平滑过渡
  226. if (loopCtrl.TargetRef > (loopCtrl.ActualRef + loopCtrl.Inc))
  227. { loopCtrl.ActualRef += loopCtrl.Inc; }
  228. else if (loopCtrl.TargetRef < (loopCtrl.ActualRef - loopCtrl.Dec))
  229. { loopCtrl.ActualRef -= loopCtrl.Dec;}
  230. else
  231. { loopCtrl.ActualRef = loopCtrl.TargetRef ;}
  232. // 环路计算
  233. estData.ISRef = HW_Zero_Calc(loopCtrl.ActualRef - estData.ActSpeedFlt);
  234. // 弱磁控制
  235. #if (Filed_Weaken_En)
  236. fieldWeaken.ISRef = estData.ISRef;
  237. File_Weaken_Control();
  238. estData.IDRef = fieldWeaken.IDRef;
  239. estData.IQRef = fieldWeaken.IQRef;
  240. #else
  241. estData.IDRef = 0;
  242. estData.IQRef = estData.ISRef;
  243. #endif
  244. // 电流给定
  245. FOC_IQREF = estData.IQRef;
  246. FOC_IDREF = estData.IDRef;
  247. }
  248. }
  249. break;
  250. }
  251. }