spdctrmode.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. /************************************************************************
  2. Project: Welling Motor Control Paltform
  3. Filename: spdctrmode.c
  4. Partner Filename: spdctrmode.h
  5. Description: Speed control mode
  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 _SPDCTRMODE_C_
  20. #define _SPDCTRMODE_C_
  21. #endif
  22. /************************************************************************
  23. Included File
  24. *************************************************************************/
  25. #include "syspar.h"
  26. #include "user.h"
  27. #include "AssistCurve.h"
  28. #include "cmdgennew.h"
  29. #include "CodePara.h"
  30. #include "FSM_2nd.h"
  31. #include "api.h"
  32. /************************************************************************
  33. Constant Table (N/A)
  34. *************************************************************************/
  35. /************************************************************************
  36. Private Variables
  37. *************************************************************************/
  38. static LPF_OUT swTmpSpdRateLpf;
  39. static SWORD swTmpSpdRate = 0;
  40. static SWORD swTmpSpdFbkPuZ1 = 0;
  41. static SWORD swSpdRateAbsPu;
  42. static SWORD swTestIqref;
  43. static UWORD DCPswitch = 0;
  44. static CRD_PARK_IN Test_U_in;
  45. static CRD_PARK_OUT Test_U_out;
  46. /*************************************************************************
  47. Exported Functions (N/A)
  48. *************************************************************************/
  49. /***************************************************************
  50. Function: scm_voSpdCtrMdInit;
  51. Description: Speed control mode initializing function
  52. Call by: rmd_voModeSchd();
  53. Input Variables: N/A
  54. Output/Return Variables: N/A
  55. Subroutine Call: ...;
  56. Reference: N/A
  57. ****************************************************************/
  58. void scm_voSpdCtrMdInit(void)
  59. {
  60. // /* PWM init */
  61. // sysctrl_voPwmInit();
  62. /*cmd handle Initial */
  63. cmd_voCmdInit();
  64. /* Current PI init */
  65. acr_voCurPIInit();
  66. /* Current decoupling init */
  67. acr_voUdqDcpInit();
  68. /* Sensorless observer init */
  69. obs_voObsInit();
  70. /* SPI position sensor init */
  71. spi_voResolverInit();
  72. /* Speed PI init */
  73. asr_voSpdPIInit();
  74. /* Flux weakening init */
  75. flx_voInit();
  76. // fw_voInit();
  77. /* Power Limit init */
  78. pwr_voPwrLimInit();
  79. /* SVPWM init */
  80. pwm_voInit();
  81. /* Dead time init */
  82. dbc_voDBCompInit();
  83. /* Contant voltage brake init */
  84. cvb_voBrakeInit();
  85. #ifdef RUN_ARCH_SIM
  86. /* switchHall init */
  87. switchhall_voInit();
  88. #endif
  89. /* Align pos startup open2clz clzloop init */
  90. align_voInit();
  91. /* Torque observer init */
  92. torqobs_voInit();
  93. /* Global variablles init */
  94. scm_stSpdFbkLpf.slY.sw.hi = 0;
  95. scm_swSpdRefPu = 0;
  96. scm_swUalphaPu = 0; // Q14
  97. scm_swUbetaPu = 0; // Q14
  98. scm_stIqLoadLpf.slY.sl = 0;
  99. scm_stIdFbkLpf.slY.sl = 0; // Id feedback LPF
  100. scm_stIqFbkLpf.slY.sl = 0; // Iq feedback LPF
  101. scm_swIdRefPu = 0; // Q14
  102. scm_swIqRefPu = 0; // Q14
  103. scm_uwAngRefPu = 0; // Q15
  104. scm_uwAngParkPu = 0; // Q15
  105. scm_uwAngIParkPu = 0; // Q15
  106. scm_swRotateDir = 1; // Direction of motor rotate
  107. scm_ulStatCt = 0; // Status hold time count
  108. scm_uwAngManuPu = 0; // Q15, Angle given manually
  109. scm_slAngManuPu = 0;
  110. scm_slDragSpdPu = 0; // Q15, Drag speed
  111. scm_slDragSpdRefPu = 0; // Q29, intermediate Drag speed
  112. scm_blCurSwitchOvrFlg = FALSE; // Current switch over flag
  113. scm_blAngSwitchOvrFlg = FALSE; // Angle switch over flag
  114. scm_uwAngSwitchK = 0; // Angle switch weight value
  115. scm_swMotorPwrInWt = 0; // unit: w, Input power of motor
  116. scm_blCoefUpdateFlg = FALSE; // Coefficient update flag
  117. scm_stSpdFbkLpf.slY.sl = 0; // Speed feedback LPF
  118. scm_uwSpdFbkLpfAbsPu = 0; // Q15, Speed feedback LPF absolute
  119. scm_swMotorPwrInPu = 0; // Q15, Input power of motor
  120. scm_stMotoPwrInLpf.slY.sl = 0; // Input power of motor after LPF
  121. scm_stPCBTempLpf.slY.sl = 0;
  122. scm_swMotorPwrInLpfWt = 0; // unit: 0.1w, Input power of motor after LPF
  123. scm_uwMotorPwrInAvgPu = 0; // Q15, Input power of motor after average filter
  124. scm_swIdFdbLpfPu = 0;
  125. scm_swIqFdbLpfPu = 0;
  126. scm_swUdRefPu = 0;
  127. scm_swUqRefPu = 0;
  128. scm_swUalphaFbkPu = 0;
  129. scm_swUbetaFbkPu = 0;
  130. scm_swUalphaRefPu = 0;
  131. scm_swUbetaRefPu = 0;
  132. scm_swUalphaCompPu = 0;
  133. scm_swUbetaCompPu = 0;
  134. scm_uwHfiAngZ1Pu = 0;
  135. scm_slAngSumPu = 0;
  136. scm_slAngErrPu = 0;
  137. scm_blAngSumOvrFlg = FALSE;
  138. scm_uwRunMdSw = 1;
  139. scm_ulRunMdSwCt = 0;
  140. scm_ulCloseCt = 0;
  141. scm_uwStartMd = cp_stControlPara.swStartMode;
  142. scm_uwStartMdSw = scm_uwStartMd;
  143. scm_uwInitPosMd = cp_stControlPara.swInitPosMode;
  144. scm_uwInitPosMdSw = scm_uwInitPosMd;
  145. scm_uwHfiOvrCnt = 0;
  146. scm_slIdRefPu = 0;
  147. /* Private variables init */
  148. swTmpSpdRateLpf.slY.sl = 0;
  149. swTmpSpdRate = 0;
  150. swTmpSpdFbkPuZ1 = 0;
  151. swSpdRateAbsPu = 0;
  152. swTestIqref = 0;
  153. DCPswitch = 0;
  154. }
  155. /***************************************************************
  156. Function: scm_voSpdCtrMdCoef;
  157. Description: Speed control mode TBS scheduler
  158. Call by: tbs_voIsr();
  159. Input Variables: N/A
  160. Output/Return Variables: N/A
  161. Subroutine Call: ...;
  162. Reference: N/A
  163. ****************************************************************/
  164. void scm_voSpdCtrMdCoef(void)
  165. {
  166. ULONG ulLpfTm; // unit: us
  167. SLONG slLqPu = 0;
  168. ULONG ulAccel100rpmpsPu = USER_MOTOR_100RPMPS2PU_Q29;
  169. if (ABS(scm_swIqRefPu) < mn_swIqTurn1Pu)
  170. {
  171. scm_uwLqPu = cof_uwLqPu;
  172. }
  173. else
  174. {
  175. slLqPu = mn_slLqTurn1Pu + (((SLONG)ABS(scm_swIqRefPu) - mn_swIqTurn1Pu) * mn_swKLqSat >> 10); // Q10
  176. if (slLqPu < cof_uwLqMinPu)
  177. {
  178. scm_uwLqPu = cof_uwLqMinPu;
  179. }
  180. else if (slLqPu > cof_uwLqPu)
  181. {
  182. scm_uwLqPu = cof_uwLqPu;
  183. }
  184. else
  185. {
  186. scm_uwLqPu = (UWORD)slLqPu;
  187. }
  188. }
  189. spi_stResolverCoefIn.uwFbHz = cof_uwFbHz;
  190. spi_stResolverCoefIn.uwFreqTbcHz = FTBC_HZ;
  191. spi_stResolverCoefIn.uwSpdPllWvcHz = 30;//cp_stControlPara.swObsSpdPLLBandWidthHz; // Real Value, Unit:Hz
  192. spi_stResolverCoefIn.uwSpdPllMcoef = 2;//cp_stControlPara.swObsSpdPLLM;
  193. spi_voResolverCoef(&spi_stResolverCoefIn, &spi_stResolverCoef);
  194. /* Sensorless observer coefficient calculate */
  195. obs_stObsCoefIn.uwRbOm = cof_uwRbOm; // Real Value, unit: 0.01Ohm, Resistance base
  196. obs_stObsCoefIn.uwLbHm = cof_uwLbHm; // Real Value, unit: 0.01mH, Inductance base
  197. obs_stObsCoefIn.uwFluxbWb = cof_uwFluxbWb; // Real Value, unit: 0.01mWb, Flux linkage base
  198. obs_stObsCoefIn.uwFbHz = cof_uwFbHz; // Real Value, Unit:Hz frequency base
  199. obs_stObsCoefIn.uwRsOm = cp_stMotorPara.swRsOhm; // Real Value, unit: 0.01Ohm, Resistance base
  200. obs_stObsCoefIn.uwLqHm = (UWORD)(((ULONG)scm_uwLqPu * cof_uwLbHm) >> 10); // Real Value, unit: 0.01mH, q Inductance
  201. obs_stObsCoefIn.uwLdHm = cp_stMotorPara.swLdmH; // Real Value, unit: 0.01mH, d Inductance
  202. obs_stObsCoefIn.uwFluxWb = cp_stMotorPara.swFluxWb; // Real Value, unit: 0.01mWb, Flux linkage
  203. obs_stObsCoefIn.uwFreqTbcHz = FTBC_HZ; // Real Value, Unit:Hz Tbc
  204. obs_stObsCoefIn.uwFluxDampingRatio = cp_stControlPara.swObsFluxPIDampratio; // Real Value, unit:0.1
  205. obs_stObsCoefIn.uwFluxCrossFreqHz = cp_stControlPara.swObsFluxPICrossfreHz; // Real Value, unit:Hz
  206. obs_stObsCoefIn.uwSpdPllWvcHz = cp_stControlPara.swObsSpdPLLBandWidthHz; // Real Value, Unit:Hz
  207. obs_stObsCoefIn.uwSpdPllMcoef = cp_stControlPara.swObsSpdPLLM;
  208. obs_voObsCoef(&obs_stObsCoefIn, &obs_stObsCoefPu);
  209. /* Speed PI coefficient calculate */
  210. asr_stSpdPICoefIn.uwUbVt = VBASE;
  211. asr_stSpdPICoefIn.uwIbAp = IBASE;
  212. asr_stSpdPICoefIn.uwFbHz = FBASE;
  213. asr_stSpdPICoefIn.uwFTbsHz = FTBS_HZ;
  214. asr_stSpdPICoefIn.uwPairs = cp_stMotorPara.swMotrPolePairs;
  215. asr_stSpdPICoefIn.uwMtJm = cp_stMotorPara.swJD;
  216. asr_stSpdPICoefIn.uwMtFlxWb = cp_stMotorPara.swFluxWb;
  217. asr_stSpdPICoefIn.uwMcoef = cp_stControlPara.swAsrPIM;
  218. asr_stSpdPICoefIn.uwWvcHz = cp_stControlPara.swAsrPIBandwidth;
  219. asr_stSpdPICoefIn.uwRatioJm = cp_stControlPara.swAsrSpdInerRate;
  220. asr_voSpdPICoef(&asr_stSpdPICoefIn, &asr_stSpdPICoef);
  221. /* Torque Observe coefficient calculate */
  222. torqobs_stCoefIn.uwUbVt = VBASE;
  223. torqobs_stCoefIn.uwIbAp = IBASE;
  224. torqobs_stCoefIn.uwFbHz = FBASE;
  225. torqobs_stCoefIn.uwFTbsHz = FTBS_HZ;
  226. torqobs_stCoefIn.uwPairs = cp_stMotorPara.swMotrPolePairs;
  227. torqobs_stCoefIn.uwMtJm = cp_stMotorPara.swJD;
  228. torqobs_stCoefIn.uwMtFlxWb = cp_stMotorPara.swFluxWb;
  229. torqobs_stCoefIn.uwWtcHz = 50; // cp_stControlPara.swAsrPIBandwidth;
  230. torqobs_stCoefIn.uwRatioJm = cp_stControlPara.swAsrSpdInerRate;
  231. torqobs_voCoef(&torqobs_stCoefIn, &torqobs_stCoef);
  232. mth_voLPFilterCoef(1000000 / 50, FTBS_HZ, &scm_stIqLoadLpf.uwKx); //50Hz
  233. /* Id PI coefficient calculate */
  234. acr_stCurIdPICoefIn.uwFbHz = FBASE;
  235. acr_stCurIdPICoefIn.uwUbVt = VBASE;
  236. acr_stCurIdPICoefIn.uwIbAp = IBASE;
  237. acr_stCurIdPICoefIn.uwLHm = cp_stMotorPara.swLdmH;
  238. acr_stCurIdPICoefIn.uwMtRsOh = cp_stMotorPara.swRsOhm;
  239. acr_stCurIdPICoefIn.uwFTbcHz = FTBC_HZ;
  240. acr_stCurIdPICoefIn.uwRaCoef = cp_stControlPara.swAcrRaCoef; // Coefficient of Active Resistance
  241. acr_stCurIdPICoefIn.uwWicHz = cp_stControlPara.swAcrPIBandwidth; // Current loop frequency bandwidth
  242. acr_voCurPICoef(&acr_stCurIdPICoefIn, &acr_stCurIdPICoef);
  243. /* Iq PI coefficient calculate */
  244. acr_stCurIqPICoefIn.uwFbHz = FBASE;
  245. acr_stCurIqPICoefIn.uwUbVt = VBASE;
  246. acr_stCurIqPICoefIn.uwIbAp = IBASE;
  247. acr_stCurIqPICoefIn.uwLHm = cp_stMotorPara.swLqmH;
  248. acr_stCurIqPICoefIn.uwMtRsOh = cp_stMotorPara.swRsOhm;
  249. acr_stCurIqPICoefIn.uwFTbcHz = FTBC_HZ;
  250. acr_stCurIqPICoefIn.uwRaCoef = cp_stControlPara.swAcrRaCoef;
  251. acr_stCurIqPICoefIn.uwWicHz = cp_stControlPara.swAcrPIBandwidth;
  252. acr_voCurPICoef(&acr_stCurIqPICoefIn, &acr_stCurIqPICoef);
  253. /* Current decoupling coefficient calculate */
  254. acr_stUdqDcpCoefIn.uwLdHm = cp_stMotorPara.swLdmH;
  255. acr_stUdqDcpCoefIn.uwLqHm = cp_stMotorPara.swLqmH;
  256. acr_stUdqDcpCoefIn.uwMtFlxWb = cp_stMotorPara.swFluxWb;
  257. acr_stUdqDcpCoefIn.uwUbVt = VBASE;
  258. acr_stUdqDcpCoefIn.uwFbHz = FBASE;
  259. acr_stUdqDcpCoefIn.uwIbAp = IBASE;
  260. acr_voUdqDcpCoef(&acr_stUdqDcpCoefIn, &acr_stUdqDcpCoef);
  261. /* Id feedback low pass filter coef */
  262. ulLpfTm = 1000000 / cp_stControlPara.swAcrCurFbLpfFre;
  263. mth_voLPFilterCoef(ulLpfTm, FTBC_HZ, &scm_stIdFbkLpf.uwKx);
  264. /* Iq feedback low pass filter coef */
  265. ulLpfTm = 1000000 / cp_stControlPara.swAcrCurFbLpfFre;
  266. mth_voLPFilterCoef(ulLpfTm, FTBC_HZ, &scm_stIqFbkLpf.uwKx);
  267. /* Coefficient update only once */
  268. if (!scm_blCoefUpdateFlg)
  269. {
  270. /* Deadband compensation coefficient calculate */
  271. dbc_stDbCompCoefIn.uwDeadBandTimeNs = cp_stControlPara.swIPMDeadTimeNs; // unit: ns, Dead band time
  272. dbc_stDbCompCoefIn.uwPosSwOnTimeNs = cp_stControlPara.swIPMTurnOnNs; // unit: ns, IPM switch-on time at positive current
  273. dbc_stDbCompCoefIn.uwPosSwOffTimeNs = cp_stControlPara.swIPMTurnOnNs; // unit: ns, IPM switch-off time at positive current
  274. dbc_stDbCompCoefIn.uwNegSwOnTimeNs = cp_stControlPara.swIPMTurnOnNs; // unit: ns, IPM switch-on time at negative current
  275. dbc_stDbCompCoefIn.uwNegSwOffTimeNs = cp_stControlPara.swIPMTurnOnNs; // unit: ns, IPM switch-off time at negative current
  276. dbc_stDbCompCoefIn.ulPWMPerUs = PWM_PERIOD_US; // unit: 0.1us, PWM period
  277. dbc_stDbCompCoefIn.uwKcoefVtPerAp = cp_stControlPara.swDbcK; // Q6, Deadband compensation slope coefficient
  278. dbc_stDbCompCoefIn.uwVBaseVt = VBASE; // Q0, Vbase
  279. dbc_stDbCompCoefIn.uwIBaseAp = IBASE; // Q0, Ibase
  280. dbc_voDBCompCoef(&dbc_stDbCompCoefIn, &dbc_stDbCompCoef);
  281. /* Flux weakening coefficient calculate */
  282. flx_stCtrlCoefIn.swIdMaxAp = (SWORD)cp_stMotorPara.swIdMaxA; // Q0,unit: 0.01A
  283. flx_stCtrlCoefIn.swIdMinAp = (SWORD)cp_stMotorPara.swIdMinA; // Q0,unit: 0.01A
  284. flx_stCtrlCoefIn.uwRsOhm = cp_stMotorPara.swRsOhm; // Q0,unit: 0.1mOhm
  285. flx_stCtrlCoefIn.swIdPIOutMinAp = (SWORD)cp_stControlPara.swFwIdPIOutMin; // Q0,unit: 0.01A
  286. flx_stCtrlCoefIn.uwCharCurCrossFreqHz = cp_stControlPara.swFwCharCurCrossFre; // Q0,unit: SQRT(1/2piR)
  287. flx_stCtrlCoefIn.uwCharCurDampRatio = cp_stControlPara.swFwCharCurDampRatio; // Q0,unit: SQRT(pi/2R)
  288. flx_stCtrlCoefIn.uwIdRegKpPu = cp_stControlPara.swFwIdKpPu; // Q16,unit: A/V2
  289. flx_stCtrlCoefIn.uwIdRegKiPu = cp_stControlPara.swFwIdKiPu; // Q16,unit: A/V2
  290. flx_stCtrlCoefIn.uwPWMDutyMax = cp_stControlPara.swFwPWMMaxDuty; // Q0,%
  291. flx_stCtrlCoefIn.uwVdcLpfFreqHz = cp_stControlPara.swFwVdcLPFFre; // Q0,unit: Hz
  292. flx_stCtrlCoefIn.uwVdcMinCalcTmMs = cp_stControlPara.swFwVdcMinCalTMms; // Q0,unit: ms
  293. flx_stCtrlCoefIn.uwFwCurLimAp = cp_stMotorPara.swIpeakMaxA; // Q0,unit: 0.01A
  294. flx_stCtrlCoefIn.uwIdMinLimRatio = cp_stControlPara.swFwIdMinLimRatio; // Q0,0.01
  295. flx_stCtrlCoefIn.uwUbVt = VBASE; // Q0,unit: 0.1V, Voltage base
  296. flx_stCtrlCoefIn.uwFreqTbcHz = FTBC_HZ; // Q0
  297. flx_stCtrlCoefIn.uwIBaseAp = IBASE; // Q0,unit: 0.01A, Base Current
  298. flx_stCtrlCoefIn.uwFBaseHz = FBASE; // Q0,unit: Hz, Base Frequency
  299. flx_voCoef(&flx_stCtrlCoefIn, &flx_stCtrlCoef);
  300. // fw_stFluxWeakeningCoefInPu
  301. // fw_voFluxWeakeningCoef(fw_stFluxWeakeningCoefInPu,flx_stCtrlCoef)
  302. /* Constant vlotage brake coefficient calculate */
  303. cvb_stBrakeCoefIn.uwVdcCvbVt = cp_stControlPara.swCvbConstantVolBrakeV;
  304. cvb_stBrakeCoefIn.uwLowSpdRpm = cp_stControlPara.swCvbConstantSpdLowRpm;
  305. cvb_stBrakeCoefIn.swIqRefMaxAp = cp_stMotorPara.swIpeakMaxA;
  306. cvb_stBrakeCoefIn.swIdRefMaxAp = cp_stMotorPara.swIdMaxA;
  307. cvb_stBrakeCoefIn.swIdRefMinAp = cp_stMotorPara.swIdMinA;
  308. cvb_stBrakeCoefIn.uwVBaseVt = VBASE;
  309. cvb_stBrakeCoefIn.uwIBaseAp = IBASE;
  310. cvb_stBrakeCoefIn.uwFBaseHz = FBASE;
  311. cvb_stBrakeCoefIn.uwMotorPairs = cp_stMotorPara.swMotrPolePairs;
  312. cvb_voBrakeCoef(&cvb_stBrakeCoefIn, &cvb_stBrakeCoef);
  313. /* Speed feedback low pass filter coef */
  314. ulLpfTm = 1000000 / cp_stControlPara.swAsrSpdFbLPFFre;
  315. mth_voLPFilterCoef(ulLpfTm, FTBC_HZ, &scm_stSpdFbkLpf.uwKx);
  316. /* Power limit coef */
  317. ulLpfTm = 1000000 / cp_stControlPara.swPwrLimitLPFFre;
  318. mth_voLPFilterCoef(ulLpfTm, FTBC_HZ, &scm_stMotoPwrInLpf.uwKx);
  319. ulLpfTm = 1000000 / 10;
  320. mth_voLPFilterCoef(ulLpfTm, FTBC_HZ, &scm_stPCBTempLpf.uwKx);
  321. pwr_stPwrLimCofIn.swPwrLimW = cp_stControlPara.swPwrLimitValWt; // Q0, unit: 0.1w, Power limit value
  322. pwr_stPwrLimCofIn.uwPwrErrW = cp_stControlPara.swPwrLimitErrWt; // Q0, unit: 0.1w, Start power limit when "VAL - ERR"
  323. pwr_stPwrLimCofIn.swIqMaxAp = cp_stMotorPara.swIpeakMaxA; // Q0, unit: 0.01A, Max phase current (peak value)
  324. pwr_stPwrLimCofIn.uwIBaseAp = IBASE; // Q0,unit: 0.01A, Base Current
  325. pwr_stPwrLimCofIn.uwUbVt = VBASE; // Q0,unit: 0.1V, Voltage base
  326. pwr_stPwrLimCofIn.uwPwrLimPIKp = cp_stControlPara.swPwrLimitKpPu;
  327. pwr_stPwrLimCofIn.uwPwrLimPIKi = cp_stControlPara.swPwrLimitKiPu;
  328. pwr_stPwrLimCofIn.swPwrLimStartTempCe = cp_stControlPara.swAlmPwrLimitStartTempVal;
  329. pwr_stPwrLimCofIn.swAlarmTempCe = cp_stControlPara.swAlmOverHeatCeVal;
  330. pwr_voPwrLimCof(&pwr_stPwrLimCofIn, &pwr_stPwrLimCof);
  331. /*Accelaration&Decelaration limit*/
  332. if (ABS(scm_swSpdRefPu) < USER_MOTOR_300RPM2PU)
  333. {
  334. cmd_stCmdCoefIn.ulAccelPu = ulAccel100rpmpsPu*2; // Q29
  335. }
  336. else
  337. {
  338. cmd_stCmdCoefIn.ulAccelPu = ulAccel100rpmpsPu*2; // Q29
  339. }
  340. cmd_stCmdCoefIn.ulDecelPu = ulAccel100rpmpsPu*10; // Q29
  341. cmd_stCmdCoefIn.swBrakeSpdDeltaPu = USER_MOTOR_100RPM2PU;
  342. cmd_voCmdCoef(&cmd_stCmdCoefIn, &cmd_stCmdCoef);
  343. pwm_stGenCoefIn.uwPWMDutyMax = cp_stControlPara.swPWMMaxDuty;
  344. pwm_stGenCoefIn.uwPWM7To5Duty = cp_stControlPara.swPWM7to5Duty;
  345. pwm_stGenCoefIn.uwPWMMinSample1Pu = cp_stControlPara.swPWMMinSampleDuty1;
  346. pwm_stGenCoefIn.uwPWMMinSample2Pu = cp_stControlPara.swPWMMinSampleDuty2;
  347. pwm_stGenCoefIn.uwPWMMinSample3Pu = cp_stControlPara.swPWMMinSampleDuty3;
  348. pwm_stGenCoefIn.uwSampleSteadyPu = cp_stControlPara.swPWMSampleToSteady;
  349. pwm_stGenCoefIn.uwSingelResisSamplePu = cp_stControlPara.swPWMSampleSigR;
  350. pwm_stGenCoefIn.uwOvmNo = cp_stControlPara.swPWMOverMdlMode;
  351. pwm_stGenCoefIn.uwPWMPd = HW_INIT_PWM_PERIOD;
  352. pwm_voGenCoef(&pwm_stGenCoefIn, &pwm_stGenCoef);
  353. scm_uwAcrLimCof = (UWORD)((ULONG)cp_stControlPara.swPWMMaxDuty * cp_stControlPara.uwAcrCurOutLim / 1000); // Q15
  354. scm_uwUdcpLimCof = (UWORD)((ULONG)cp_stControlPara.swPWMMaxDuty * cp_stControlPara.uwAcrUdcpOutLim / 1000); // Q15
  355. }
  356. }
  357. /***************************************************************
  358. Function: scm_voLimit_Power;
  359. Description: Limit motor power
  360. Call by: tbs_voIsr();
  361. Input Variables: uwCurLim-Q10 ucCurrentGain-%
  362. Output/Return Variables: N/A
  363. Subroutine Call: ...;
  364. Reference: N/A
  365. ****************************************************************/
  366. void scm_voLimit_Power(UWORD uwBikeGear, UWORD *uwCurLim, UBYTE *ucCurrentGain)
  367. {
  368. if((uwBikeGear <= 5) && (uwBikeGear > 0))
  369. {
  370. pwr_stPwrLimCofIn.swPwrLimW = (SWORD)((((SLONG)cp_stControlPara.swPwrLimitValWt * uwCurLim[uwBikeGear]) >> 10) * ucCurrentGain[uwBikeGear-1] / 100);
  371. }
  372. else if(uwBikeGear == 0x22)
  373. {
  374. pwr_stPwrLimCofIn.swPwrLimW = cp_stControlPara.swPwrLimitValWt>>1;
  375. }
  376. else
  377. {
  378. pwr_stPwrLimCofIn.swPwrLimW = cp_stControlPara.swPwrLimitValWt; // Q0, unit: 0.1w, Power limit value
  379. }
  380. if(pwr_stPwrLimCofIn.swPwrLimW > cp_stControlPara.swPwrLimitValWt)
  381. {
  382. pwr_stPwrLimCofIn.swPwrLimW = cp_stControlPara.swPwrLimitValWt;
  383. }
  384. pwr_stPwrLimCofIn.uwPwrErrW = cp_stControlPara.swPwrLimitErrWt; // Q0, unit: 0.1w, Start power limit when "VAL - ERR"
  385. pwr_stPwrLimCofIn.swIqMaxAp = cp_stMotorPara.swIpeakMaxA; // Q0, unit: 0.01A, Max phase current (peak value)
  386. pwr_stPwrLimCofIn.uwIBaseAp = IBASE; // Q0,unit: 0.01A, Base Current
  387. pwr_stPwrLimCofIn.uwUbVt = VBASE; // Q0,unit: 0.1V, Voltage base
  388. pwr_stPwrLimCofIn.uwPwrLimPIKp = cp_stControlPara.swPwrLimitKpPu;
  389. pwr_stPwrLimCofIn.uwPwrLimPIKi = cp_stControlPara.swPwrLimitKiPu;
  390. pwr_stPwrLimCofIn.swPwrLimStartTempCe = cp_stControlPara.swAlmPwrLimitStartTempVal;
  391. pwr_stPwrLimCofIn.swAlarmTempCe = cp_stControlPara.swAlmOverHeatCeVal;
  392. pwr_voPwrLimCof(&pwr_stPwrLimCofIn, &pwr_stPwrLimCof);
  393. }
  394. /***************************************************************
  395. Function: scm_voSpdCtrMdTbs;
  396. Description: Speed control mode TBS scheduler
  397. Call by: tbs_voIsr();
  398. Input Variables: N/A
  399. Output/Return Variables: N/A
  400. Subroutine Call: ...;
  401. Reference: N/A
  402. ****************************************************************/
  403. void scm_voSpdCtrMdTbs(void)
  404. {
  405. SWORD swIqLowerPu;
  406. /* Speed feedback LPF */
  407. if(cp_stFlg.ThetaGetModelSelect == ANG_OBSERVER)
  408. {
  409. mth_voLPFilter(obs_stObsOutPu.swElecFreqPu, &scm_stSpdFbkLpf);
  410. }
  411. else if(cp_stFlg.ThetaGetModelSelect == ANG_RESOLVER)
  412. {
  413. mth_voLPFilter(spi_stResolverOut.swSpdFbkPu, &scm_stSpdFbkLpf);
  414. }
  415. else if(cp_stFlg.ThetaGetModelSelect == ANG_SWITCHHALL)
  416. {
  417. scm_stSpdFbkLpf.slY.sw.hi = switchhall_stOut.swLowSpdLpfPu;
  418. }
  419. else
  420. {
  421. //do nothing
  422. }
  423. /* Speed feedback Absolute */
  424. scm_uwSpdFbkLpfAbsPu = (UWORD)ABS(scm_stSpdFbkLpf.slY.sw.hi);
  425. /*============================================================
  426. Speed command generator to generate speed ramp
  427. =============================================================*/
  428. if(curSpeed_state.state == ClzLoop || curSpeed_state.state == Open2Clz)
  429. {
  430. cmd_stCmdIn.swSpdCmdRpm = (SWORD)uart_slSpdRefRpm;
  431. cmd_stCmdIn.swSpdNowPu = scm_stSpdFbkLpf.slY.sw.hi;
  432. cmd_voCmdOut(&cmd_stCmdIn, &cmd_stCmdCoef, &cmd_stCmdOut);
  433. scm_swRotateDir = cmd_stCmdOut.swNewCmdDir;
  434. scm_swSpdRefPu = cmd_stCmdOut.swIntRefPu; // cmd_stCmdGenOut.Out.swSpdRefPu;
  435. }
  436. else if (curSpeed_state.state == StartUp)
  437. {
  438. SWORD tempSpeed = 0;
  439. tempSpeed = (cp_stControlPara.swDragSpdHz * 60 / cp_stMotorPara.swMotrPolePairs);
  440. if(cp_stFlg.RunModelSelect == ClZLOOP)
  441. {
  442. if(uart_slSpdRefRpm>0)
  443. {
  444. cmd_stCmdIn.swSpdCmdRpm = tempSpeed;
  445. }
  446. else
  447. {
  448. cmd_stCmdIn.swSpdCmdRpm = -tempSpeed;
  449. }
  450. }
  451. else if(cp_stFlg.RunModelSelect == VFContorl || cp_stFlg.RunModelSelect == IFContorl)
  452. {
  453. if(cp_stFlg.RotateDirectionSelect == ForwardRotate)
  454. {
  455. cmd_stCmdIn.swSpdCmdRpm = tempSpeed;
  456. }
  457. else
  458. {
  459. cmd_stCmdIn.swSpdCmdRpm = -tempSpeed;
  460. }
  461. }
  462. else
  463. {
  464. //do nothing
  465. }
  466. cmd_stCmdIn.swSpdNowPu = scm_stSpdFbkLpf.slY.sw.hi;
  467. cmd_voCmdOut(&cmd_stCmdIn, &cmd_stCmdCoef, &cmd_stCmdOut);
  468. scm_swRotateDir = cmd_stCmdOut.swNewCmdDir;
  469. scm_swSpdRefPu = cmd_stCmdOut.swIntRefPu; // cmd_stCmdGenOut.Out.swSpdRefPu;
  470. }
  471. else
  472. {
  473. cmd_stCmdIn.swSpdCmdRpm = 0;
  474. cmd_stCmdIn.swSpdNowPu = scm_stSpdFbkLpf.slY.sw.hi;
  475. cmd_voCmdOut(&cmd_stCmdIn, &cmd_stCmdCoef, &cmd_stCmdOut);
  476. scm_swRotateDir = cmd_stCmdOut.swNewCmdDir;
  477. scm_swSpdRefPu = cmd_stCmdOut.swIntRefPu; // cmd_stCmdGenOut.Out.swSpdRefPu;
  478. }
  479. /*=======================================================================
  480. Speed PI Controller
  481. =======================================================================*/
  482. asr_stSpdPIIn.swSpdRefPu = scm_swSpdRefPu; // Q15
  483. asr_stSpdPIIn.swSpdFdbPu = scm_stSpdFbkLpf.slY.sw.hi; // Q15
  484. if(curSpeed_state.state != ClzLoop)
  485. {
  486. swIqLowerPu = flx_stCtrlOut.swIqLimPu;
  487. }
  488. else
  489. {
  490. swIqLowerPu = (SWORD)((flx_stCtrlOut.swIqLimPu < ABS(pwr_stPwrLimOut2.swIqLimPu)) ? flx_stCtrlOut.swIqLimPu : ABS(pwr_stPwrLimOut2.swIqLimPu));
  491. }
  492. if (scm_swRotateDir > 0)
  493. {
  494. asr_stSpdPIIn.swIqMaxPu = swIqLowerPu;
  495. asr_stSpdPIIn.swIqMinPu = -swIqLowerPu;
  496. }
  497. else
  498. {
  499. asr_stSpdPIIn.swIqMaxPu = swIqLowerPu;
  500. asr_stSpdPIIn.swIqMinPu = -swIqLowerPu;
  501. }
  502. asr_voSpdPI(&asr_stSpdPIIn, &asr_stSpdPICoef, &asr_stSpdPIOut);
  503. /* Torque observe */
  504. // if (scm_swRotateDir > 0)
  505. // {
  506. // torqobs_stCalIn.swIqMaxPu = swIqLowerPu;
  507. // torqobs_stCalIn.swIqMinPu = -swIqLowerPu;
  508. // }
  509. // else
  510. // {
  511. // torqobs_stCalIn.swIqMaxPu = swIqLowerPu;
  512. // torqobs_stCalIn.swIqMinPu = -swIqLowerPu;
  513. // }
  514. // torqobs_stCalIn.swIqfbkPu = scm_swIqFdbLpfPu;
  515. // torqobs_stCalIn.swSpdPu = spi_stResolverOut.swSpdFbkPu;
  516. // torqobs_voCal(&torqobs_stCalIn, &torqobs_stCoef, &torqobs_stCalOut);
  517. // mth_voLPFilter(torqobs_stCalOut.swIqLoadPu, &scm_stIqLoadLpf);
  518. // swCurRefrompu = asr_stSpdPIOut.swIqRefPu - scm_stIqLoadLpf.slY.sw.hi;
  519. // if (swCurRefrompu > swIqLowerPu)
  520. // {
  521. // swCurRefrompu = swIqLowerPu;
  522. // }
  523. // else if (swCurRefrompu < -swIqLowerPu)
  524. // {
  525. // swCurRefrompu = -swIqLowerPu;
  526. // }
  527. // else
  528. // {}
  529. swCurRefrompu = asr_stSpdPIOut.swIqRefPu;
  530. curSpeed_state.Tbs_hook();
  531. }
  532. void scm_voTorqCtrMdTbs(void)
  533. {
  534. SWORD swIqLowerPu;
  535. /* Speed feedback LPF */
  536. if(cp_stFlg.ThetaGetModelSelect == ANG_OBSERVER)
  537. {
  538. mth_voLPFilter(obs_stObsOutPu.swElecFreqPu, &scm_stSpdFbkLpf);
  539. }
  540. else if(cp_stFlg.ThetaGetModelSelect == ANG_RESOLVER)
  541. {
  542. mth_voLPFilter(spi_stResolverOut.swSpdFbkPu, &scm_stSpdFbkLpf);
  543. }
  544. else if(cp_stFlg.ThetaGetModelSelect == ANG_SWITCHHALL)
  545. {
  546. scm_stSpdFbkLpf.slY.sw.hi = switchhall_stOut.swLowSpdLpfPu;
  547. }
  548. else
  549. {
  550. //do nothing
  551. }
  552. /* Speed feedback Absolute */
  553. scm_uwSpdFbkLpfAbsPu = (UWORD)ABS(scm_stSpdFbkLpf.slY.sw.hi);
  554. /* Current limit value */
  555. swIqLowerPu = (SWORD)((flx_stCtrlOut.swIqLimPu < ABS(pwr_stPwrLimOut2.swIqLimPu)) ? flx_stCtrlOut.swIqLimPu : ABS(pwr_stPwrLimOut2.swIqLimPu));
  556. /* Torque observer */
  557. // if (scm_swRotateDir > 0)
  558. // {
  559. // torqobs_stCalIn.swIqMaxPu = swIqLowerPu;
  560. // torqobs_stCalIn.swIqMinPu = -swIqLowerPu;
  561. // }
  562. // else
  563. // {
  564. // torqobs_stCalIn.swIqMaxPu = swIqLowerPu;
  565. // torqobs_stCalIn.swIqMinPu = -swIqLowerPu;
  566. // }
  567. // torqobs_stCalIn.swIqfbkPu = scm_swIqFdbLpfPu;
  568. // torqobs_stCalIn.swSpdPu = spi_stResolverOut.swSpdFbkPu;
  569. // torqobs_voCal(&torqobs_stCalIn, &torqobs_stCoef, &torqobs_stCalOut);
  570. // mth_voLPFilterCoef(1000000 / 250, FTBS_HZ, &scm_stIqLoadLpf.uwKx);
  571. // mth_voLPFilter((torqobs_stCalOut.swIqLoadPu + scm_swIqFdbLpfPu), &scm_stIqLoadLpf);
  572. /* Speed fluctuation compensation */
  573. mth_voLPFilterCoef(1000000 / 50, FTBS_HZ, &scm_stIqLoadLpf.uwKx);
  574. mth_voLPFilter(spi_stResolverOut.swSpdFbkPu, &scm_stIqLoadLpf);
  575. scm_swSpdFbkCompPu = spi_stResolverOut.swSpdFbkPu - scm_stIqLoadLpf.slY.sw.hi;
  576. if(Ass_FSM != Prepare)
  577. {
  578. swTmpSpdRate = (SLONG)scm_swSpdFbkCompPu * ass_stParaSet.uwSpeedAssistSpdRpm >> 11;
  579. }
  580. else
  581. {
  582. swTmpSpdRate = (SLONG)scm_swSpdFbkCompPu * ass_stParaSet.uwSpeedAssistSpdRpm >> 12;
  583. }
  584. mth_voLPFilterCoef(1000000 / 250, FTBS_HZ, &swTmpSpdRateLpf.uwKx);
  585. mth_voLPFilter(swTmpSpdRate, &swTmpSpdRateLpf);
  586. // swTmpSpdRateLpf.slY.sw.hi = swTmpSpdRate;
  587. /* Torque Calculate */
  588. // swTmpSpdRate = spi_stResolverOut.swSpdFbkPu - swTmpSpdFbkPuZ1; //Q15
  589. // mth_voLPFilterCoef(1000000 / 30, FTBS_HZ, &swTmpSpdRateLpf.uwKx); //30Hz,TBS
  590. // mth_voLPFilter(swTmpSpdRate, &swTmpSpdRateLpf);
  591. // swTmpSpdFbkPuZ1 = spi_stResolverOut.swSpdFbkPu;
  592. // scm_swSpdFbkCompPu = scm_stSpdFbkLpf.slY.sw.hi + (SLONG)swTmpSpdRateLpf.slY.sw.hi * FTBS_HZ / 30; //30Hz,TBS
  593. // mth_voLPFilterCoef(1000000 / 250, FTBS_HZ, &scm_stIqLoadLpf.uwKx);
  594. // mth_voLPFilter(spi_stResolverOut.swSpdFbkPu, &scm_stIqLoadLpf);
  595. // scm_swSpdFbkCompPu = spi_stResolverOut.swSpdFbkPu - scm_stIqLoadLpf.slY.sw.hi;
  596. //
  597. // swTmpSpdRate = (SLONG)scm_swSpdFbkCompPu * ass_stParaSet.uwSpeedAssistSpdRpm >> 11; // 系数 = J/Tlpf/Pesi
  598. //
  599. //// mth_voLPFilterCoef(1000000 / 250, FTBS_HZ, &swTmpSpdRateLpf.uwKx);
  600. //// mth_voLPFilter(swTmpSpdRate, &swTmpSpdRateLpf);
  601. // swTmpSpdRateLpf.slY.sw.hi = swTmpSpdRate;
  602. //
  603. /* Iqref Compensation */
  604. if(((uart_swTorqRefNm < -200)||(uart_swTorqRefNm > 200)) && (Ass_FSM !=Spd2Torq) && (Ass_FSM !=SpeedAssit))
  605. {
  606. /* Torque Calculate */
  607. //swTestIqref = uart_swTorqRefNm - (((SLONG)swTmpSpdRateLpf.slY.sw.hi * cof_uwJmPu * 2 << 11) / cof_uwFluxPu); //Q15+Q0+Q11-Q12=Q14
  608. /* Speed fluctuation compensation*/
  609. swTestIqref = uart_swTorqRefNm - swTmpSpdRateLpf.slY.sw.hi;
  610. /* Torgque observer */
  611. //swTestIqref = uart_swTorqRefNm - scm_stIqLoadLpf.slY.sw.hi;
  612. }
  613. else
  614. {
  615. swTestIqref = uart_swTorqRefNm;
  616. }
  617. /* Current limit */
  618. if (swTestIqref > swIqLowerPu)
  619. {
  620. swTestIqref = swIqLowerPu;
  621. }
  622. else if (swTestIqref < -swIqLowerPu)
  623. {
  624. swTestIqref = -swIqLowerPu;
  625. }
  626. else
  627. {
  628. //do nothing
  629. }
  630. swCurRefrompu = swTestIqref;
  631. /* 3rd FSM*/
  632. curSpeed_state.Tbs_hook();
  633. }
  634. /***************************************************************
  635. Function: scm_voSpdCtrMdUpTbc;
  636. Description: Speed control mode TBC scheduler
  637. Call by: tbc_voIsr();
  638. Input Variables: N/A
  639. Output/Return Variables: N/A
  640. Subroutine Call: ...;
  641. Reference: N/A
  642. ****************************************************************/
  643. void scm_voSpdCtrMdUpTbc(void)
  644. {
  645. /*=======================================================================
  646. Max voltage of current PI out
  647. =======================================================================*/
  648. scm_swVsLimPu = (SWORD)((SWORD)adc_stUpOut.uwVdcLpfPu * (SLONG)scm_uwAcrLimCof >> 15); // Q14+Q15-Q15=Q14
  649. scm_swVsDcpLimPu = (SWORD)((SWORD)adc_stUpOut.uwVdcLpfPu * (SLONG)scm_uwUdcpLimCof >> 15); // Q14+Q15-Q15=Q14
  650. /*=======================================================================
  651. Voltage get
  652. =======================================================================*/
  653. /* Get Ualpha & Ubeta from command voltage */
  654. scm_swUalphaPu = pwm_stGenOut.swUalphaPu - scm_swUalphaCompPu; // Q14
  655. scm_swUbetaPu = pwm_stGenOut.swUbetaPu - scm_swUbetaCompPu; // Q14
  656. /*=======================================================================
  657. Startup control FSM
  658. =======================================================================*/
  659. scm_voSpdCtrMdFSM();
  660. curSpeed_state.Tbcup_hook();
  661. }
  662. /***************************************************************
  663. Function: scm_voSpdCtrMdTbc;
  664. Description: Speed control mode TBC scheduler
  665. Call by: tbc_voIsr();
  666. Input Variables: N/A
  667. Output/Return Variables: N/A
  668. Subroutine Call: ...;
  669. Reference: N/A
  670. ****************************************************************/
  671. void scm_voSpdCtrMdDownTbc(void)
  672. {
  673. /*=======================================================================
  674. Clark transformation for phase current
  675. =======================================================================*/
  676. crd_stClarkIn.swAPu = adc_stDownOut.swIaPu; // Q14
  677. crd_stClarkIn.swBPu = adc_stDownOut.swIbPu; // Q14
  678. crd_stClarkIn.swCPu = adc_stDownOut.swIcPu; // Q14
  679. crd_voClark(&crd_stClarkIn, &crd_stCurClarkOut);
  680. /*=======================================================================
  681. Code Of spdFSM
  682. =======================================================================*/
  683. curSpeed_state.Tbcdown_hook();
  684. /*=======================================================================
  685. Current loop control
  686. =======================================================================*/
  687. /* Get Id & Iq for current PI control */
  688. /*=======================================================================
  689. Park transformation for current
  690. =======================================================================*/
  691. crd_stParkIn.swAlphaPu = crd_stCurClarkOut.swAlphaPu; // Q14
  692. crd_stParkIn.swBetaPu = crd_stCurClarkOut.swBetaPu; // Q14
  693. crd_stParkIn.uwThetaPu = scm_uwAngParkPu; // Q15
  694. crd_voPark(&crd_stParkIn, &crd_stCurParkOut);
  695. /*=======================================================================
  696. Current feedback LPF
  697. =======================================================================*/
  698. mth_voLPFilter(crd_stCurParkOut.swDPu, &scm_stIdFbkLpf);
  699. mth_voLPFilter(crd_stCurParkOut.swQPu, &scm_stIqFbkLpf);
  700. scm_swIdFdbLpfPu = scm_stIdFbkLpf.slY.sw.hi;
  701. scm_swIqFdbLpfPu = scm_stIqFbkLpf.slY.sw.hi;
  702. /*=======================================================================
  703. Calculate input power of motor
  704. =======================================================================*/
  705. scm_swMotorPwrInPu = (SWORD)(((SLONG)Test_U_out.swDPu * scm_swIdFdbLpfPu + (SLONG)Test_U_out.swQPu * scm_swIqFdbLpfPu) >> 13); // Q14+Q14-Q13=Q15
  706. mth_voLPFilter(scm_swMotorPwrInPu, &scm_stMotoPwrInLpf);
  707. scm_swMotorPwrInLpfWt = (SWORD)(scm_stMotoPwrInLpf.slY.sw.hi * (SLONG)cof_uwPbWt >> 15); // unit: 0.1w
  708. /*=======================================================================
  709. Id current PI control
  710. =======================================================================*/
  711. //DCPswitch = 0; //0 with forwardFeedBack 1 without forwardFeedBack
  712. acr_stCurIdPIIn.swCurRefPu = scm_swIdRefPu; // Q14
  713. acr_stCurIdPIIn.swCurFdbPu = scm_swIdFdbLpfPu;
  714. if (DCPswitch == 1)
  715. {
  716. acr_stCurIdPIIn.swUmaxPu = scm_swVsDcpLimPu; // Q14
  717. acr_stCurIdPIIn.swUminPu = -scm_swVsDcpLimPu; // Q14
  718. }
  719. else if (DCPswitch == 0)
  720. {
  721. acr_stCurIdPIIn.swUmaxPu = scm_swVsDcpLimPu - acr_stUdqDcpOut.swUdPu; // Q14
  722. acr_stCurIdPIIn.swUminPu = -scm_swVsDcpLimPu - acr_stUdqDcpOut.swUdPu; // Q14
  723. // acr_stCurIdPIIn.swUmaxPu = scm_swVsLimPu - acr_stUdqDcpOut.swUdPu; // Q14
  724. // acr_stCurIdPIIn.swUminPu = -scm_swVsLimPu - acr_stUdqDcpOut.swUdPu; // Q14
  725. }
  726. else
  727. {
  728. //do nothing
  729. }
  730. acr_voCurPI(&acr_stCurIdPIIn, &acr_stCurIdPICoef, &acr_stCurIdPIOut);
  731. /*=======================================================================
  732. Iq current PI control
  733. =======================================================================*/
  734. acr_stCurIqPIIn.swCurRefPu = scm_swIqRefPu; // Q14
  735. acr_stCurIqPIIn.swCurFdbPu = scm_swIqFdbLpfPu;
  736. if (DCPswitch == 1)
  737. {
  738. acr_stCurIqPIIn.swUmaxPu = scm_swVsDcpLimPu; // Q14
  739. acr_stCurIqPIIn.swUminPu = -scm_swVsDcpLimPu; // Q14
  740. }
  741. else if (DCPswitch == 0)
  742. {
  743. // if(FSM2nd_Run_state.state == Assistance)
  744. // {
  745. // acr_stCurIqPIIn.swUmaxPu = ass_stCalOut.swVoltLimitPu - acr_stUdqDcpOut.swUqPu; // Q14
  746. // acr_stCurIqPIIn.swUminPu = -ass_stCalOut.swVoltLimitPu - acr_stUdqDcpOut.swUqPu; // Q14
  747. // }
  748. // else
  749. {
  750. acr_stCurIqPIIn.swUmaxPu = scm_swVsDcpLimPu - acr_stUdqDcpOut.swUqPu; // Q14
  751. acr_stCurIqPIIn.swUminPu = -scm_swVsDcpLimPu - acr_stUdqDcpOut.swUqPu; // Q14
  752. }
  753. // scm_swUqLimPu = mth_slSqrt(((SLONG)scm_swVsLimPu * scm_swVsLimPu) - (SLONG)(acr_stCurIdPIOut.swURefPu + acr_stUdqDcpOut.swUdPu) * (acr_stCurIdPIOut.swURefPu + acr_stUdqDcpOut.swUdPu));//Q14
  754. // acr_stCurIqPIIn.swUmaxPu = scm_swUqLimPu - acr_stUdqDcpOut.swUqPu; // Q14
  755. // acr_stCurIqPIIn.swUminPu = -scm_swUqLimPu - acr_stUdqDcpOut.swUqPu; // Q14
  756. }
  757. else
  758. {
  759. //do nothing
  760. }
  761. acr_voCurPI(&acr_stCurIqPIIn, &acr_stCurIqPICoef, &acr_stCurIqPIOut);
  762. if (DCPswitch == 1)
  763. {
  764. scm_swUqRefPu = acr_stCurIqPIOut.swURefPu; // Q14
  765. scm_swUdRefPu = acr_stCurIdPIOut.swURefPu; // Q14
  766. }
  767. else if (DCPswitch == 0)
  768. {
  769. scm_swUqRefPu = acr_stCurIqPIOut.swURefPu + acr_stUdqDcpOut.swUqPu; // Q14
  770. scm_swUdRefPu = acr_stCurIdPIOut.swURefPu + acr_stUdqDcpOut.swUdPu; // Q14
  771. }
  772. else
  773. {
  774. //do nothing
  775. }
  776. /*=======================================================================
  777. IPark transformation for current
  778. =======================================================================*/
  779. crd_stIParkIn.swDPu = scm_swUdRefPu;
  780. crd_stIParkIn.swQPu = scm_swUqRefPu;
  781. crd_stIParkIn.uwThetaPu = scm_uwAngIParkPu;
  782. crd_voIPark(&crd_stIParkIn, &crd_stVltIParkOut);
  783. /*=======================================================================
  784. Deadband compensation
  785. =======================================================================*/
  786. #if (0)
  787. dbc_stDbCompIn.swIaPu = adc_stDownOut.swIaPu; // Q14
  788. dbc_stDbCompIn.swIbPu = adc_stDownOut.swIbPu; // Q14
  789. dbc_stDbCompIn.swIcPu = adc_stDownOut.swIcPu; // Q14
  790. dbc_stDbCompIn.uwVdcPu = adc_stUpOut.uwVdcLpfPu; // Q14
  791. dbc_stDbCompIn.swWsPu = scm_stSpdFbkLpf.slY.sw.hi; // Q15
  792. // dbc_stDbCompCoef.uwNegWinVoltDuty = mn_uwNegWinVoltDuty;
  793. // dbc_stDbCompCoef.uwPosLostVoltDuty = mn_uwPosLostVoltDuty;
  794. dbc_voDBComp(&dbc_stDbCompIn, &dbc_stDbCompCoef, &dbc_stDbCompOut);
  795. #endif
  796. scm_swUalphaRefPu = crd_stVltIParkOut.swAlphaPu + dbc_stDbCompOut.swUalphaCompPu; // Q14
  797. scm_swUbetaRefPu = crd_stVltIParkOut.swBetaPu + dbc_stDbCompOut.swUbetaCompPu; // Q14
  798. scm_swUalphaCompPu = dbc_stDbCompOut.swUalphaCompPu; // Q14
  799. scm_swUbetaCompPu = dbc_stDbCompOut.swUbetaCompPu; // Q14
  800. /*=======================================================================
  801. PWM generate
  802. =======================================================================*/
  803. if(cp_stFlg.RunModelSelect == VFContorl)
  804. {
  805. SWORD swVFVolAmp = 0;
  806. swVFVolAmp = (SWORD)(((SLONG)cp_stControlPara.swDragVolAp << 14) / VBASE);
  807. if(cp_stFlg.RotateDirectionSelect == ForwardRotate)
  808. {
  809. crd_stIParkIn.swDPu = 0;
  810. crd_stIParkIn.swQPu = swVFVolAmp;
  811. }
  812. else if(cp_stFlg.RotateDirectionSelect == BackwardRotate)
  813. {
  814. crd_stIParkIn.swDPu = 0;
  815. crd_stIParkIn.swQPu = -swVFVolAmp;
  816. }
  817. else
  818. {
  819. //do nothing
  820. }
  821. crd_stIParkIn.uwThetaPu = scm_uwAngIParkPu;//scm_uwAngIParkPu;
  822. crd_voIPark(&crd_stIParkIn, &crd_stVltIParkOut);
  823. scm_swUalphaRefPu = crd_stVltIParkOut.swAlphaPu ;
  824. scm_swUbetaRefPu = crd_stVltIParkOut.swBetaPu;
  825. }
  826. pwm_stGenIn.swUalphaPu = scm_swUalphaRefPu; // Q14
  827. pwm_stGenIn.swUbetaPu = scm_swUbetaRefPu; // Q14
  828. pwm_stGenIn.uwVdcPu = adc_stUpOut.uwVdcLpfPu; // Q14
  829. pwm_voGen(&pwm_stGenIn, &pwm_stGenCoef, &pwm_stGenOut);
  830. iPwm_SetCompareGroupValues16(0, pwm_stGenOut.uwNewTIM1COMPR);
  831. ULONG samplingTick[2];
  832. samplingTick[0]=pwm_stGenOut.uwSigRTrig;
  833. samplingTick[1]=pwm_stGenOut.uwRdsonTrig;
  834. iPwm_SyncMultiSamplingCountUp(0, &samplingTick[0], 2);
  835. Test_U_in.swAlphaPu = pwm_stGenOut.swUalphaPu - scm_swUalphaCompPu; // Q14
  836. Test_U_in.swBetaPu = pwm_stGenOut.swUbetaPu - scm_swUbetaCompPu; // Q14
  837. Test_U_in.uwThetaPu = scm_uwAngIParkPu; // Q15
  838. crd_voPark(&Test_U_in, &Test_U_out);
  839. }
  840. /*************************************************************************
  841. Local Functions (N/A)
  842. *************************************************************************/
  843. /*************************************************************************
  844. Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.
  845. All rights reserved.
  846. *************************************************************************/
  847. #ifdef _SPDCTRMODE_C_
  848. #undef _SPDCTRMODE_C_ /* parasoft-suppress MISRA2004-19_6 "本项目中无法更改,后续避免使用" */
  849. #endif
  850. /*************************************************************************
  851. End of this File (EOF)!
  852. Do not put anything after this part!
  853. *************************************************************************/