FocControl.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. #include <Myproject.h>
  2. MotStaType mcState;
  3. /**
  4. @function Motor_Control_State
  5. @brief 电机控制状态机 负责状态跳转
  6. @date 2025-11-03
  7. */
  8. void Motor_Control_State(void)
  9. {
  10. // 故障直接跳转Fault
  11. if (mcFaultSource != FaultNoSource)
  12. { mcState = mcFault; }
  13. // 非Ready状态检测到关机信号跳转Stop
  14. else if ((isCtrlPowOn == false) && (mcState != mcReady))
  15. {
  16. // 若当前为Run 配置停机时间再跳转Stop
  17. if (mcState == mcRun)
  18. { mcFocCtrl.State_Count = 30000; }
  19. mcState = mcStop;
  20. }
  21. switch (mcState)
  22. {
  23. case mcReady:
  24. switch (currOffset.OffsetCalib)
  25. {
  26. // 初始化状态
  27. case CALIB_INIT:
  28. if (powerControl.PowerSate == POWER_RUN)
  29. {
  30. ClrBit(DRV_CR, FOCEN);
  31. MOE = 0;
  32. // 使能ADC转换通道
  33. SetBit(ADC_MASK, CH1EN | CH0EN);
  34. // 电流校准变量初始化
  35. memset(&currOffset, 0, sizeof(Curr_Offset_t));
  36. // 配置初始值
  37. currOffset.IuOffsetSum = 16383;
  38. currOffset.IvOffsetSum = 16383;
  39. currOffset.IwBusOffsetSum = 16383;
  40. // 跳转状态
  41. currOffset.OffsetCalib = GET_OFFSET;
  42. }
  43. break;
  44. // 检查状态
  45. case GET_OFFSET:
  46. SetBit(ADC_CR, ADCBSY);
  47. while (ReadBit(ADC_CR, ADCBSY));
  48. currOffset.IuOffsetSum += ((ADC0_DR & 0x7ff8));
  49. currOffset.IuOffset = currOffset.IuOffsetSum >> 4;
  50. currOffset.IuOffsetSum -= currOffset.IuOffset;
  51. currOffset.IvOffsetSum += ((ADC1_DR & 0x7ff8));
  52. currOffset.IvOffset = currOffset.IvOffsetSum >> 4;
  53. currOffset.IvOffsetSum -= currOffset.IvOffset;
  54. currOffset.IwBusOffset = currOffset.IvOffset;
  55. if (++currOffset.OffsetCount > 1000)
  56. {
  57. //进入偏置电压错误保护
  58. if (((currOffset.IuOffset > 19959) || (currOffset.IuOffset < 10107)) ||
  59. ((currOffset.IvOffset > 19959) || (currOffset.IvOffset < 10107)))
  60. {
  61. currOffset.OffsetCalib = CALIB_INIT;
  62. mcFaultSource = FaultIbusOffset;
  63. FaultProcess();
  64. }
  65. else
  66. { currOffset.OffsetCalib = OFFSET_READY; }
  67. }
  68. break;
  69. // 启动状态
  70. case OFFSET_READY:
  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. break;
  84. case mcInit:
  85. if (motorControl.DCBus > UNDER_RECOVER_VALUE)
  86. {
  87. // 关闭软件电流采样的ADC
  88. mcFaultSource = 0;
  89. memset(&mcFaultDect, 0, sizeof(FaultVarible));
  90. memset(&mcFocCtrl, 0, sizeof(FOCCTRL));
  91. // PI控制器初始化
  92. HW_Zero_PI_Init();
  93. // 弱磁初始化
  94. #if (FiledWeakenCompEnable)
  95. memset(&mcFieldWeaken, 0, sizeof(FieldWeakeningTypeDef));
  96. HW_One_PI_Init();
  97. #endif
  98. // 环路配置
  99. #if (SPEED_CONTROL_MODE)
  100. motorControl.RampInc = MOTOR_SPEED_INC;
  101. motorControl.RampDec = MOTOR_SPEED_DEC;
  102. #endif
  103. // 此模块不需要预充电
  104. #if (PRE_DRIVER_CHARGE)
  105. mcState = mcCharge;
  106. motorControl.ChargeState = CHARGE_INIT;
  107. #else
  108. mcState = mcAlign;
  109. #endif
  110. }
  111. break;
  112. #if (PRE_DRIVER_CHARGE)
  113. case mcCharge:
  114. switch (motorControl.ChargeState)
  115. {
  116. case CHARGE_INIT:
  117. // 配置占空比
  118. DRV_DR = CALIB_DUTY * DRV_ARR;
  119. // DRV_CTL:PWM来源选择
  120. // OCS = 0, DRV_COMR
  121. // OCS = 1, FOC/SVPWM/SPWM
  122. ClrBit(DRV_CR, OCS);
  123. motorControl.ChargeState = U_BRIDGE;
  124. mcFocCtrl.State_Count = 30;
  125. break;
  126. // U相下桥臂通
  127. case U_BRIDGE:
  128. DRV_CMR |= 0x01;
  129. MOE = 1;
  130. if (!mcFocCtrl.State_Count)
  131. {
  132. mcFocCtrl.State_Count = 30;
  133. motorControl.ChargeState = V_BRIDGE
  134. }
  135. break;
  136. // V相下桥臂导通
  137. case V_BRIDGE:
  138. DRV_CMR |= 0x04;
  139. if (!mcFocCtrl.State_Count)
  140. {
  141. mcFocCtrl.State_Count = 30;
  142. motorControl.ChargeState = W_BRIDGE
  143. }
  144. break;
  145. // W相下桥臂导通
  146. case W_BRIDGE:
  147. DRV_CMR |= 0x10;
  148. if (!mcFocCtrl.State_Count)
  149. { motorControl.ChargeState = CHARGE_END; }
  150. break;
  151. // 启动
  152. case CHARGE_END:
  153. #if (0)
  154. DRV_CMR |= 0x3F;
  155. #else
  156. MOE = 0;
  157. mcState = mcAlign;
  158. #endif
  159. break;
  160. }
  161. break;
  162. #endif
  163. case mcAlign:
  164. switch (motorControl.AlignState)
  165. {
  166. // 预定位初始化
  167. case ALIGN_INIT:
  168. // FOC初始化
  169. FOC_Init();
  170. // 配置预定位的电流、KP、KI
  171. FOC_IDREF = 0;
  172. FOC_IQREF = 0;
  173. FOC_DKP = DQKP_Alignment;
  174. FOC_DKI = DQKI_Alignment;
  175. FOC_QKP = DQKP_Alignment;
  176. FOC_QKI = DQKI_Alignment;
  177. FOC_EKP = OBSW_KP_GAIN;
  178. FOC_EKI = OBSW_KI_GAIN;
  179. // 配置预定位角度
  180. #if (EstimateAlgorithm == SMO)
  181. FOC__ETHETA = FOC__THETA - 4836;
  182. #elif (EstimateAlgorithm == PLL)
  183. FOC__ETHETA = FOC__THETA;
  184. #endif
  185. DRV_CMR |= 0x03F;
  186. MOE = 1;
  187. mcFocCtrl.State_Count = 500;
  188. motorControl.AlignState = ALIGN_CURR_RAMP;
  189. break;
  190. // 第一角度预定位电流爬坡
  191. case ALIGN_CURR_RAMP:
  192. FOC__THETA = ALIGN_ANGLE_1;
  193. FOC_IQREF = IQ_ALIGN_CURRENT * (AlignmentRampTime - mcFocCtrl.State_Count) / AlignmentRampTime;
  194. if (!mcFocCtrl.State_Count)
  195. {
  196. mcFocCtrl.State_Count = 500;
  197. motorControl.AlignState = ALIGN_FIRST_ANGLE;
  198. }
  199. break;
  200. // 第一角度预定位
  201. case ALIGN_FIRST_ANGLE:
  202. FOC_IQREF = IQ_ALIGN_CURRENT;
  203. FOC__THETA = ALIGN_ANGLE_1;
  204. if (!mcFocCtrl.State_Count)
  205. {
  206. mcFocCtrl.State_Count = 500;
  207. motorControl.AlignState = ALIGN_SECOND_ANGLE;
  208. }
  209. break;
  210. // 第二角度预定位
  211. case ALIGN_SECOND_ANGLE:
  212. FOC_IQREF = IQ_ALIGN_CURRENT;
  213. FOC__THETA = ALIGN_ANGLE_2;
  214. if (!mcFocCtrl.State_Count)
  215. {
  216. mcFocCtrl.State_Count = 500;
  217. motorControl.AlignState = ALIGN_INIT;
  218. mcState = mcStart;
  219. }
  220. break;
  221. }
  222. break;
  223. case mcStart: // 配置电机启动参数,进入mcRun状态。
  224. Motor_Open();
  225. break;
  226. case mcRun:
  227. break;
  228. case mcStop:
  229. #if (StopBrakeFlag)
  230. if (motorControl.ActualSpeed < MOTOR_STOP_SPEED)
  231. {
  232. MOE = 0;
  233. FOC_CR1 = 0x00;
  234. ClrBit(DRV_CR, FOCEN);
  235. DRV_DR = DRV_ARR + 1;
  236. DRV_CMR = 0x00;
  237. DRV_CMR |= 0x015; // 三相下桥臂通,刹车
  238. ClrBit(DRV_CR, OCS); // OCS = 0, DRV_COMR;OCS = 1, FOC/SVPWM/SPWM
  239. MOE = 1;
  240. mcState = mcBrake;
  241. mcFocCtrl.State_Count = StopWaitTime;
  242. }
  243. #else
  244. {
  245. mcState = mcReady;
  246. FOC_CR1 = 0x00;
  247. ClrBit(DRV_CR, FOCEN); //关闭FOC
  248. MOE = 0;
  249. }
  250. #endif
  251. break;
  252. case mcBrake:
  253. if (isCtrlPowOn)
  254. {
  255. mcState = mcReady;
  256. mcFocCtrl.State_Count = 0;
  257. }
  258. else if (mcFocCtrl.State_Count == 0)
  259. {
  260. mcState = mcReady;
  261. MOE = 0;
  262. ClrBit(DRV_CR, FOCEN);
  263. }
  264. break;
  265. case mcFault:
  266. if (mcFaultSource == FaultNoSource)
  267. { mcState = mcReady;}
  268. break;
  269. default:
  270. mcState = mcReady;
  271. break;
  272. }
  273. }
  274. /**
  275. @function Tick_Task
  276. @brief 周期任务
  277. @date 2025-11-03
  278. */
  279. void Tick_Task(void)
  280. {
  281. if ((mcState == mcStart) || (mcState == mcRun) || (mcState == mcStop))
  282. {
  283. mcFocCtrl.Powerlpf = LPF_Zero_Update(FOC__POW, mcFocCtrl.Powerlpf, LPF_K(1.0));
  284. mcFocCtrl.UDFlt = LPF_Zero_Update(FOC__UD, mcFocCtrl.UDFlt, LPF_K(30.0));
  285. mcFocCtrl.UQFlt = LPF_Zero_Update(FOC__UQ, mcFocCtrl.UQFlt, LPF_K(30.0));
  286. motorControl.ActualSpeed = LPF_Zero_Update(FOC__EOME, motorControl.ActualSpeed, LPF_K(71.0));
  287. motorControl.BackEMF = LPF_Zero_Update(FOC__EMF, motorControl.BackEMF, LPF_K(5.0));
  288. if (mcFocCtrl.Powerlpf <= 0)
  289. {mcFocCtrl.Powerlpf = 0;}
  290. }
  291. else
  292. {
  293. mcFocCtrl.Powerlpf = 0;
  294. motorControl.ActualSpeed = 0;
  295. motorControl.BackEMF = 0;
  296. }
  297. }