MotorControl.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /**
  2. * @copyright None
  3. * @file MotorControl.c
  4. * @author Comment Vivre
  5. * @date 2024-08-26
  6. * @brief 电机状态机切换
  7. */
  8. #include <MyProject.h>
  9. MotStateType data mcState;
  10. MotStaM McStaSet;
  11. /**
  12. @brief 电机控制状态机
  13. @warning 电机的状态只能在电机状态控制中切换,禁止在其他地方切换电机状态
  14. @date 2022-07-14
  15. */
  16. void FiniteStateManger(void)
  17. {
  18. // 故障下状态调整
  19. if (mcFaultSource != FaultNoSource)
  20. { mcState = mcFault; }
  21. // 关机命令下状态调整
  22. else if ((mcState == mcInit) || (mcState == mcCharge)
  23. || (mcState == mcTailWind) || (mcState == mcPosiCheck)
  24. || (mcState == mcAlign) || (mcState == mcStart))
  25. {
  26. if (isCtrlPowOn == false)
  27. { mcState = mcStop; }
  28. }
  29. // 状态机执行
  30. switch (mcState)
  31. {
  32. case mcReady:
  33. {
  34. Motor_Ready();
  35. if ((mcCurOffset.OffsetFlag == 1) && (isCtrlPowOn))
  36. {
  37. mcState = mcInit;
  38. mcCurOffset.OffsetFlag = 0;
  39. mcCurOffset.OffsetCount = 0; // 偏置电压采集计数
  40. }
  41. break;
  42. }
  43. case mcInit:
  44. {
  45. if (mcCurOffset.OffsetFlag == 1)
  46. {
  47. Motor_Init();
  48. #if (CHARGE_EN == Enable)
  49. {
  50. mcFocCtrl.State_Count = CHARGE_TIME;
  51. mcState = mcCharge; // 跳入mcCharge状态
  52. }
  53. #else
  54. {
  55. #if (TAILWIND_MODE == NoTailWind)
  56. {
  57. #if (ALIGN_MOME != ALIGN_DSIABLE)
  58. {
  59. mcFocCtrl.mcPosCheckAngle = Align_Angle;
  60. mcState = mcAlign;
  61. mcFocCtrl.State_Count = Align_Time;
  62. }
  63. #else
  64. mcState = mcStart;
  65. #endif
  66. }
  67. #else
  68. {
  69. mcFocCtrl.State_Count = TAILWIND_TIME; // 顺逆风判断时间
  70. mcState = mcTailWind;
  71. }
  72. #endif
  73. }
  74. #endif
  75. }
  76. break;
  77. }
  78. case mcCharge:
  79. {
  80. Motor_Charge();
  81. #if (IPMTEST == Enable)
  82. #else
  83. if (mcFocCtrl.State_Count == 0)
  84. {
  85. MOE = 0; // 关闭输出
  86. #if (TAILWIND_MODE == NoTailWind)
  87. {
  88. #if (ALIGN_MOME != ALIGN_DSIABLE)
  89. mcFocCtrl.mcPosCheckAngle = Align_Angle;
  90. mcState = mcAlign;
  91. mcFocCtrl.State_Count = Align_Time;
  92. #else
  93. mcState = mcStart;
  94. #endif
  95. }
  96. #else
  97. mcFocCtrl.State_Count = TAILWIND_TIME; // 顺逆风判断时间
  98. mcState = mcTailWind;
  99. #endif
  100. }
  101. #endif
  102. break;
  103. }
  104. #if (TAILWIND_MODE != NoTailWind)
  105. case mcTailWind:
  106. {
  107. Motor_TailWind();
  108. break;
  109. }
  110. #endif
  111. #if (ALIGN_MOME != ALIGN_DSIABLE)
  112. case mcAlign:
  113. {
  114. Motor_Align();
  115. #if (ALIGN_MOME == ALIGN_TEST)
  116. while (1) ;
  117. #else
  118. {
  119. if (mcFocCtrl.State_Count == 0)
  120. { mcState = mcStart; }
  121. }
  122. #endif
  123. break;
  124. }
  125. #endif
  126. case mcStart:
  127. {
  128. if (mcFocCtrl.Start_Mode == TAILWIND_START) // 顺风启动
  129. {
  130. #if (TAILWIND_MODE == BEMFMethod)
  131. mcState = mcRun;
  132. #elif (TAILWIND_MODE == RSDMethod)
  133. mcState = mcRun;
  134. #elif (TAILWIND_MODE == FOCMethod)
  135. {
  136. Motor_FocTailWind_Open();
  137. mcState = mcRun;
  138. }
  139. #endif
  140. }
  141. else if (mcFocCtrl.Start_Mode == HEADWIND_START) // 逆风启动
  142. {
  143. if (mcFocCtrl.State_Count > 0) // 逆风启动刹车过程
  144. {
  145. // 配置刹车代码
  146. MC_Break();
  147. }
  148. else
  149. {
  150. mcFocCtrl.State_Count = 200; // 顺逆风判断时间
  151. mcState = mcReady; // 刹车结束 切回顺逆风检测
  152. }
  153. }
  154. else // 静止启动
  155. {
  156. Motor_Static_Open();
  157. mcState = mcRun;
  158. }
  159. break;
  160. }
  161. case mcRun:
  162. {
  163. if (isCtrlPowOn == false)
  164. {
  165. mcState = mcStop;
  166. mcFocCtrl.State_Count = 5; // 单位:1ms
  167. }
  168. break;
  169. }
  170. case mcStop:
  171. {
  172. MC_Stop();
  173. break;
  174. }
  175. case mcBrake:
  176. {
  177. if (mcFocCtrl.State_Count == 0)
  178. {
  179. fault.Voltage.VoltDetecBraketDuty = 0;
  180. fault.Voltage.FlagBrakeInit = 0;
  181. MOE = 0;
  182. DRV_OUT = 0x00;
  183. ClrBit(DRV_CR, FOCEN);
  184. mcState = mcReady;
  185. mcFocCtrl.State_Count = 10;
  186. }
  187. break;
  188. }
  189. case mcFault:
  190. {
  191. // 欠压保护处理函数
  192. if (mcFaultSource == FaultUnderVoltageDC)
  193. { UnderProcess(); }
  194. else
  195. {
  196. MOE = 0;
  197. ClrBit(DRV_CR, FOCEN); // 关闭FOC
  198. if (mcFaultSource == FaultNoSource)
  199. { mcState = mcReady; }
  200. }
  201. break;
  202. }
  203. default:
  204. {
  205. mcState = mcReady;
  206. break;
  207. }
  208. }
  209. }
  210. /**
  211. @brief 默认1ms周期服务函数,运行信号采样,调速信号处理,闭环控制,故障检测,ATO爬坡函数
  212. 该函数运行于大循环中,由SYSTICK定时器间隔1ms触发运行。
  213. @date 2022-07-14
  214. */
  215. void TickCycle(void)
  216. {
  217. #if (VoltageCompensationEn == 1)
  218. {
  219. if (VoltageComp.cpscnt <= VoltageCompensationDelayCnt)
  220. { SetBit(ADC_CR, ADCBSY);}
  221. }
  222. #else
  223. // 使能ADC的DCBUS采样
  224. SetBit(ADC_CR, ADCBSY);
  225. #endif
  226. if ((mcState != mcInit) && (mcState != mcReady))
  227. {
  228. // 速度滤波
  229. mcFocCtrl.SpeedFlt = LPFFunction(FOC__EOME, mcFocCtrl.SpeedFlt, 50); // 注意低通滤波器系数范围为0---127
  230. mcFocCtrl.EMFsquare = Sqrt_alpbet(FOC__EALP, FOC__EBET);
  231. mcFocCtrl.Is = Sqrt_alpbet(FOC__IA, FOC__IBET);
  232. if (mcState == mcRun)
  233. { mcFocCtrl.Power = LPFFunction(FOC__POW << 3, mcFocCtrl.Power, 10); }
  234. }
  235. else
  236. {
  237. mcFocCtrl.SpeedFlt = 0;
  238. mcFocCtrl.Power = 0;
  239. }
  240. // DCbus的采样获取值并滤波
  241. #if (VoltageCompensationEn == 1)
  242. {
  243. // 未进入电压补偿之前在1ms中断里面采集电压,进入之后在载波中断里面采集电压
  244. if (VoltageComp.cpscnt <= VoltageCompensationDelayCnt)
  245. { mcFocCtrl.mcDcbusFlt = LPFFunction(ADC2_DR, mcFocCtrl.mcDcbusFlt, 50); }
  246. if ((mcFocCtrl.CtrlMode == 1) && (mcState == mcRun) && (mcFaultSource == FaultNoSource)) // 进入速度环后进行延时计数
  247. {
  248. if (VoltageComp.cpscnt < VoltageCompensationDelayCnt + 10)
  249. { VoltageComp.cpscnt++; }
  250. else
  251. { VoltageComp.cpscnt = VoltageCompensationDelayCnt + 10; }
  252. }
  253. else
  254. { VoltageComp.cpscnt = 0; }
  255. // 母线电压平均值
  256. BusAverageVoltage();
  257. }
  258. #else
  259. mcFocCtrl.mcDcbusFlt = LPFFunction(ADC2_DR, mcFocCtrl.mcDcbusFlt, 50); // 母线电压值滤波
  260. #endif
  261. mcFocCtrl.NTCValue = LPFFunction(ADC8_DR, mcFocCtrl.NTCValue, 100);
  262. mcFocCtrl.SREFValue = LPFFunction(ADC9_DR, mcFocCtrl.SREFValue, 100);
  263. mcFocCtrl.UqFlt = LPFFunction(FOC__UQ, mcFocCtrl.UqFlt, 50);
  264. mcFocCtrl.UdFlt = LPFFunction(FOC__UD, mcFocCtrl.UdFlt, 50);
  265. // 获取调速信号,不同调速模式(PWMMODE,NONEMODE,SREFMODE)的目标值修改
  266. GetTargetRef();
  267. // 启动ATO控制,环路响应,如速度环、转矩环、功率环等
  268. LoopResponse();
  269. //故障保护函数功能,如过欠压保护、启动保护、缺相、堵转等
  270. Fault_Detection();
  271. // 电机启动ATO爬坡函数处理
  272. ATORamp();
  273. // 电机状态机的时序处理
  274. if (mcFocCtrl.State_Count > 0)
  275. { mcFocCtrl.State_Count--; }
  276. }