pwrlim.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. /************************************************************************
  2. Project: Welling Motor Control Paltform
  3. Filename: pwrlim.c
  4. Partner Filename: pwrlim.h
  5. Description: Motor input power limit
  6. Complier: IAR Embedded Workbench for ARM 7.80, IAR Systems.
  7. CPU TYPE : GD32F3x0
  8. *************************************************************************
  9. Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.
  10. All rights reserved.
  11. *************************************************************************
  12. *************************************************************************
  13. Revising History (ECL of this file):
  14. Fjy create this file;
  15. ************************************************************************/
  16. /************************************************************************
  17. Beginning of File, do not put anything above here except notes
  18. Compiler Directives:
  19. *************************************************************************/
  20. #ifndef _PWRLIM_C_
  21. #define _PWRLIM_C_
  22. #endif
  23. /************************************************************************
  24. Include File
  25. ************************************************************************/
  26. #include "syspar.h"
  27. #include "user.h"
  28. /************************************************************************
  29. Constant Table:
  30. ************************************************************************/
  31. /************************************************************************
  32. Exported Functions:
  33. ************************************************************************/
  34. /************************************************************************
  35. Function: pwr_voPwrLimInit;
  36. Description: Initialize Variables for "pwr_voPwrLim"
  37. Call by:
  38. Input Variables:
  39. Output/Return Variables:
  40. Subroutine Call:
  41. Reference:
  42. ************************************************************************/
  43. void pwr_voPwrLimInit(void)
  44. {
  45. pwr_stPwrLimOut2.swIqLimPu = cof_uwCurMaxPu;
  46. pwr_stPwrLimOut2.swErrorZ1 = 0; // Q14
  47. pwr_stPwrLimOut2.slIqLimDetaSum = 0;
  48. pwr_stPwrLimOut2.swIqLimDetaSum = 0;
  49. pwr_stPwrLimOut2.swIqLimPu = 0;
  50. }
  51. /************************************************************************
  52. Function: pwr_voPwrLimCof;
  53. Description: Coefficient calculation for "pwr_voPwrLim"
  54. Call by:
  55. Input Variables:
  56. Output/Return Variables:
  57. Subroutine Call:
  58. Reference:
  59. ************************************************************************/
  60. void pwr_voPwrLimCof(PWRLIM_COFIN *in, PWRLIM_COF *out)
  61. {
  62. UWORD uwPwrLim;
  63. ULONG ulPbWt;
  64. if (in->uwIBaseAp > 32767)
  65. {
  66. in->uwIBaseAp = 32767;
  67. }
  68. else if (in->uwIBaseAp < 1)
  69. {
  70. in->uwIBaseAp = 1;
  71. }
  72. else
  73. {}
  74. if (in->uwUbVt < 100)
  75. {
  76. in->uwUbVt = 100;
  77. }
  78. else
  79. {}
  80. if (in->swPwrLimW > 30000)
  81. {
  82. in->swPwrLimW = 30000;
  83. }
  84. else if (in->swPwrLimW < 100)
  85. {
  86. in->swPwrLimW = 100;
  87. }
  88. else
  89. {}
  90. if (in->uwPwrErrW < 20)
  91. {
  92. in->uwPwrErrW = 20;
  93. }
  94. else if (in->uwPwrErrW >= in->swPwrLimW)
  95. {
  96. in->uwPwrErrW = in->swPwrLimW - 10;
  97. }
  98. else
  99. {}
  100. if (in->swIqMaxAp > 32766)
  101. {
  102. in->swIqMaxAp = 32766;
  103. }
  104. else if (in->swIqMaxAp < 1)
  105. {
  106. in->swIqMaxAp = 1;
  107. }
  108. else
  109. {}
  110. out->swIqMaxPu = (SWORD)(((SLONG)in->swIqMaxAp << 14) / in->uwIBaseAp); // Q14, Max phase current (peak value)
  111. ulPbWt = ((ULONG)3 * in->uwUbVt * in->uwIBaseAp / 100) >> 1; // Q0, unit: 0.1w, Power base
  112. uwPwrLim = ((ULONG)in->uwPwrErrW << 15) / ulPbWt; // Q15
  113. out->uwPwrLimKp = (((SLONG)out->swIqMaxPu << 6) / uwPwrLim); // 14+6-15=Q5
  114. out->swPwrLimStartThresholdTemp = in->uwPwrLimSTARTCe; // PWRLIM_START_THRESHOLD_TEMP; // Ce Q0
  115. out->swPwrLimENDThresholdTemp = (in->uwPwrLimSTARTCe + in->uwPwrLimENDCe) >> 1;
  116. out->swPwrLimMotorStartThresholdTemp = in->uwPwrLimMotTempSTARTCe; // PWRLIM_START_THRESHOLD_TEMP; // Ce Q0
  117. out->swPwrLimMotorENDThresholdTemp = (in->uwPwrLimMotTempSTARTCe + in->uwPwrLimMotTempENDCe) >> 1; // in->uwPwrLimMotTempENDCe;
  118. out->uwPwrLimStartBatCap = in->uwPwrLimStartBatCap;
  119. out->uwPwrLimEndBatCap = in->uwPwrLimEndBatCap;
  120. if (in->swPwrLimW > ((SWORD)in->uwPwrErrW))
  121. {
  122. out->swMotorPwrLimitPu = (SWORD)((((ULONG)in->swPwrLimW - (ULONG)in->uwPwrErrW) << 15) / ulPbWt); // Q15
  123. }
  124. else
  125. {
  126. out->swMotorPwrLimitPu = 0;
  127. }
  128. /* 根据PCB温度线性限制功率系数,PuQ15 */
  129. out->swPwrLimTempGain = (out->swMotorPwrLimitPu >> 1) / (out->swPwrLimENDThresholdTemp - out->swPwrLimStartThresholdTemp);
  130. /* 根据PCB温度线性限制电流系数,PuQ14 */
  131. out->swCurLimTempGain = (out->swIqMaxPu * 5 >> 3) / (out->swPwrLimENDThresholdTemp - out->swPwrLimStartThresholdTemp);
  132. /* 根据MOTOR温度线性限制电流系数,PuQ14 */
  133. out->swCurLimMotorTempGain = (out->swIqMaxPu * 5 >> 3) / (out->swPwrLimMotorENDThresholdTemp - out->swPwrLimMotorStartThresholdTemp);
  134. /* 根据电量线性限制功率系数,PuQ15 */
  135. out->uwPwrlimBatCapCof = ((SLONG)out->swMotorPwrLimitPu * 3 >> 2) / (out->uwPwrLimStartBatCap - out->uwPwrLimEndBatCap);
  136. out->uwPwrLimPIKp = in->uwPwrLimPIKp; // q15
  137. out->uwPwrLimPIKi = in->uwPwrLimPIKi; // q15
  138. }
  139. /************************************************************************
  140. Function: pwr_voPwrLim;
  141. Description: Power Limit Using Kp;
  142. Call by:
  143. Input Variables:
  144. Output/Return Variables:
  145. Subroutine Call:
  146. Reference:
  147. ************************************************************************/
  148. SWORD swEmPwLimIqPu; // Q14
  149. void pwr_voPwrLim(PWRLIM_IN *in, PWRLIM_COF *cof, PWRLIM_OUT *out)
  150. {
  151. if (in->swMotorPwrPu > cof->swMotorPwrLimitPu)
  152. {
  153. if (in->swSpdPu >= 0)
  154. {
  155. swEmPwLimIqPu = (SWORD)((SLONG)(cof->swMotorPwrLimitPu - in->swMotorPwrPu) * cof->uwPwrLimKp >> 6) + cof->swIqMaxPu; // Q15+Q5-Q6=Q14
  156. if (swEmPwLimIqPu > cof->swIqMaxPu)
  157. {
  158. swEmPwLimIqPu = cof->swIqMaxPu;
  159. }
  160. else if (swEmPwLimIqPu < 0)
  161. {
  162. swEmPwLimIqPu = 0;
  163. }
  164. else
  165. {}
  166. out->swIqLimPu = swEmPwLimIqPu;
  167. }
  168. else
  169. {
  170. swEmPwLimIqPu = ((SLONG)(in->swMotorPwrPu - cof->swMotorPwrLimitPu) * cof->uwPwrLimKp >> 6) - cof->swIqMaxPu; // Q14
  171. if (swEmPwLimIqPu < -cof->swIqMaxPu)
  172. {
  173. swEmPwLimIqPu = -cof->swIqMaxPu;
  174. }
  175. else if (swEmPwLimIqPu > 0)
  176. {
  177. swEmPwLimIqPu = 0;
  178. }
  179. else
  180. {}
  181. out->swIqLimPu = swEmPwLimIqPu;
  182. }
  183. }
  184. else
  185. {
  186. if (in->swSpdPu >= 0)
  187. {
  188. out->swIqLimPu = cof->swIqMaxPu;
  189. }
  190. else
  191. {
  192. out->swIqLimPu = -cof->swIqMaxPu;
  193. }
  194. }
  195. }
  196. /************************************************************************
  197. Function: pwr_voPwrLim;
  198. Description: Power Limit Using Kp and Ki;
  199. Call by:
  200. Input Variables:
  201. Output/Return Variables:
  202. Subroutine Call:
  203. Reference:
  204. ************************************************************************/
  205. void pwr_voPwrLimPI(PWRLIM_IN *in, PWRLIM_COF *cof, PWRLIM_OUT *out)
  206. {
  207. SWORD swERROR, swErrorDeta;
  208. SLONG slERROR, slIqLimDetaP, slIqLimDetaI;
  209. SLONG slIqLimSum;
  210. SLONG slIqMaxLimSum ;
  211. static SWORD swPCBTempCurLimitPu, swMotorTempCurLimitPu;
  212. SWORD swMotorPwriqfdb;
  213. SWORD swPwrLimActualPu1 = cof->swMotorPwrLimitPu, swPwrLimActualPu2 = cof->swMotorPwrLimitPu; ///< Q15
  214. SWORD swIqlimPu1 = cof->swIqMaxPu, swIqlimPu2 = cof->swIqMaxPu; ///< Q14
  215. slIqMaxLimSum=(SLONG) cof->swIqMaxPu<<16;
  216. /* 根据温度限制功率,电机测试模式开放 */
  217. if (cp_stFlg.RunModelSelect == ClZLOOP)
  218. {
  219. if (in->swPCBTemp < cof->swPwrLimStartThresholdTemp)
  220. {
  221. swPwrLimActualPu1 = cof->swMotorPwrLimitPu;
  222. }
  223. else if (in->swPCBTemp < cof->swPwrLimENDThresholdTemp)
  224. {
  225. swPwrLimActualPu1 = cof->swMotorPwrLimitPu - ((in->swPCBTemp - cof->swPwrLimStartThresholdTemp) * cof->swPwrLimTempGain);
  226. }
  227. else
  228. {
  229. swPwrLimActualPu1 = cof->swMotorPwrLimitPu >> 1; ///< EndTemp时限制为1/2的功率
  230. }
  231. }
  232. /* 根据电池电量限制功率 */
  233. if (in->uwBatCap > cof->uwPwrLimStartBatCap)
  234. {
  235. swPwrLimActualPu2 = cof->swMotorPwrLimitPu;
  236. }
  237. else if (in->uwBatCap > cof->uwPwrLimEndBatCap)
  238. {
  239. swPwrLimActualPu2 = cof->swMotorPwrLimitPu - ((cof->uwPwrLimStartBatCap - in->uwBatCap) * cof->uwPwrlimBatCapCof);
  240. }
  241. else
  242. {
  243. swPwrLimActualPu2 = cof->swMotorPwrLimitPu >> 2; ///< EndTemp时限制为1/4的功率
  244. }
  245. out->swMotorPwrLimitActualPu = (swPwrLimActualPu1 < swPwrLimActualPu2) ? swPwrLimActualPu1 : swPwrLimActualPu2;
  246. if (cp_stFlg.RunModelSelect == CadAssist || cp_stFlg.RunModelSelect == TorqAssist)
  247. {
  248. /* 根据PCB温度限制电流 */
  249. if(in->swPCBTemp < cof->swPwrLimStartThresholdTemp)
  250. {
  251. swPCBTempCurLimitPu = cof->swIqMaxPu; // Q0, unit: 0.1w, Power limit value
  252. }
  253. else if(in->swPCBTemp < cof->swPwrLimENDThresholdTemp)
  254. {
  255. swPCBTempCurLimitPu = cof->swIqMaxPu - ((in->swPCBTemp - cof->swPwrLimStartThresholdTemp) * cof->swCurLimTempGain);
  256. }
  257. else
  258. {
  259. swPCBTempCurLimitPu = cof->swIqMaxPu - ((cof->swPwrLimENDThresholdTemp - cof->swPwrLimStartThresholdTemp) * cof->swCurLimTempGain);
  260. }
  261. /* 根据MOTOR温度限制电流 */
  262. if(in->swMotorTemp < cof->swPwrLimMotorStartThresholdTemp)
  263. {
  264. swMotorTempCurLimitPu = cof->swIqMaxPu; // Q0, unit: 0.1w, Power limit value
  265. }
  266. else if(in->swMotorTemp < cof->swPwrLimMotorENDThresholdTemp)
  267. {
  268. swMotorTempCurLimitPu = cof->swIqMaxPu - ((in->swMotorTemp - cof->swPwrLimMotorStartThresholdTemp) * cof->swCurLimMotorTempGain);
  269. }
  270. else
  271. {
  272. swMotorTempCurLimitPu =
  273. cof->swIqMaxPu - ((cof->swPwrLimMotorENDThresholdTemp - cof->swPwrLimMotorStartThresholdTemp) * cof->swCurLimMotorTempGain);
  274. }
  275. swIqlimPu1 = (swMotorTempCurLimitPu < swPCBTempCurLimitPu) ? swMotorTempCurLimitPu : swPCBTempCurLimitPu;
  276. }
  277. /* 功率限制PI调节:根据功率限制电流 */
  278. slERROR = out->swMotorPwrLimitActualPu - in->swMotorPwrPu;
  279. // slERROR = cof->swMotorPwrLimitPu - in->swMotorPwrPu;
  280. if (slERROR >= 32768)
  281. {
  282. slERROR = 32768;
  283. }
  284. else if (slERROR < -32768)
  285. {
  286. slERROR = -32768;
  287. }
  288. else
  289. {}
  290. swERROR = slERROR;
  291. swErrorDeta = swERROR - out->swErrorZ1;
  292. out->swErrorZ1 = swERROR;
  293. slIqLimDetaP = (SLONG)cof->uwPwrLimPIKp * swErrorDeta; // Q15+Q15 = Q30;
  294. slIqLimDetaI = (SLONG)cof->uwPwrLimPIKi * swERROR; // Q15+Q15 = Q30;
  295. slIqLimSum = out->slIqLimDetaSum + slIqLimDetaP + slIqLimDetaI;
  296. out->slIqLimDetaSum = slIqLimSum; // Q30
  297. //--------------------
  298. if(in->swMotoriqfdb<0)
  299. {
  300. swMotorPwriqfdb=-in->swMotoriqfdb;
  301. }
  302. else
  303. {
  304. swMotorPwriqfdb=in->swMotoriqfdb;
  305. }
  306. if(pwr_stPwrLimOut2.swErrorZ1 <0)
  307. {
  308. if(pwr_stPwrLimOut2.uwfisrttime==0)
  309. {
  310. // pwr_stPwrLimOut2.Mortor_time++;
  311. // if(pwr_stPwrLimOut2.Mortor_time>800) //
  312. {
  313. pwr_stPwrLimOut2.Mortor_time=8000;
  314. pwr_stPwrLimOut2.uwfisrttime=1000;
  315. out->slIqLimDetaSum= ( swMotorPwriqfdb-cof->swIqMaxPu)<<16;
  316. }
  317. }
  318. }
  319. else
  320. {
  321. if(pwr_stPwrLimOut2.Mortor_time>0)
  322. {
  323. pwr_stPwrLimOut2.Mortor_time--;
  324. }
  325. else
  326. {
  327. pwr_stPwrLimOut2.uwfisrttime=0;
  328. }
  329. }
  330. //---------------------
  331. if (out->slIqLimDetaSum > 0)
  332. {
  333. out->slIqLimDetaSum = 0;
  334. }
  335. else if (out->slIqLimDetaSum <-slIqMaxLimSum)// -1073741824)
  336. {
  337. out->slIqLimDetaSum = -slIqMaxLimSum;//-1073741824;
  338. }
  339. else
  340. {}
  341. out->swIqLimDetaSum = out->slIqLimDetaSum >> 16; // Q30-Q16 =Q14;
  342. swIqlimPu2 = cof->swIqMaxPu + out->swIqLimDetaSum;
  343. /* 电流限制值输出 */
  344. out->swIqLimPu = (swIqlimPu1 < swIqlimPu2) ? swIqlimPu1 : swIqlimPu2;
  345. // out->swIqLimPu = swIqlimPu2;
  346. if (out->swIqLimPu <= 0)
  347. {
  348. out->swIqLimPu = 0;
  349. }
  350. else
  351. {}
  352. }
  353. /************************************************************************
  354. Local Functions (N/A)
  355. ************************************************************************/
  356. /************************************************************************
  357. Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.
  358. All rights reserved.
  359. ************************************************************************/
  360. #ifdef _PWRLIM_C_
  361. #undef _PWRLIM_C_
  362. #endif
  363. /************************************************************************
  364. End of this File (EOF)!
  365. Do not put anything after this part!
  366. ************************************************************************/