spdctrmode.c 39 KB

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