FocControl.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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 (McStaSet.SetFlag.CalibFlag == 0)
  27. {
  28. McStaSet.SetFlag.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 FOC模块会自动调用相应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. HW_Zero_PI_Init();
  57. HW_One_PI_Init();
  58. #if (FiledWeakenCompEnable)
  59. memset(&mcFieldWeaken, 0, sizeof(FieldWeakeningTypeDef));
  60. #endif
  61. // 此模块不需要预充电
  62. mcState = mcCharge;
  63. }
  64. break;
  65. }
  66. case mcCharge:
  67. {
  68. if ((mcFocCtrl.State_Count == 0) && (mcFocCtrl.ChargeStep !=5 ))
  69. {
  70. mcFocCtrl.ChargeStep ++;
  71. mcFocCtrl.State_Count = 30;
  72. #if (1)
  73. if (mcFocCtrl.ChargeStep == 4)
  74. { mcFocCtrl.ChargeStep = 5; }
  75. #endif
  76. }
  77. switch (mcFocCtrl.ChargeStep)
  78. {
  79. case 0:
  80. {
  81. // 配置占空比
  82. DRV_DR = Calib_Duty * DRV_ARR;
  83. // DRV_CTL:PWM来源选择
  84. // OCS = 0, DRV_COMR
  85. // OCS = 1, FOC/SVPWM/SPWM
  86. ClrBit(DRV_CR, OCS);
  87. mcFocCtrl.ChargeStep = 1;
  88. mcFocCtrl.State_Count = 30;
  89. break;
  90. }
  91. // U相下桥臂通
  92. case 1:
  93. {
  94. DRV_CMR |= 0x01;
  95. MOE = 1;
  96. break;
  97. }
  98. // V相下桥臂导通
  99. case 2:
  100. {
  101. DRV_CMR |= 0x04;
  102. break;
  103. }
  104. // W相下桥臂导通
  105. case 3:
  106. {
  107. DRV_CMR |= 0x10;
  108. break;
  109. }
  110. case 4:
  111. {
  112. MOE = 0;
  113. mcState = mcCharge;
  114. mcFocCtrl.State_Count = Align_Time;
  115. break;
  116. }
  117. case 5:
  118. {
  119. DRV_CMR |= 0x3F;
  120. break;
  121. }
  122. }
  123. break;
  124. }
  125. case mcAlign: // 预定位时间结束后,直接启动; AlignTestMode=1用于初始位置检测调试用
  126. {
  127. Motor_Align();
  128. #if (AlignTestMode)
  129. {
  130. while (1);
  131. }
  132. #endif
  133. break;
  134. }
  135. case mcStart: // 配置电机启动参数,进入mcRun状态。
  136. {
  137. Motor_Open();
  138. break;
  139. }
  140. case mcRun: // 运行状态,若运行状态的给定变为0,进入mcStop状态。
  141. {
  142. break;
  143. }
  144. case mcStop:
  145. {
  146. #if (StopBrakeFlag == 0)
  147. {
  148. mcState = mcReady;
  149. FOC_CR1 = 0x00;
  150. ClrBit(DRV_CR, FOCEN); //关闭FOC
  151. MOE = 0;
  152. }
  153. #else
  154. if (motorControl.ActualSpeed < MOTOR_STOP_SPEED)
  155. {
  156. MOE = 0;
  157. FOC_CR1 = 0x00;
  158. ClrBit(DRV_CR, FOCEN);
  159. DRV_DR = DRV_ARR + 1;
  160. DRV_CMR = 0x00;
  161. DRV_CMR |= 0x015; // 三相下桥臂通,刹车
  162. ClrBit(DRV_CR, OCS); // OCS = 0, DRV_COMR;OCS = 1, FOC/SVPWM/SPWM
  163. MOE = 1;
  164. mcState = mcBrake;
  165. mcFocCtrl.State_Count = StopWaitTime;
  166. }
  167. #endif
  168. break;
  169. }
  170. case mcBrake:
  171. {
  172. if (isCtrlPowOn)
  173. {
  174. mcState = mcReady;
  175. mcFocCtrl.State_Count = 0; //单位:1ms 强制关机时间
  176. }
  177. else if (mcFocCtrl.State_Count == 0)
  178. {
  179. mcState = mcReady;
  180. MOE = 0;
  181. ClrBit(DRV_CR, FOCEN);
  182. }
  183. break;
  184. }
  185. case mcFault:
  186. {
  187. if (mcFaultSource == FaultNoSource)
  188. { mcState = mcReady;}
  189. break;
  190. }
  191. default:
  192. {
  193. mcState = mcReady;
  194. break;
  195. }
  196. }
  197. }
  198. /**
  199. @function Tick_Task
  200. @brief 周期任务
  201. @date 2025-11-03
  202. */
  203. void Tick_Task(void)
  204. {
  205. if ((mcState == mcStart) || (mcState == mcRun) || (mcState == mcStop))
  206. {
  207. mcFocCtrl.Powerlpf = LPF_Zero_Update(FOC__POW, mcFocCtrl.Powerlpf, LPF_K(1.0));
  208. mcFocCtrl.IDQFlt = LPF_Zero_Update(mcCurVarible.Max_is, mcFocCtrl.IDQFlt, LPF_K(1.0));
  209. mcFocCtrl.UDFlt = LPF_Zero_Update(FOC__UD, mcFocCtrl.UDFlt, LPF_K(30.0)); //LPF_K(30.0)
  210. mcFocCtrl.UQFlt = LPF_Zero_Update(FOC__UQ, mcFocCtrl.UQFlt, LPF_K(30.0)); //LPF_K(30.0)
  211. motorControl.ActualSpeed = LPF_Zero_Update(FOC__EOME, motorControl.ActualSpeed, LPF_K(71.0));
  212. motorControl.BackEMF = LPF_Zero_Update(FOC__EMF, motorControl.BackEMF, LPF_K(5.0));
  213. if (mcFocCtrl.Powerlpf <= 0)
  214. {mcFocCtrl.Powerlpf = 0;}
  215. }
  216. else
  217. {
  218. mcFocCtrl.IDQFlt = 0;
  219. mcFocCtrl.Powerlpf = 0;
  220. motorControl.ActualSpeed = 0;
  221. motorControl.BackEMF = 0;
  222. }
  223. StarRampDealwith();
  224. }