FocControl.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #include <Myproject.h>
  2. MotStaType mcState;
  3. MotStaM McStaSet;
  4. /**
  5. @function Motor_Control_State
  6. @brief 电机控制状态机 负责状态跳转
  7. @date 2025-11-03
  8. */
  9. void Motor_Control_State(void)
  10. {
  11. // 故障直接跳转Fault
  12. if (mcFaultSource != FaultNoSource)
  13. { mcState = mcFault; }
  14. // 非Ready状态检测到关机信号跳转Stop
  15. else if ((isCtrlPowOn == false) && (mcState != mcReady))
  16. {
  17. // 若当前为Run 配置停机时间再跳转Stop
  18. if (mcState == mcRun)
  19. { mcFocCtrl.State_Count = 30000; }
  20. mcState = mcStop;
  21. }
  22. switch (mcState)
  23. {
  24. case mcReady:
  25. {
  26. if (mcCurOffset.CalibFlag == 0)
  27. {
  28. mcCurOffset.CalibFlag = 1;
  29. ClrBit(DRV_CR, FOCEN);
  30. MOE = 0;
  31. SetBit(ADC_MASK, CH1EN | CH0EN);
  32. mcCurOffset.OffsetCount = 0;
  33. mcCurOffset.OffsetFlag = 0;
  34. }
  35. if (mcCurOffset.OffsetFlag && isCtrlPowOn)
  36. {
  37. mcState = mcInit;
  38. ClrBit(DRV_CR, DRVEN);
  39. _nop_(); _nop_(); _nop_(); _nop_();
  40. SetBit(DRV_CR, DRVEN);
  41. }
  42. break;
  43. }
  44. case mcInit:
  45. {
  46. //if ((mcFocCtrl.mcDcbusFlt > _Q15(Under_Protect_Voltage / HW_BOARD_VOLT_MAX)))
  47. {
  48. // 关闭软件电流采样的ADC
  49. ClrBit(ADC_MASK, CH1EN | CH0EN);
  50. mcFaultSource = 0;
  51. memset(&mcFaultDect, 0, sizeof(FaultVarible));
  52. memset(&mcFocCtrl, 0, sizeof(FOCCTRL));
  53. mcFocCtrl.mcDcbus_chazhi = 32760;
  54. McStaSet.SetMode = 0;
  55. memset(&VoltageComp, 0, sizeof(VOLCOMP));
  56. // PI控制器初始化
  57. HW_Zero_PI_Init();
  58. HW_One_PI_Init();
  59. #if (FiledWeakenCompEnable)
  60. memset(&mcFieldWeaken, 0, sizeof(FieldWeakeningTypeDef));
  61. #endif
  62. // 此模块不需要预充电
  63. #if 0
  64. mcState = mcCharge;
  65. mcFocCtrl.ChargeStep = 0;
  66. mcFocCtrl.State_Count = 0;
  67. #else
  68. mcState = mcAlign;
  69. mcFocCtrl.State_Count = Align_Time;
  70. #endif
  71. }
  72. break;
  73. }
  74. case mcCharge:
  75. {
  76. switch (mcFocCtrl.ChargeStep)
  77. {
  78. case 0:
  79. {
  80. // 配置占空比
  81. DRV_DR = Calib_Duty * DRV_ARR;
  82. // DRV_CTL:PWM来源选择
  83. // OCS = 0, DRV_COMR
  84. // OCS = 1, FOC/SVPWM/SPWM
  85. ClrBit(DRV_CR, OCS);
  86. mcFocCtrl.ChargeStep = 1;
  87. mcFocCtrl.State_Count = 30;
  88. break;
  89. }
  90. // U相下桥臂通
  91. case 1:
  92. {
  93. DRV_CMR |= 0x01;
  94. MOE = 1;
  95. break;
  96. }
  97. // V相下桥臂导通
  98. case 2:
  99. {
  100. DRV_CMR |= 0x04;
  101. break;
  102. }
  103. // W相下桥臂导通
  104. case 3:
  105. {
  106. DRV_CMR |= 0x10;
  107. break;
  108. }
  109. case 4:
  110. {
  111. #if (1)
  112. DRV_CMR |= 0x3F;
  113. #else
  114. MOE = 0;
  115. mcState = mcAlign;
  116. mcFocCtrl.State_Count = Align_Time;
  117. #endif
  118. break;
  119. }
  120. }
  121. if ((mcFocCtrl.State_Count == 0) && (mcFocCtrl.ChargeStep != 4 ))
  122. {
  123. mcFocCtrl.ChargeStep ++;
  124. mcFocCtrl.State_Count = 30;
  125. }
  126. break;
  127. }
  128. case mcAlign: // 预定位时间结束后,直接启动; AlignTestMode=1用于初始位置检测调试用
  129. {
  130. Motor_Align();
  131. #if (AlignTestMode)
  132. {
  133. while (1);
  134. }
  135. #endif
  136. break;
  137. }
  138. case mcStart: // 配置电机启动参数,进入mcRun状态。
  139. {
  140. Motor_Open();
  141. break;
  142. }
  143. case mcRun: // 运行状态,若运行状态的给定变为0,进入mcStop状态。
  144. {
  145. break;
  146. }
  147. case mcStop:
  148. {
  149. #if (StopBrakeFlag == 0)
  150. {
  151. mcState = mcReady;
  152. FOC_CR1 = 0x00;
  153. ClrBit(DRV_CR, FOCEN); //关闭FOC
  154. MOE = 0;
  155. }
  156. #else
  157. if (motorControl.ActualSpeed < MOTOR_STOP_SPEED)
  158. {
  159. MOE = 0;
  160. FOC_CR1 = 0x00;
  161. ClrBit(DRV_CR, FOCEN);
  162. DRV_DR = DRV_ARR + 1;
  163. DRV_CMR = 0x00;
  164. DRV_CMR |= 0x015; // 三相下桥臂通,刹车
  165. ClrBit(DRV_CR, OCS); // OCS = 0, DRV_COMR;OCS = 1, FOC/SVPWM/SPWM
  166. MOE = 1;
  167. mcState = mcBrake;
  168. mcFocCtrl.State_Count = StopWaitTime;
  169. }
  170. #endif
  171. break;
  172. }
  173. case mcBrake:
  174. {
  175. if (isCtrlPowOn)
  176. {
  177. mcState = mcReady;
  178. mcFocCtrl.State_Count = 0; //单位:1ms 强制关机时间
  179. }
  180. else if (mcFocCtrl.State_Count == 0)
  181. {
  182. mcState = mcReady;
  183. MOE = 0;
  184. ClrBit(DRV_CR, FOCEN);
  185. }
  186. break;
  187. }
  188. case mcFault:
  189. {
  190. if (mcFaultSource == FaultNoSource)
  191. { mcState = mcReady;}
  192. break;
  193. }
  194. default:
  195. {
  196. mcState = mcReady;
  197. break;
  198. }
  199. }
  200. }
  201. /**
  202. @function Tick_Task
  203. @brief 周期任务
  204. @date 2025-11-03
  205. */
  206. void Tick_Task(void)
  207. {
  208. if ((mcState == mcStart) || (mcState == mcRun) || (mcState == mcStop))
  209. {
  210. mcFocCtrl.Powerlpf = LPF_Zero_Update(FOC__POW, mcFocCtrl.Powerlpf, LPF_K(1.0));
  211. mcFocCtrl.IDQFlt = LPF_Zero_Update(mcCurVarible.Max_is, mcFocCtrl.IDQFlt, LPF_K(1.0));
  212. mcFocCtrl.UDFlt = LPF_Zero_Update(FOC__UD, mcFocCtrl.UDFlt, LPF_K(30.0)); //LPF_K(30.0)
  213. mcFocCtrl.UQFlt = LPF_Zero_Update(FOC__UQ, mcFocCtrl.UQFlt, LPF_K(30.0)); //LPF_K(30.0)
  214. motorControl.ActualSpeed = LPF_Zero_Update(FOC__EOME, motorControl.ActualSpeed, LPF_K(71.0));
  215. motorControl.BackEMF = LPF_Zero_Update(FOC__EMF, motorControl.BackEMF, LPF_K(5.0));
  216. if (mcFocCtrl.Powerlpf <= 0)
  217. {mcFocCtrl.Powerlpf = 0;}
  218. }
  219. else
  220. {
  221. mcFocCtrl.IDQFlt = 0;
  222. mcFocCtrl.Powerlpf = 0;
  223. motorControl.ActualSpeed = 0;
  224. motorControl.BackEMF = 0;
  225. }
  226. // StarRampDealwith();
  227. }