MotorProtect.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. /**
  2. * @copyright None
  3. * @file MotorProtect.c
  4. * @author Comment Vivre
  5. * @date 2024-08-26
  6. * @brief None
  7. */
  8. #include <FU68xx_5.h>
  9. #include <Myproject.h>
  10. FaultStateType data mcFaultSource; ///< 故障类型
  11. uint8 xdata mcPOSTErrSource; ///< 自检故障类型
  12. FaultVarible xdata fault; ///< 故障检测相关结构体变量
  13. FaultRecoverTypedef xdata Restart; ///< 故障恢复重启控制相关结构体变量
  14. /**
  15. @brief 过温检测
  16. @date 2022-07-14
  17. */
  18. void Fault_Temperature(void)
  19. {
  20. if (mcFaultSource == FaultNoSource)
  21. {
  22. if (mcFocCtrl.NTCValueFlt <= OVER_Temperature) // 过温保护
  23. {
  24. if (fault.Temperature.DetecCnt < TemperatureProtectTime)
  25. {
  26. fault.Temperature.DetecCnt++;
  27. }
  28. else
  29. {
  30. fault.Temperature.DetecCnt = 0;
  31. mcFaultSource = FaultNtcOTErr;
  32. }
  33. }
  34. else
  35. {
  36. fault.Temperature.DetecCnt = 0;
  37. }
  38. }
  39. }
  40. /**
  41. @brief 过欠压检测
  42. @date 2022-07-14
  43. */
  44. void Fault_Voltage(void)
  45. {
  46. if (fault.Voltage.DectDealyCnt < 100)
  47. {
  48. fault.Voltage.DectDealyCnt++;
  49. }
  50. else
  51. {
  52. if (mcFaultSource == FaultNoSource)
  53. {
  54. // 过压检测
  55. if (mcFocCtrl.mcDcbusFlt > OVER_VOLTAGE_PROTECT)
  56. {
  57. fault.Voltage.OverVoltDetecCnt += 1;
  58. if (fault.Voltage.OverVoltDetecCnt >= 100)
  59. {
  60. fault.Voltage.OverVoltDetecCnt = 0;
  61. mcFaultSource = FaultOverVoltageDC;
  62. }
  63. }
  64. else if (fault.Voltage.OverVoltDetecCnt > 0)
  65. { fault.Voltage.OverVoltDetecCnt--; }
  66. if (mcFocCtrl.mcDcbusFlt < UNDER_VOLTAGE_PROTECT)
  67. {
  68. fault.Voltage.UnderVoltDetecCnt += 1;
  69. if (fault.Voltage.UnderVoltDetecCnt >= 20)
  70. { VoltageComp.Undervoltage_flag = 1; }
  71. if (fault.Voltage.UnderVoltDetecCnt >= 60)
  72. {
  73. fault.Voltage.UnderVoltDetecCnt = 0;
  74. mcFaultSource = FaultUnderVoltageDC;
  75. fault.Voltage.VoltDetecBraketCount = 500;
  76. fault.Voltage.VoltDetecBraketDuty = 0.05 * DRV_ARR;
  77. fault.Voltage.FlagBrakeInit = 1;
  78. }
  79. }
  80. else if (fault.Voltage.UnderVoltDetecCnt)
  81. { fault.Voltage.UnderVoltDetecCnt--; }
  82. }
  83. }
  84. }
  85. /**
  86. * @brief 欠压处理
  87. * @brief 刹车处理
  88. * @date 2022-07-14
  89. */
  90. void UnderProcess(void)
  91. {
  92. if (mcFaultSource == FaultUnderVoltageDC)
  93. {
  94. // 过欠压停机刹车功能
  95. if (fault.Voltage.VoltDetecBraketCount > 0)
  96. {
  97. DRV_DR = fault.Voltage.VoltDetecBraketDuty; // 下桥臂10% duty
  98. if (fault.Voltage.FlagBrakeInit == 1)
  99. {
  100. fault.Voltage.FlagBrakeInit = 2;
  101. // DRV_CMR &= 0xFFC0;
  102. ClrBit(DRV_CR, OCS); // OCS = 0, PWM来源DRV_COMR
  103. DRV_CMR = 0x0015; // UVW相下桥输出
  104. SetBit(DRV_CR, DRVEN); // DRV计数器使能,0-禁止,1-使能
  105. MOE = 1;
  106. DRV_DR = 0.05 * DRV_ARR;
  107. }
  108. }
  109. else
  110. {
  111. fault.Voltage.FlagBrakeInit = 0;
  112. MOE = 0;
  113. DRV_OUT = 0x00;
  114. }
  115. }
  116. }
  117. /**
  118. @brief 软件过流检测
  119. @date 2022-08-09
  120. */
  121. void Fault_OverCurrent(void)
  122. {
  123. if (mcFaultSource == FaultNoSource)
  124. {
  125. if (mcState == mcStart || mcState == mcAlign || mcState == mcRun || mcState == mcStop)
  126. {
  127. fault.Current.Is = Sqrt_alpbet(FOC__IA, FOC__IBET);
  128. if (fault.Current.Is >= SW_OC_CurrentVal)
  129. {
  130. if (fault.Current.SWOC_DectTimeCnt < SW_OC_DectTime)
  131. {
  132. fault.Current.SWOC_DectTimeCnt++;
  133. }
  134. else
  135. {
  136. fault.Current.SWOC_DectTimeCnt = 0;
  137. mcFaultSource = FaultSoftOVCurrent;
  138. }
  139. }
  140. else
  141. {
  142. fault.Current.SWOC_DectTimeCnt = 0;
  143. }
  144. }
  145. }
  146. }
  147. /**
  148. @brief 堵转检测
  149. @date 2022-07-14
  150. */
  151. void Fault_Stall(void)
  152. {
  153. if (mcState == mcRun)
  154. {
  155. fault.Stall.EsValue = mcFocCtrl.EMFsquare;
  156. if (fault.Stall.DectDealyCnt < 3000) /* Delay for a period of time to test */
  157. {
  158. fault.Stall.DectDealyCnt++;
  159. }
  160. else
  161. {
  162. /* ****** 1 ****** */
  163. if ((fault.Stall.EsValue < EsThresholdValueL))
  164. {
  165. fault.Stall.EsDectCnt++;
  166. if (fault.Stall.EsDectCnt >= 75)
  167. {
  168. fault.Stall.EsDectCnt = 0;
  169. mcFaultSource = FaultStall;
  170. fault.Stall.Type = 11;
  171. }
  172. }
  173. else if ((fault.Stall.EsValue < EsThresholdValueH) && (mcFocCtrl.SpeedFlt > EsThresholdSpeed))
  174. {
  175. fault.Stall.EsDectCnt++;
  176. if (fault.Stall.EsDectCnt >= 60)
  177. {
  178. fault.Stall.EsDectCnt = 0;
  179. mcFaultSource = FaultStall;
  180. fault.Stall.Type = 12;
  181. }
  182. }
  183. else
  184. {
  185. if (fault.Stall.EsDectCnt > 0)
  186. {
  187. fault.Stall.EsDectCnt--;
  188. }
  189. }
  190. /* ****** 2 ****** */
  191. if (mcFocCtrl.SpeedFlt < STALL_SPEED_MIN || mcFocCtrl.SpeedFlt > STALL_SPEED_MAX)
  192. {
  193. fault.Stall.SpeedMinCnt++;
  194. if (fault.Stall.SpeedMinCnt >= 75)
  195. {
  196. fault.Stall.SpeedMinCnt = 0;
  197. mcFaultSource = FaultStall;
  198. fault.Stall.Type = 21;
  199. }
  200. }
  201. else
  202. {
  203. if (fault.Stall.SpeedMinCnt > 0)
  204. {
  205. fault.Stall.SpeedMinCnt--;
  206. }
  207. }
  208. }
  209. /* ****** 3 ****** */
  210. if (mcFocCtrl.CtrlMode == 0)
  211. {
  212. fault.Stall.Mode0DectCnt++;
  213. if (fault.Stall.Mode0DectCnt >= 6000)
  214. {
  215. fault.Stall.Mode0DectCnt = 0;
  216. mcFaultSource = FaultStall;
  217. fault.Stall.Type = 31;
  218. }
  219. }
  220. else
  221. {
  222. fault.Stall.Mode0DectCnt = 0;
  223. }
  224. }
  225. }
  226. /**
  227. @brief 缺相检测
  228. @date 2022-07-14
  229. */
  230. void Fault_PhaseLoss(void)
  231. {
  232. if (mcState == mcRun)
  233. {
  234. if (fault.PhaseLoss.DectDealyCnt < LP_DectDealyTIME)
  235. {
  236. fault.PhaseLoss.DectDealyCnt++;
  237. }
  238. else
  239. {
  240. if (fault.PhaseLoss.DectCycleCnt < LP_DectCycleTIME)
  241. {
  242. fault.PhaseLoss.Max_ia = FOC__IAMAX;
  243. fault.PhaseLoss.Max_ib = FOC__IBMAX;
  244. fault.PhaseLoss.Max_ic = FOC__ICMAX;
  245. fault.PhaseLoss.DectCycleCnt++;
  246. }
  247. else
  248. {
  249. fault.PhaseLoss.DectCycleCnt = 0;
  250. if (((fault.PhaseLoss.Max_ia > (fault.PhaseLoss.Max_ib * 3)) || (fault.PhaseLoss.Max_ia > (fault.PhaseLoss.Max_ic * 3))) && (fault.PhaseLoss.Max_ia > LP_NoLoadCurrentValue))
  251. {
  252. fault.PhaseLoss.ALossCnt++;
  253. }
  254. else
  255. {
  256. if (fault.PhaseLoss.ALossCnt > 0)
  257. {
  258. fault.PhaseLoss.ALossCnt--;
  259. }
  260. }
  261. if (((fault.PhaseLoss.Max_ib > (fault.PhaseLoss.Max_ia * 3)) || (fault.PhaseLoss.Max_ib > (fault.PhaseLoss.Max_ic * 3))) && (fault.PhaseLoss.Max_ib > LP_NoLoadCurrentValue))
  262. {
  263. fault.PhaseLoss.BLossCnt++;
  264. }
  265. else
  266. {
  267. if (fault.PhaseLoss.BLossCnt > 0)
  268. {
  269. fault.PhaseLoss.BLossCnt--;
  270. }
  271. }
  272. if (((fault.PhaseLoss.Max_ic > (fault.PhaseLoss.Max_ia * 3)) || (fault.PhaseLoss.Max_ic > (fault.PhaseLoss.Max_ib * 3))) && (fault.PhaseLoss.Max_ic > LP_NoLoadCurrentValue))
  273. {
  274. fault.PhaseLoss.CLossCnt++;
  275. }
  276. else
  277. {
  278. if (fault.PhaseLoss.CLossCnt > 0)
  279. {
  280. fault.PhaseLoss.CLossCnt--;
  281. }
  282. }
  283. fault.PhaseLoss.Max_ia = 0;
  284. fault.PhaseLoss.Max_ib = 0;
  285. fault.PhaseLoss.Max_ic = 0;
  286. SetBit(FOC_CR2, ICLR);
  287. if ((fault.PhaseLoss.ALossCnt > 10) || (fault.PhaseLoss.BLossCnt > 10) || (fault.PhaseLoss.CLossCnt > 10))
  288. {
  289. mcFaultSource = FaultPhaseLost;
  290. }
  291. }
  292. }
  293. }
  294. }
  295. /**
  296. * @brief 功率保护函数
  297. * @date 2022-07-14
  298. */
  299. void Fault_Power(void)
  300. {
  301. if (mcFaultSource == FaultNoSource) // 程序无其他保护下
  302. {
  303. if ((mcFocCtrl.PowerFlt > OverPowerValue) && (mcState == mcRun)) // 功率大于保护值时计数,超过20次,判断为过载保护,关闭输出;反之,计数器慢慢减
  304. {
  305. fault.Power.OverPowerDetecCnt++;
  306. if (fault.Power.OverPowerDetecCnt > 150)
  307. {
  308. fault.Power.OverPowerDetecCnt = 0;
  309. mcFaultSource = FaultOverPowerErr;
  310. }
  311. }
  312. else
  313. {
  314. if (fault.Power.OverPowerDetecCnt > 0)
  315. {
  316. fault.Power.OverPowerDetecCnt--;
  317. }
  318. }
  319. }
  320. }
  321. /* -------------------------------------------------------------------------------------------------
  322. Function Name : Fault_Recovery
  323. Description : 故障恢复,条件满足只清除故障码,状态跳转由状态机执行
  324. Date : 2022-07-01
  325. Parameter : None
  326. ------------------------------------------------------------------------------------------------- */
  327. static void Fault_Recovery(void)
  328. {
  329. if (mcState == mcFault)
  330. {
  331. #if (OV_RecoveryTimes) /* DC电压保护恢复 */
  332. {
  333. if (mcFaultSource == FaultUnderVoltageDC || mcFaultSource == FaultOverVoltageDC)
  334. {
  335. if ((mcFocCtrl.mcDcbusFlt > UNDER_VOLTAGE_RECOVER) && (mcFocCtrl.mcDcbusFlt < OVER_VOLTAGE_RECOVER))
  336. {
  337. if (fault.Voltage.FlagBrakeInit == 0)
  338. {
  339. Restart.DC_DelayTcnt++;
  340. }
  341. else
  342. {
  343. Restart.DC_DelayTcnt = 0;
  344. }
  345. if (Restart.DC_DelayTcnt > OV_RecoveryDelayTime)
  346. {
  347. Restart.DC_DelayTcnt = 0;
  348. mcFaultSource = FaultNoSource;
  349. }
  350. if (Restart.DC_DelayTcnt > 40)
  351. {
  352. VoltageComp.Undervoltage_flag = 0;
  353. }
  354. }
  355. else
  356. {
  357. Restart.DC_DelayTcnt = 0;
  358. }
  359. if (mcFaultSource == FaultUnderVoltageDC)
  360. {
  361. if (fault.Voltage.VoltDetecBraketCount > 0)
  362. {
  363. fault.Voltage.VoltDetecBraketCount--;
  364. }
  365. if (fault.Voltage.VoltDetecBraketDuty < DRV_ARR + 4)
  366. {
  367. fault.Voltage.VoltDetecBraketDuty += 20;
  368. }
  369. }
  370. }
  371. }
  372. #endif
  373. #if (OT_RecoveryTimes)
  374. /* 过温保护恢复 */
  375. if (mcFaultSource == FaultNtcOTErr)
  376. {
  377. if (mcFocCtrl.NTCValueFlt >= UNDER_Temperature)
  378. {
  379. if (Restart.OT_Times <= OT_RecoveryTimes)
  380. {
  381. if (Restart.OT_DelayTcnt < OT_RecoveryDelayTime)
  382. {
  383. Restart.OT_DelayTcnt++;
  384. }
  385. else
  386. {
  387. Restart.OT_Times++;
  388. Restart.OT_DelayTcnt = 0;
  389. mcFaultSource = FaultNoSource;
  390. }
  391. }
  392. }
  393. }
  394. #endif
  395. #if (LP_RecoveryTimes)
  396. /* 缺相保护恢复 */
  397. if (mcFaultSource == FaultPhaseLost)
  398. {
  399. if (Restart.LP_Times < LP_RecoveryTimes)
  400. {
  401. if (Restart.LP_DelayTcnt < LP_RecoveryDelayTime)
  402. {
  403. Restart.LP_DelayTcnt++;
  404. }
  405. else
  406. {
  407. Restart.LP_Times++;
  408. Restart.LP_DelayTcnt = 0;
  409. mcFaultSource = FaultNoSource;
  410. }
  411. }
  412. }
  413. #endif
  414. #if (Stall_RecoveryTimes)
  415. /* 堵转保护恢复 */
  416. if (mcFaultSource == FaultStall)
  417. {
  418. if (Restart.Stall_Times < Stall_RecoveryTimes)
  419. {
  420. if (Restart.Stall_DealyTcnt < Stall_RecoveryDelayTime)
  421. {
  422. Restart.Stall_DealyTcnt++;
  423. }
  424. else
  425. {
  426. Restart.Stall_Times++;
  427. Restart.Stall_DealyTcnt = 0;
  428. mcFaultSource = FaultNoSource;
  429. }
  430. }
  431. }
  432. #endif
  433. #if (OC_RecoveryTimes)
  434. /* 软件过流恢复 */
  435. if (mcFaultSource == FaultSoftOVCurrent || mcFaultSource == FaultHardOVCurrent)
  436. {
  437. if (Restart.SWOC_Times < OC_RecoveryTimes)
  438. {
  439. if (Restart.SWOC_DelayTcnt < OC_RecoveryDelayTime)
  440. {
  441. Restart.SWOC_DelayTcnt++;
  442. }
  443. else
  444. {
  445. Restart.SWOC_Times++;
  446. Restart.SWOC_DelayTcnt = 0;
  447. mcFaultSource = FaultNoSource;
  448. }
  449. }
  450. }
  451. #endif
  452. #if (OP_RecoveryTimes) // 功率保护恢复使能
  453. {
  454. if (mcFaultSource == FaultOverPowerErr)
  455. {
  456. if (Restart.OverPower_Times < OP_RecoveryTimes)
  457. {
  458. if (Restart.OverPower_DealyTcnt < OP_RecoveryDelayTime)
  459. {
  460. Restart.OverPower_DealyTcnt++;
  461. }
  462. else
  463. {
  464. Restart.OverPower_Times++;
  465. Restart.OverPower_DealyTcnt = 0;
  466. mcFaultSource = FaultNoSource;
  467. }
  468. }
  469. }
  470. }
  471. #endif
  472. }
  473. }
  474. /**
  475. @brief 偏置电压检测
  476. */
  477. void Fault_GetCurrentOffset(void)
  478. {
  479. if (mcCurOffset.OffsetFlag == 1)
  480. {
  481. #if (VHALF_EN == Enable) // 有加VHALF偏置,理论值为16383
  482. {
  483. #if (Shunt_Resistor_Mode == Single_Resistor) // 单电阻模式
  484. {
  485. if ((mcCurOffset.Iw_busOffset < GetCurrentOffsetValueLow) || (mcCurOffset.Iw_busOffset > GetCurrentOffsetValueHigh))
  486. {
  487. mcFaultSource = FaultGetOffset;
  488. }
  489. }
  490. #elif (Shunt_Resistor_Mode == Double_Resistor) // 双电阻模式
  491. {
  492. if ((mcCurOffset.IuOffset < GetCurrentOffsetValueLow) || (mcCurOffset.IuOffset > GetCurrentOffsetValueHigh) || (mcCurOffset.IvOffset < GetCurrentOffsetValueLow) || (mcCurOffset.IvOffset > GetCurrentOffsetValueHigh))
  493. {
  494. mcFaultSource = FaultGetOffset;
  495. }
  496. }
  497. #elif (Shunt_Resistor_Mode == Three_Resistor) // 三电阻模式
  498. {
  499. if ((mcCurOffset.IuOffset < GetCurrentOffsetValueLow) || (mcCurOffset.IuOffset > GetCurrentOffsetValueHigh) || (mcCurOffset.IvOffset < GetCurrentOffsetValueLow) || (mcCurOffset.IvOffset > GetCurrentOffsetValueHigh) || (mcCurOffset.Iw_busOffset < GetCurrentOffsetValueLow) || (mcCurOffset.Iw_busOffset > GetCurrentOffsetValueHigh))
  500. {
  501. mcFaultSource = FaultGetOffset;
  502. }
  503. }
  504. #endif
  505. }
  506. #else // 没加VHALF偏置,理论值在0
  507. {
  508. #if (Shunt_Resistor_Mode == Single_Resistor) // 单电阻模式
  509. {
  510. if (mcCurOffset.Iw_busOffset > GetCurrentOffsetValue)
  511. {
  512. mcFaultSource = FaultGetOffset;
  513. }
  514. }
  515. #elif (Shunt_Resistor_Mode == Double_Resistor) // 双电阻模式
  516. {
  517. if ((mcCurOffset.IuOffset > GetCurrentOffsetValue) || (mcCurOffset.IvOffset > GetCurrentOffsetValue))
  518. {
  519. mcFaultSource = FaultGetOffset;
  520. }
  521. }
  522. #elif (Shunt_Resistor_Mode == Three_Resistor) // 三电阻模式
  523. {
  524. if ((mcCurOffset.IuOffset > GetCurrentOffsetValue) || (mcCurOffset.IvOffset > GetCurrentOffsetValue) || (mcCurOffset.Iw_busOffset > GetCurrentOffsetValue))
  525. {
  526. mcFaultSource = FaultGetOffset;
  527. }
  528. }
  529. #endif
  530. }
  531. #endif
  532. }
  533. }
  534. /* -------------------------------------------------------------------------------------------------
  535. Function Name : Fault_Detection
  536. Description : 故障检测与保护,扫描周期默认为1ms
  537. 所有故障发送只进行 故障码 赋值
  538. 禁止在状态机以外地方进行状态跳转
  539. Date : 2022-07-01
  540. Parameter : None
  541. ------------------------------------------------------------------------------------------------- */
  542. void Fault_Detection(void)
  543. {
  544. #if (OC_SW_ProtectEn == 1)
  545. {
  546. Fault_OverCurrent();
  547. }
  548. #endif
  549. #if (OT_ProtectEn == 1)
  550. {
  551. Fault_Temperature();
  552. }
  553. #endif
  554. #if (OV_ProtectEn == 1)
  555. {
  556. Fault_Voltage();
  557. }
  558. #endif
  559. #if (Stall_ProtectEn == 1)
  560. {
  561. Fault_Stall();
  562. }
  563. #endif
  564. #if (LP_ProtectEn == 1)
  565. {
  566. Fault_PhaseLoss();
  567. }
  568. #endif
  569. #if (OP_ProtectEn == 1) // 功率保护使能
  570. {
  571. Fault_Power();
  572. }
  573. #endif
  574. Fault_Recovery();
  575. }