MotorProtect.c 19 KB

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