MotorProtect.c 19 KB

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