asr_new.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /************************************************************************
  2. Project: Welling Motor Control Paltform
  3. Filename: asr.c
  4. Partner Filename: asr.h
  5. Description: Automatic speed regulator
  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. ************************************************************************/
  15. /************************************************************************
  16. Beginning of File, do not put anything above here except notes
  17. Compiler Directives:
  18. *************************************************************************/
  19. #ifndef _ASR_NEW_C_
  20. #define _ASR_NEW_C_
  21. #endif
  22. /************************************************************************
  23. Included File:
  24. *************************************************************************/
  25. #include "syspar.h"
  26. #include "user.h"
  27. /************************************************************************
  28. Constant Table:
  29. *************************************************************************/
  30. /************************************************************************
  31. Exported Functions:
  32. *************************************************************************/
  33. /***************************************************************
  34. Function: asr_voSpdPIInit;
  35. Description: Speed PI initialization
  36. Call by: functions in main loop;
  37. Input Variables: N/A
  38. Output/Return Variables: N/A
  39. Subroutine Call: N/A;
  40. Reference: N/A
  41. ****************************************************************/
  42. void asrnew_voSpdPIInit(void)
  43. {
  44. asr_stSpdPIOut.slIqiPu = 0;
  45. asr_stSpdPIOut.slIqSumPu = 0;
  46. asr_stSpdPIOut.slIqRefPu = 0;
  47. asr_stSpdPIOut.swIqRefPu = 0;
  48. asr_stSpdPIOut.swErrZ1Pu = 0;
  49. }
  50. /***************************************************************
  51. Function: asr_voSpdPICoef;
  52. Description: Coefficient calculation for "asr_voSpdPICoef"
  53. Call by: functions in main loop;
  54. Input Variables: ASR_SPDPI_COFIN
  55. Output/Return Variables: ASR_SPDPI_COF
  56. Subroutine Call: N/A;
  57. Reference: N/A
  58. ****************************************************************/
  59. void asrnew_voSpdPICoef(ASRNEW_SPDPI_COFIN *in, ASRNEW_SPDPI_COF *out)
  60. {
  61. ULONG ulWebRadps;
  62. UWORD uwPbWt;
  63. UWORD uwWmb;
  64. UWORD uwTbUs;
  65. UWORD uwTbNm;
  66. UWORD uwJb;
  67. UWORD uwJmPu;
  68. UWORD uwFluxbWb;
  69. UWORD uwFluxPu;
  70. UWORD uwWvcPu;
  71. UWORD uwTCtrPu;
  72. ULONG ulJmPu;
  73. if (in->uwFbHz < 1)
  74. {
  75. in->uwFbHz = 1;
  76. }
  77. if (in->uwUbVt < 1)
  78. {
  79. in->uwUbVt = 1;
  80. }
  81. if (in->uwIbAp < 1)
  82. {
  83. in->uwIbAp = 1;
  84. }
  85. if (in->uwPairs < 1)
  86. {
  87. in->uwPairs = 1;
  88. }
  89. if (in->uwMtJm < 1)
  90. {
  91. in->uwMtJm = 1;
  92. }
  93. if (in->uwMtFlxWb < 1)
  94. {
  95. in->uwMtFlxWb = 1;
  96. }
  97. if (in->uwFTbsHz < 1)
  98. {
  99. in->uwFTbsHz = 1;
  100. }
  101. if (in->uwRatioJm > 10)
  102. {
  103. in->uwRatioJm = 10;
  104. }
  105. if (in->uwWvcHz > 30)
  106. {
  107. in->uwWvcHz = 30;
  108. }
  109. if (in->uwMcoef > 20)
  110. {
  111. in->uwMcoef = 20;
  112. }
  113. ulWebRadps = (ULONG)2 * 31416 * in->uwFbHz / 1000; /* unit: 0.1rad/s, Electrical radian frequency base */
  114. uwPbWt = (ULONG)3 * in->uwUbVt * in->uwIbAp / 100 >> 1; /* unit: 0.1w, Power base */
  115. uwWmb = ulWebRadps / in->uwPairs; /* unit: 0.1rad/s, Mechanical radian frequency base */
  116. uwTbUs = (ULONG)100000000 / ulWebRadps; /* unit: 0.1us, Time base */
  117. uwTbNm = (ULONG)uwPbWt * 1000 / uwWmb; /* unit: mNm, Torque base */
  118. uwJb = ((ULONG)uwTbNm * uwTbUs * 10) / uwWmb; /* unit: 10^-10*kg*m2, Rotational inertia base */
  119. uwJmPu = ((ULONG)in->uwMtJm * 1000) / uwJb; /* Q0, Rotational inertia */
  120. uwFluxbWb = ((ULONG)in->uwUbVt * 1000000) / ulWebRadps; /* unit: 0.01mWb, Flux linkage base */
  121. uwFluxPu = ((ULONG)in->uwMtFlxWb << 12) / uwFluxbWb; /* Q12, Flux linkage */
  122. uwTCtrPu = (ULONG)2 * 12868 * in->uwFbHz / in->uwFTbsHz; /* Q12, Speed control period Pu, pi(Q12)=12868 */
  123. /* Jm */
  124. ulJmPu = (ULONG)(in->uwRatioJm + 1) * uwJmPu; // Q0
  125. /* Kp = Wvc*Jm/FluxF */
  126. uwWvcPu = (((ULONG)in->uwWvcHz << 15) / in->uwFbHz); // Q15 BW_HZ2PU(x)
  127. // out->uwKpPu = (ulJmPu * uwWvcPu << 3) / uwFluxPu; // Q0+Q15+Q3-Q12=Q6
  128. // // out->uwKpPu = (ulJmPu * uwWvcPu ) / uwFluxPu;
  129. // /* Kit = Kp*T_spd_ctrl*Wvc/M */
  130. // out->uwKitPu = ((((ULONG)uwWvcPu * uwTCtrPu) >> 18) * out->uwKpPu) / in->uwMcoef; // Q15+Q12-Q18+Q6=Q15
  131. // if (out->uwKitPu < 1)
  132. // {
  133. // out->uwKitPu = 1;
  134. // }
  135. //
  136. // /* Kb = 1/Kp */
  137. // out->uwKbPu = ((ULONG)1 << 15) / out->uwKpPu; // Q15-Q6=Q9
  138. //
  139. // /* Kb = Ki/Kp */
  140. // out->uwKsPu = uwWvcPu / in->uwMcoef; //Q15
  141. out->uwKpPu = 1000;
  142. out->uwKitPu = 100;
  143. out->uwKsPu = 0;
  144. }
  145. /***************************************************************
  146. Function: asr_voSpdPI;
  147. Description: speed PI regulator;
  148. Call by: functions in TBS;
  149. Input Variables: ASR_SPDPI_IN,SPD_SPDPI_COF
  150. Output/Return Variables: ASR_SPDPI_OUT
  151. Subroutine Call: N/A;
  152. Reference: N/A
  153. ****************************************************************/
  154. SQWORD IqiPu;
  155. SQWORD IqiPuZ1;
  156. SQWORD IqiAnti;
  157. SWORD tstIq;
  158. void asrnew_voSpdPI(ASRNEW_SPDPI_IN *in, ASRNEW_SPDPI_COF *cof, ASRNEW_SPDPI_OUT *out)
  159. {
  160. SLONG slIqMaxPu; // Q30
  161. SLONG slIqMinPu; // Q30
  162. SLONG slSpdErrPu; // Q15
  163. SQWORD sqIqRefPu;
  164. SQWORD sqIqpPu;
  165. SQWORD sqIqiPu;
  166. /* Coefficient get */
  167. slIqMaxPu = (SLONG)in->swIqMaxPu << 16; // Q14+Q16=Q30
  168. slIqMinPu = (SLONG)in->swIqMinPu << 16; // Q14+Q16=Q30
  169. /* Calculate the error */
  170. slSpdErrPu = (SLONG)in->swSpdRefPu - in->swSpdFdbPu; // Q15
  171. if (slSpdErrPu > 32767)
  172. {
  173. slSpdErrPu = 32767;
  174. }
  175. else if (slSpdErrPu < -32767)
  176. {
  177. slSpdErrPu = -32767;
  178. }
  179. else
  180. {
  181. /* Nothing */
  182. }
  183. sqIqpPu = ((SQWORD)slSpdErrPu * cof->uwKpPu) << 9; // Q30
  184. /* Calculate the integral output */
  185. sqIqiPu = (SQWORD)slSpdErrPu * cof->uwKitPu; // Q30
  186. // if (sqIqiPu > 32768)
  187. // {
  188. // sqIqiPu = 32768;
  189. // }
  190. // else if (sqIqiPu < -32768)
  191. // {
  192. // sqIqiPu = -32768;
  193. // }
  194. // else
  195. // {}
  196. IqiPu = sqIqiPu + IqiPuZ1 + (IqiAnti * cof->uwKsPu >> 15); //Q30
  197. // if (IqiPu > slIqMaxPu)
  198. // {
  199. // IqiPu = slIqMaxPu;
  200. // }
  201. // else if (IqiPu < slIqMinPu)
  202. // {
  203. // IqiPu = slIqMinPu;
  204. // }
  205. // else
  206. // {}
  207. IqiPuZ1 = IqiPu;
  208. /* Calculate the Controller output */
  209. sqIqRefPu = sqIqpPu + IqiPu; // Q30
  210. tstIq = sqIqRefPu >> 16;
  211. /* Iq output limit */
  212. if (sqIqRefPu > slIqMaxPu)
  213. {
  214. out->slIqRefPu = slIqMaxPu;
  215. }
  216. else if (sqIqRefPu < slIqMinPu)
  217. {
  218. out->slIqRefPu = slIqMinPu;
  219. }
  220. else
  221. {
  222. out->slIqRefPu = (SLONG)sqIqRefPu;
  223. }
  224. /* Anti-Windup */
  225. IqiAnti = (SQWORD)out->slIqRefPu - sqIqRefPu; //Q30
  226. out->swIqRefPu = out->slIqRefPu >> 16; // Q30-Q16=Q14
  227. out->swErrZ1Pu = (SWORD)slSpdErrPu;
  228. }
  229. /************************************************************************
  230. Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.
  231. All rights reserved.
  232. *************************************************************************/
  233. #ifdef _ASR_C_
  234. #undef _ASR_C_
  235. #endif
  236. /*************************************************************************
  237. End of this File (EOF)��
  238. Do not put anything after this part!
  239. *************************************************************************/