FocControl.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  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. switch (currOffset.OffsetCalib)
  27. {
  28. // 初始化状态
  29. case CALIB_INIT:
  30. {
  31. if (powerControl.PowerSate == POWER_RUN)
  32. {
  33. ClrBit(DRV_CR, FOCEN);
  34. MOE = 0;
  35. SetBit(ADC_MASK, CH1EN | CH0EN);
  36. currOffset.OffsetCount = 0;
  37. currOffset.OffsetCalib = GET_OFFSET;
  38. }
  39. break;
  40. }
  41. // 检查状态
  42. case GET_OFFSET:
  43. {
  44. SetBit(ADC_CR, ADCBSY);
  45. while (ReadBit(ADC_CR, ADCBSY));
  46. currOffset.IuOffsetSum += ((ADC0_DR & 0x7ff8));
  47. currOffset.IuOffset = currOffset.IuOffsetSum >> 4;
  48. currOffset.IuOffsetSum -= currOffset.IuOffset;
  49. currOffset.IvOffsetSum += ((ADC1_DR & 0x7ff8));
  50. currOffset.IvOffset = currOffset.IvOffsetSum >> 4;
  51. currOffset.IvOffsetSum -= currOffset.IvOffset;
  52. currOffset.IwBusOffset = currOffset.IvOffset;
  53. if (++currOffset.OffsetCount > 1000)
  54. {
  55. //进入偏置电压错误保护
  56. if (((currOffset.IuOffset > 19959) || (currOffset.IuOffset < 10107)) ||
  57. ((currOffset.IvOffset > 19959) || (currOffset.IvOffset < 10107)))
  58. {
  59. currOffset.OffsetCalib = CALIB_INIT;
  60. mcFaultSource = FaultIbusOffset;
  61. FaultProcess();
  62. }
  63. else
  64. { currOffset.OffsetCalib = OFFSET_READY; }
  65. }
  66. break;
  67. }
  68. // 启动状态
  69. case OFFSET_READY:
  70. {
  71. if (isCtrlPowOn)
  72. {
  73. mcState = mcInit;
  74. // 关闭软件电流采样的ADC
  75. ClrBit(ADC_MASK, CH1EN | CH0EN);
  76. currOffset.OffsetCalib = CALIB_INIT;
  77. ClrBit(DRV_CR, DRVEN);
  78. _nop_(); _nop_(); _nop_(); _nop_();
  79. SetBit(DRV_CR, DRVEN);
  80. }
  81. break;
  82. }
  83. }
  84. break;
  85. }
  86. case mcInit:
  87. {
  88. //if ((mcFocCtrl.mcDcbusFlt > _Q15(Under_Protect_Voltage / HW_BOARD_VOLT_MAX)))
  89. {
  90. // 关闭软件电流采样的ADC
  91. mcFaultSource = 0;
  92. memset(&mcFaultDect, 0, sizeof(FaultVarible));
  93. memset(&mcFocCtrl, 0, sizeof(FOCCTRL));
  94. mcFocCtrl.mcDcbus_chazhi = 32760;
  95. McStaSet.SetMode = 0;
  96. memset(&VoltageComp, 0, sizeof(VOLCOMP));
  97. // PI控制器初始化
  98. HW_Zero_PI_Init();
  99. HW_One_PI_Init();
  100. #if (FiledWeakenCompEnable)
  101. memset(&mcFieldWeaken, 0, sizeof(FieldWeakeningTypeDef));
  102. #endif
  103. // 此模块不需要预充电
  104. #if 0
  105. mcState = mcCharge;
  106. mcFocCtrl.ChargeStep = 0;
  107. mcFocCtrl.State_Count = 0;
  108. #else
  109. mcState = mcAlign;
  110. mcFocCtrl.State_Count = Align_Time;
  111. #endif
  112. }
  113. break;
  114. }
  115. case mcCharge:
  116. {
  117. switch (mcFocCtrl.ChargeStep)
  118. {
  119. case 0:
  120. {
  121. // 配置占空比
  122. DRV_DR = Calib_Duty * DRV_ARR;
  123. // DRV_CTL:PWM来源选择
  124. // OCS = 0, DRV_COMR
  125. // OCS = 1, FOC/SVPWM/SPWM
  126. ClrBit(DRV_CR, OCS);
  127. mcFocCtrl.ChargeStep = 1;
  128. mcFocCtrl.State_Count = 30;
  129. break;
  130. }
  131. // U相下桥臂通
  132. case 1:
  133. {
  134. DRV_CMR |= 0x01;
  135. MOE = 1;
  136. break;
  137. }
  138. // V相下桥臂导通
  139. case 2:
  140. {
  141. DRV_CMR |= 0x04;
  142. break;
  143. }
  144. // W相下桥臂导通
  145. case 3:
  146. {
  147. DRV_CMR |= 0x10;
  148. break;
  149. }
  150. case 4:
  151. {
  152. #if (1)
  153. DRV_CMR |= 0x3F;
  154. #else
  155. MOE = 0;
  156. mcState = mcAlign;
  157. mcFocCtrl.State_Count = Align_Time;
  158. #endif
  159. break;
  160. }
  161. }
  162. if ((mcFocCtrl.State_Count == 0) && (mcFocCtrl.ChargeStep != 4 ))
  163. {
  164. mcFocCtrl.ChargeStep ++;
  165. mcFocCtrl.State_Count = 30;
  166. }
  167. break;
  168. }
  169. case mcAlign:
  170. {
  171. Motor_Align();
  172. break;
  173. }
  174. case mcStart: // 配置电机启动参数,进入mcRun状态。
  175. {
  176. Motor_Open();
  177. break;
  178. }
  179. case mcRun: // 运行状态,若运行状态的给定变为0,进入mcStop状态。
  180. {
  181. break;
  182. }
  183. case mcStop:
  184. {
  185. #if (StopBrakeFlag == 0)
  186. {
  187. mcState = mcReady;
  188. FOC_CR1 = 0x00;
  189. ClrBit(DRV_CR, FOCEN); //关闭FOC
  190. MOE = 0;
  191. }
  192. #else
  193. if (motorControl.ActualSpeed < MOTOR_STOP_SPEED)
  194. {
  195. MOE = 0;
  196. FOC_CR1 = 0x00;
  197. ClrBit(DRV_CR, FOCEN);
  198. DRV_DR = DRV_ARR + 1;
  199. DRV_CMR = 0x00;
  200. DRV_CMR |= 0x015; // 三相下桥臂通,刹车
  201. ClrBit(DRV_CR, OCS); // OCS = 0, DRV_COMR;OCS = 1, FOC/SVPWM/SPWM
  202. MOE = 1;
  203. mcState = mcBrake;
  204. mcFocCtrl.State_Count = StopWaitTime;
  205. }
  206. #endif
  207. break;
  208. }
  209. case mcBrake:
  210. {
  211. if (isCtrlPowOn)
  212. {
  213. mcState = mcReady;
  214. mcFocCtrl.State_Count = 0; //单位:1ms 强制关机时间
  215. }
  216. else if (mcFocCtrl.State_Count == 0)
  217. {
  218. mcState = mcReady;
  219. MOE = 0;
  220. ClrBit(DRV_CR, FOCEN);
  221. }
  222. break;
  223. }
  224. case mcFault:
  225. {
  226. if (mcFaultSource == FaultNoSource)
  227. { mcState = mcReady;}
  228. break;
  229. }
  230. default:
  231. {
  232. mcState = mcReady;
  233. break;
  234. }
  235. }
  236. }
  237. /**
  238. @function Tick_Task
  239. @brief 周期任务
  240. @date 2025-11-03
  241. */
  242. void Tick_Task(void)
  243. {
  244. if ((mcState == mcStart) || (mcState == mcRun) || (mcState == mcStop))
  245. {
  246. mcFocCtrl.Powerlpf = LPF_Zero_Update(FOC__POW, mcFocCtrl.Powerlpf, LPF_K(1.0));
  247. mcFocCtrl.IDQFlt = LPF_Zero_Update(mcCurVarible.Max_is, mcFocCtrl.IDQFlt, LPF_K(1.0));
  248. mcFocCtrl.UDFlt = LPF_Zero_Update(FOC__UD, mcFocCtrl.UDFlt, LPF_K(30.0)); //LPF_K(30.0)
  249. mcFocCtrl.UQFlt = LPF_Zero_Update(FOC__UQ, mcFocCtrl.UQFlt, LPF_K(30.0)); //LPF_K(30.0)
  250. motorControl.ActualSpeed = LPF_Zero_Update(FOC__EOME, motorControl.ActualSpeed, LPF_K(71.0));
  251. motorControl.BackEMF = LPF_Zero_Update(FOC__EMF, motorControl.BackEMF, LPF_K(5.0));
  252. if (mcFocCtrl.Powerlpf <= 0)
  253. {mcFocCtrl.Powerlpf = 0;}
  254. }
  255. else
  256. {
  257. mcFocCtrl.IDQFlt = 0;
  258. mcFocCtrl.Powerlpf = 0;
  259. motorControl.ActualSpeed = 0;
  260. motorControl.BackEMF = 0;
  261. }
  262. // StarRampDealwith();
  263. }