pwrlim.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  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. UWORD 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. static SWORD swPCBTempCurLimitPu, swMotorTempCurLimitPu;
  211. SWORD swPwrLimActualPu1 = cof->swMotorPwrLimitPu, swPwrLimActualPu2 = cof->swMotorPwrLimitPu; ///< Q15
  212. SWORD swIqlimPu1 = cof->swIqMaxPu, swIqlimPu2 = cof->swIqMaxPu; ///< Q14
  213. /* 根据温度限制功率,电机测试模式开放 */
  214. if (cp_stFlg.RunModelSelect == ClZLOOP)
  215. {
  216. if (in->swPCBTemp < cof->swPwrLimStartThresholdTemp)
  217. {
  218. swPwrLimActualPu1 = cof->swMotorPwrLimitPu;
  219. }
  220. else if (in->swPCBTemp < cof->swPwrLimENDThresholdTemp)
  221. {
  222. swPwrLimActualPu1 = cof->swMotorPwrLimitPu - ((in->swPCBTemp - cof->swPwrLimStartThresholdTemp) * cof->swPwrLimTempGain);
  223. }
  224. else
  225. {
  226. swPwrLimActualPu1 = cof->swMotorPwrLimitPu >> 1; ///< EndTemp时限制为1/2的功率
  227. }
  228. }
  229. /* 根据电池电量限制功率 */
  230. if (in->uwBatCap > cof->uwPwrLimStartBatCap)
  231. {
  232. swPwrLimActualPu2 = cof->swMotorPwrLimitPu;
  233. }
  234. else if (in->uwBatCap > cof->uwPwrLimEndBatCap)
  235. {
  236. swPwrLimActualPu2 = cof->swMotorPwrLimitPu - ((cof->uwPwrLimStartBatCap - in->uwBatCap) * cof->uwPwrlimBatCapCof);
  237. }
  238. else
  239. {
  240. swPwrLimActualPu2 = cof->swMotorPwrLimitPu >> 2; ///< EndTemp时限制为1/4的功率
  241. }
  242. out->swMotorPwrLimitActualPu = (swPwrLimActualPu1 < swPwrLimActualPu2) ? swPwrLimActualPu1 : swPwrLimActualPu2;
  243. if (cp_stFlg.RunModelSelect == CadAssist || cp_stFlg.RunModelSelect == TorqAssist)
  244. {
  245. /* 根据PCB温度限制电流 */
  246. if(in->swPCBTemp < cof->swPwrLimStartThresholdTemp)
  247. {
  248. swPCBTempCurLimitPu = cof->swIqMaxPu; // Q0, unit: 0.1w, Power limit value
  249. }
  250. else if(in->swPCBTemp < cof->swPwrLimENDThresholdTemp)
  251. {
  252. swPCBTempCurLimitPu = cof->swIqMaxPu - ((in->swPCBTemp - cof->swPwrLimStartThresholdTemp) * cof->swCurLimTempGain);
  253. }
  254. else
  255. {
  256. swPCBTempCurLimitPu = cof->swIqMaxPu - ((cof->swPwrLimENDThresholdTemp - cof->swPwrLimStartThresholdTemp) * cof->swCurLimTempGain);
  257. }
  258. /* 根据MOTOR温度限制电流 */
  259. if(in->swMotorTemp < cof->swPwrLimMotorStartThresholdTemp)
  260. {
  261. swMotorTempCurLimitPu = cof->swIqMaxPu; // Q0, unit: 0.1w, Power limit value
  262. }
  263. else if(in->swMotorTemp < cof->swPwrLimMotorENDThresholdTemp)
  264. {
  265. swMotorTempCurLimitPu = cof->swIqMaxPu - ((in->swMotorTemp - cof->swPwrLimMotorStartThresholdTemp) * cof->swCurLimMotorTempGain);
  266. }
  267. else
  268. {
  269. swMotorTempCurLimitPu =
  270. cof->swIqMaxPu - ((cof->swPwrLimMotorENDThresholdTemp - cof->swPwrLimMotorStartThresholdTemp) * cof->swCurLimMotorTempGain);
  271. }
  272. swIqlimPu1 = (swMotorTempCurLimitPu < swPCBTempCurLimitPu) ? swMotorTempCurLimitPu : swPCBTempCurLimitPu;
  273. }
  274. /* 功率限制PI调节:根据功率限制电流 */
  275. slERROR = out->swMotorPwrLimitActualPu - in->swMotorPwrPu;
  276. // slERROR = cof->swMotorPwrLimitPu - in->swMotorPwrPu;
  277. if (slERROR >= 32768)
  278. {
  279. slERROR = 32768;
  280. }
  281. else if (slERROR < -32768)
  282. {
  283. slERROR = -32768;
  284. }
  285. else
  286. {}
  287. swERROR = slERROR;
  288. swErrorDeta = swERROR - out->swErrorZ1;
  289. out->swErrorZ1 = swERROR;
  290. slIqLimDetaP = (SLONG)cof->uwPwrLimPIKp * swErrorDeta; // Q15+Q15 = Q30;
  291. slIqLimDetaI = (SLONG)cof->uwPwrLimPIKi * swERROR; // Q15+Q15 = Q30;
  292. slIqLimSum = out->slIqLimDetaSum + slIqLimDetaP + slIqLimDetaI;
  293. out->slIqLimDetaSum = slIqLimSum; // Q30
  294. if (out->slIqLimDetaSum > 0)
  295. {
  296. out->slIqLimDetaSum = 0;
  297. }
  298. else if (out->slIqLimDetaSum < -1073741824)
  299. {
  300. out->slIqLimDetaSum = -1073741824;
  301. }
  302. else
  303. {}
  304. out->swIqLimDetaSum = out->slIqLimDetaSum >> 16; // Q30-Q16 =Q14;
  305. swIqlimPu2 = cof->swIqMaxPu + out->swIqLimDetaSum;
  306. /* 电流限制值输出 */
  307. out->swIqLimPu = (swIqlimPu1 < swIqlimPu2) ? swIqlimPu1 : swIqlimPu2;
  308. // out->swIqLimPu = swIqlimPu2;
  309. if (out->swIqLimPu <= 0)
  310. {
  311. out->swIqLimPu = 0;
  312. }
  313. else
  314. {}
  315. }
  316. /************************************************************************
  317. Local Functions (N/A)
  318. ************************************************************************/
  319. /************************************************************************
  320. Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.
  321. All rights reserved.
  322. ************************************************************************/
  323. #ifdef _PWRLIM_C_
  324. #undef _PWRLIM_C_
  325. #endif
  326. /************************************************************************
  327. End of this File (EOF)!
  328. Do not put anything after this part!
  329. ************************************************************************/