MotorProtect.c 19 KB

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