torqobs.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /************************************************************************
  2. Project: Welling Motor Control Paltform
  3. Filename: torqobs.c
  4. Partner Filename: torqobs.h
  5. Description: Automatic current regulator
  6. Complier: IAR Embedded Workbench for ARM 8.40, IAR Systems.
  7. CPU TYPE : STM32F30x
  8. *************************************************************************
  9. Copyright (c) 2022 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 _TORQOBS_C_
  20. #define _TORQOBS_C_
  21. #endif
  22. /************************************************************************
  23. Included File:
  24. *************************************************************************/
  25. #include "torqobs.h"
  26. /************************************************************************
  27. Constant Table:
  28. *************************************************************************/
  29. /*************************************************************************
  30. extern Parameter
  31. **************************************************************************/
  32. TORQOBS_COEFIN torqobs_stCoefIn;
  33. TORQOBS_COEFOUT torqobs_stCoef;
  34. TORQOBS_IN torqobs_stCalIn;
  35. TORQOBS_OUT torqobs_stCalOut;
  36. /************************************************************************
  37. Exported Functions:
  38. *************************************************************************/
  39. /***************************************************************
  40. Function: ;
  41. Description:
  42. Call by: functions
  43. Input Variables:
  44. Output/Return Variables:
  45. Subroutine Call: N/A;
  46. Reference: N/A
  47. ****************************************************************/
  48. void torqobs_voInit(void)
  49. {
  50. torqobs_stCalOut.slSpdObsPu = 0;
  51. torqobs_stCalOut.slIqLoadPu = 0;
  52. torqobs_stCalOut.swErrZ1Pu = 0;
  53. torqobs_stCalOut.swIqLoadPu = 0;
  54. torqobs_stCalOut.swSpdObsPu = 0;
  55. torqobs_stCalOut.swSpdObsPu = 0;
  56. torqobs_stCalOut.swTorqObsPu = 0;
  57. }
  58. /***************************************************************
  59. Function: ;
  60. Description:
  61. Call by: functions
  62. Input Variables:
  63. Output/Return Variables:
  64. Subroutine Call: N/A;
  65. Reference: N/A
  66. ****************************************************************/
  67. void torqobs_voCoef(TORQOBS_COEFIN *in, TORQOBS_COEFOUT*out)
  68. {
  69. UWORD uwWebRadps;
  70. UWORD uwPbWt;
  71. UWORD uwWmb;
  72. UWORD uwTbUs;
  73. UWORD uwTbNm;
  74. UWORD uwJb;
  75. UWORD uwJmPu;
  76. UWORD uwFluxbWb;
  77. UWORD uwFluxPu;
  78. UWORD uwWtcPu;
  79. UWORD uwTCtrPu;
  80. ULONG ulJmPu;
  81. if (in->uwFbHz < 1)
  82. {
  83. in->uwFbHz = 1;
  84. }
  85. if (in->uwUbVt < 1)
  86. {
  87. in->uwUbVt = 1;
  88. }
  89. if (in->uwIbAp < 1)
  90. {
  91. in->uwIbAp = 1;
  92. }
  93. if (in->uwPairs < 1)
  94. {
  95. in->uwPairs = 1;
  96. }
  97. if (in->uwMtJm < 1)
  98. {
  99. in->uwMtJm = 1;
  100. }
  101. if (in->uwMtFlxWb < 1)
  102. {
  103. in->uwMtFlxWb = 1;
  104. }
  105. if (in->uwFTbsHz < 1)
  106. {
  107. in->uwFTbsHz = 1;
  108. }
  109. if (in->uwRatioJm > 10)
  110. {
  111. in->uwRatioJm = 10;
  112. }
  113. if (in->uwWtcHz > 50)
  114. {
  115. in->uwWtcHz = 50;
  116. }
  117. uwWebRadps = (ULONG)2 * 31416 * in->uwFbHz / 1000; /* unit: 0.1rad/s, Electrical radian frequency base */
  118. uwPbWt = (ULONG)3 * in->uwUbVt * in->uwIbAp / 100 >> 1; /* unit: 0.1w, Power base */
  119. uwWmb = uwWebRadps / in->uwPairs; /* unit: 0.1rad/s, Mechanical radian frequency base */
  120. uwTbUs = (ULONG)100000000 / uwWebRadps; /* unit: 0.1us, Time base */
  121. uwTbNm = (ULONG)uwPbWt * 1000 / uwWmb; /* unit: mNm, Torque base */
  122. uwJb = ((ULONG)uwTbNm * uwTbUs * 10) / uwWmb; /* unit: 10^-10*kg*m2, Rotational inertia base */
  123. uwJmPu = ((ULONG)in->uwMtJm * 1000) / uwJb; /* Q0, Rotational inertia */
  124. uwFluxbWb = ((ULONG)in->uwUbVt * 1000000) / uwWebRadps; /* unit: 0.001mWb, Flux linkage base */
  125. uwFluxPu = ((ULONG)in->uwMtFlxWb << 12) / uwFluxbWb; /* Q12, Flux linkage */
  126. uwTCtrPu = (ULONG)2 * 12868 * in->uwFbHz / in->uwFTbsHz; /* Q12, Speed control period Pu, pi(Q12)=12868 */
  127. /* Jm */
  128. //ulJmPu = uwJmPu;
  129. ulJmPu = (ULONG)(in->uwRatioJm + 1) * uwJmPu; // Q0
  130. /* Kp = Wtc * Jm /FluxF */
  131. uwWtcPu = (((ULONG)in->uwWtcHz << 15) / in->uwFbHz); // Q15 BW_HZ2PU(x)
  132. out->uwKpPu = (ulJmPu * uwWtcPu << 3) / uwFluxPu; // Q6
  133. /* Kit = Kp * Wtc * T_spd_ctrl */
  134. out->uwKitPu = (((ULONG)uwWtcPu * uwTCtrPu) >> 18) * out->uwKpPu * 4; // Q15
  135. if (out->uwKitPu < 1)
  136. {
  137. out->uwKitPu = 1;
  138. }
  139. out->ulJmPu_Inv = ((ULONG) 1 << 12) / ulJmPu; // Q12
  140. out->uwTCtrPu = uwTCtrPu; // Q12
  141. out->uwCur2TorqKPu = uwFluxPu; // Q12
  142. }
  143. /***************************************************************
  144. Function: ;
  145. Description:
  146. Call by: functions
  147. Input Variables:
  148. Output/Return Variables:
  149. Subroutine Call: N/A;
  150. Reference: N/A
  151. ****************************************************************/
  152. void torqobs_voCal(TORQOBS_IN *in, TORQOBS_COEFOUT *cof, TORQOBS_OUT *out)
  153. {
  154. SLONG slIqMaxPu; // Q30
  155. SLONG slIqMinPu; // Q30
  156. SLONG slSpdErrPu; // Q15
  157. SLONG slDeltaErrPu;
  158. SQWORD sqIqLoadPu;
  159. SQWORD sqIqpPu;
  160. SQWORD sqIqiPu;
  161. SLONG slDeltaTorqPu;
  162. SLONG slSpdObsPu;
  163. /* Coefficient get */
  164. slIqMaxPu = (SLONG)in->swIqMaxPu << 16; // Q14+Q16=Q30
  165. slIqMinPu = (SLONG)in->swIqMinPu << 16; // Q14+Q16=Q30
  166. /* Calculate the error */
  167. slSpdErrPu = (SLONG)in->swSpdPu - out->swSpdObsPu; // Q15
  168. if (slSpdErrPu > 32767)
  169. {
  170. slSpdErrPu = 32767;
  171. }
  172. else if (slSpdErrPu < -32767)
  173. {
  174. slSpdErrPu = -32767;
  175. }
  176. else
  177. {
  178. /* Nothing */
  179. }
  180. /* Calculate the delta error */
  181. slDeltaErrPu = slSpdErrPu - out->swErrZ1Pu; // Q15
  182. if (slDeltaErrPu > 32767)
  183. {
  184. slDeltaErrPu = 32767;
  185. }
  186. else if (slDeltaErrPu < -32768)
  187. {
  188. slDeltaErrPu = -32768;
  189. }
  190. else
  191. {
  192. /* Nothing */
  193. }
  194. sqIqpPu = ((SQWORD)slDeltaErrPu * cof->uwKpPu) << 9; // Q30
  195. /* Calculate the integral output */
  196. sqIqiPu = (SQWORD)slSpdErrPu * cof->uwKitPu; // Q30
  197. // if (sqIqiPu > 32768)
  198. // {
  199. // sqIqiPu = 32768;
  200. // }
  201. // else if (sqIqiPu < -32768)
  202. // {
  203. // sqIqiPu = -32768;
  204. // }
  205. // else
  206. // {}
  207. /* Calculate the Controller output */
  208. sqIqLoadPu = sqIqpPu + sqIqiPu + (SQWORD)out->slIqLoadPu; // Q30
  209. /* Iq output limit */
  210. if (sqIqLoadPu > slIqMaxPu)
  211. {
  212. out->slIqLoadPu = slIqMaxPu;
  213. }
  214. else if (sqIqLoadPu < slIqMinPu)
  215. {
  216. out->slIqLoadPu = slIqMinPu;
  217. }
  218. else
  219. {
  220. out->slIqLoadPu = (SLONG)sqIqLoadPu;
  221. }
  222. out->swIqLoadPu = out->slIqLoadPu >> 16; // Q30-Q16=Q14
  223. out->swErrZ1Pu = (SWORD)slSpdErrPu;
  224. out->swTorqObsPu = (SWORD)-(SWORD)((SLONG)out->swIqLoadPu * cof->uwCur2TorqKPu >> 12); // Q14+Q12-Q12=Q14
  225. slDeltaTorqPu = (SLONG)cof->uwCur2TorqKPu * (in->swIqfbkPu + out->swIqLoadPu) >> 12; // Q14
  226. slSpdObsPu = out->slSpdObsPu + ((SLONG)slDeltaTorqPu * cof->uwTCtrPu >> 9) * cof->ulJmPu_Inv; // Q29
  227. if(slSpdObsPu >= 531502202L)
  228. {
  229. out->slSpdObsPu = 531502202L;
  230. }
  231. else if(slSpdObsPu <= -531502202L)
  232. {
  233. out->slSpdObsPu = -531502202L;
  234. }
  235. else
  236. {
  237. out->slSpdObsPu = slSpdObsPu;
  238. }
  239. out->swSpdObsPu = out->slSpdObsPu >> 14; // Q15
  240. out->slDeltaTorqPu = slDeltaTorqPu;
  241. }
  242. /*************************************************************************
  243. Local Functions (N/A)
  244. *************************************************************************/
  245. /************************************************************************
  246. Copyright (c) 2018 Welling Motor Technology(Shanghai) Co., Ltd.
  247. All rights reserved.
  248. *************************************************************************/
  249. #ifdef _TORQOBS_C_
  250. #undef _TORQOBS_C_
  251. #endif
  252. /*************************************************************************
  253. End of this File (EOF)!
  254. Do not put anything after this part!
  255. *************************************************************************/