spdctrmode.c 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192
  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 "bikeinformation.h"
  28. #include "FuncLayerAPI.h"
  29. #include "AssistCurve.h"
  30. #include "cmdgennew.h"
  31. #include "CodePara.h"
  32. #include "CadAssist.h"
  33. //#include "api.h"
  34. #include "TimeTask_Event.h"
  35. #include "emcdeal.h"
  36. #include "LoadObsTheta.h"
  37. #include "obs.h"
  38. #include "FSM_1st.h"
  39. #include "cmdgennew.h"
  40. /************************************************************************
  41. Constant Table (N/A)
  42. *************************************************************************/
  43. /*************************************************************************
  44. Exported Functions (N/A)
  45. *************************************************************************/
  46. /***************************************************************
  47. Function: scm_voSpdCtrMdInit;
  48. Description: Speed control mode initializing function
  49. Call by: rmd_voModeSchd();
  50. Input Variables: N/A
  51. Output/Return Variables: N/A
  52. Subroutine Call: ...;
  53. Reference: N/A
  54. ****************************************************************/
  55. void scm_voSpdCtrMdInit(void)
  56. {
  57. // /* PWM init */
  58. // hw_voPWMInit();
  59. /*cmd handle Initial */
  60. cmd_voCmdInit();
  61. /* Current PI init */
  62. acr_voCurPIInit();
  63. /* Current decoupling init */
  64. acr_voUdqDcpInit();
  65. /* Sensorless observer init */
  66. // obs_voObsInit();
  67. /* SPI position sensor init */
  68. //spi_voResolverInit();
  69. /* Speed PI init */
  70. asr_voSpdPIInit();
  71. // asrnew_voSpdPIInit();
  72. torqobs_voInit();
  73. // LoadObsTheta_voInit();
  74. /* Flux weakening init */
  75. #if(FLUX_MODE == 0)
  76. spdflx_voInit();
  77. #elif(FLUX_MODE == 1)
  78. flx_voInit();
  79. #else
  80. //Config Error
  81. #endif
  82. // fw_voInit();
  83. /* Power Limit init */
  84. pwr_voPwrLimInit();
  85. /* SVPWM init */
  86. pwm_voInit();
  87. /* Dead time init */
  88. dbc_voDBCompInit();
  89. /* Contant voltage brake init */
  90. cvb_voBrakeInit();
  91. /* switchHall init */
  92. switchhall_voInit();
  93. /* Align pos startup open2clz clzloop init */
  94. align_voInit();
  95. scm_stSpdFbkLpf.slY.sw.hi = 0;
  96. scm_swSpdRefPu = 0;
  97. scm_swUalphaPu = 0; // Q14
  98. scm_swUbetaPu = 0; // Q14
  99. scm_stIdFbkLpf.slY.sl = 0; // Id feedback LPF
  100. scm_stIqFbkLpf.slY.sl = 0; // Iq feedback LPF
  101. scm_stIqRefforDesat.slY.sl = 0; // Iq Ref for desaturation Lpf
  102. scm_stIqFbkforDesat.slY.sl = 0; // Iq Fbk for desaturation Lpf
  103. scm_swIdRefPu = 0; // Q14
  104. scm_swIqRefPu = 0; // Q14
  105. scm_uwAngRefPu = 0; // Q15
  106. scm_uwAngParkPu = 0; // Q15
  107. scm_uwAngIParkPu = 0; // Q15
  108. scm_swRotateDir = -1; // Direction of motor rotate
  109. scm_ulStatCt = 0; // Status hold time count
  110. scm_uwAngManuPu = 0; // Q15, Angle given manually
  111. scm_slAngManuPu = 0;
  112. scm_slDragSpdPu = 0; // Q15, Drag speed
  113. scm_slDragSpdRefPu = 0; // Q29, intermediate Drag speed
  114. scm_blCurSwitchOvrFlg = FALSE; // Current switch over flag
  115. scm_blAngSwitchOvrFlg = FALSE; // Angle switch over flag
  116. scm_uwAngSwitchK = 0; // Angle switch weight value
  117. scm_swMotorPwrInWt = 0; // unit: w, Input power of motor
  118. scm_blCoefUpdateFlg = FALSE; // Coefficient update flag
  119. scm_stIqLoadLpf.slY.sl = 0;
  120. scm_stSpdFbkLpf.slY.sl = 0; // Speed feedback LPF
  121. scm_uwSpdFbkLpfAbsPu = 0; // Q15, Speed feedback LPF absolute
  122. scm_swMotorPwrInPu = 0; // Q15, Input power of motor
  123. scm_swSystemPwrInPu = 0; // Q15, Input power of System
  124. scm_stMotoPwrInLpf.slY.sl = 0; // Input power of motor after LPF
  125. scm_stPCBTempLpf.slY.sl = 0;
  126. scm_stMotorTempLpf.slY.sl = 0;
  127. scm_swMotorPwrInLpfWt = 0; // unit: 0.1w, Input power of motor after LPF
  128. scm_uwMotorPwrInAvgPu = 0; // Q15, Input power of motor after average filter
  129. scm_swIdFdbLpfPu = 0;
  130. scm_swIqFdbLpfPu = 0;
  131. scm_swUdRefPu = 0;
  132. scm_swUqRefPu = 0;
  133. scm_swUalphaFbkPu = 0;
  134. scm_swUbetaFbkPu = 0;
  135. scm_swUalphaRefPu = 0;
  136. scm_swUbetaRefPu = 0;
  137. scm_swUalphaCompPu = 0;
  138. scm_swUbetaCompPu = 0;
  139. scm_uwHfiAngZ1Pu = 0;
  140. scm_slAngSumPu = 0;
  141. scm_slAngErrPu = 0;
  142. scm_blAngSumOvrFlg = FALSE;
  143. scm_uwRunMdSw = 1;
  144. scm_ulRunMdSwCt = 0;
  145. scm_ulCloseCt = 0;
  146. scm_uwStartMd = cp_stControlPara.swStartMode;
  147. scm_uwStartMdSw = scm_uwStartMd;
  148. scm_uwInitPosMd = cp_stControlPara.swInitPosMode;
  149. scm_uwInitPosMdSw = scm_uwInitPosMd;
  150. scm_uwHfiOvrCnt = 0;
  151. scm_slIdRefPu = 0;
  152. }
  153. /***************************************************************
  154. Function: scm_voSpdCtrMdCoef;
  155. Description: Speed control mode TBS scheduler
  156. Call by: tbs_voIsr();
  157. Input Variables: N/A
  158. Output/Return Variables: N/A
  159. Subroutine Call: ...;
  160. Reference: N/A
  161. ****************************************************************/
  162. void scm_voSpdCtrMdCoef(void)
  163. {
  164. ULONG ulLpfTm; // unit: us
  165. UWORD uwLqPu = 0;
  166. ULONG ulAccel100rpmpsPu = USER_MOTOR_240RPMPS2PU_Q29;
  167. if (abs(scm_swIqRefPu) < mn_swIqTurn1Pu)
  168. {
  169. scm_uwLqPu = cof_uwLqPu;
  170. }
  171. else
  172. {
  173. uwLqPu = mn_slLqTurn1Pu + ((SLONG)(abs(scm_swIqRefPu) - mn_swIqTurn1Pu) * mn_swKLqSat >> 10); // Q10
  174. if (uwLqPu < cof_uwLqMinPu)
  175. {
  176. scm_uwLqPu = cof_uwLqMinPu;
  177. }
  178. else if (uwLqPu > cof_uwLqPu)
  179. {
  180. scm_uwLqPu = cof_uwLqPu;
  181. }
  182. else
  183. {
  184. scm_uwLqPu = uwLqPu;
  185. }
  186. }
  187. /* Sensorless observer coefficient calculate */
  188. // obs_stObsCoefIn.uwRbOm = cof_uwRbOm; // Real Value, unit: 0.01Ohm, Resistance base
  189. // obs_stObsCoefIn.uwLbHm = cof_uwLbHm; // Real Value, unit: 0.01mH, Inductance base
  190. // obs_stObsCoefIn.uwFluxbWb = cof_uwFluxbWb; // Real Value, unit: 0.01mWb, Flux linkage base
  191. // obs_stObsCoefIn.uwFbHz = cof_uwFbHz; // Real Value, Unit:Hz frequency base
  192. // obs_stObsCoefIn.uwRsOm = cp_stMotorPara.swRsOhm; // Real Value, unit: 0.01Ohm, Resistance base
  193. // obs_stObsCoefIn.uwLqHm = ((ULONG)scm_uwLqPu * cof_uwLbHm) >> 10; // Real Value, unit: 0.01mH, q Inductance
  194. // obs_stObsCoefIn.uwLdHm = cp_stMotorPara.uwLdmH; // Real Value, unit: 0.01mH, d Inductance
  195. // obs_stObsCoefIn.uwFluxWb = cp_stMotorPara.swFluxWb; // Real Value, unit: 0.01mWb, Flux linkage
  196. // obs_stObsCoefIn.uwFreqTbcHz = FTBC_HZ; // Real Value, Unit:Hz Tbc
  197. // obs_stObsCoefIn.uwFluxDampingRatio = cp_stControlPara.swObsFluxPIDampratio; // Real Value, unit:0.1
  198. // obs_stObsCoefIn.uwFluxCrossFreqHz = cp_stControlPara.swObsFluxPICrossfreHz; // Real Value, unit:Hz
  199. // obs_stObsCoefIn.uwSpdPllWvcHz = cp_stControlPara.swObsSpdPLLBandWidthHz; // Real Value, Unit:Hz
  200. // obs_stObsCoefIn.uwSpdPllMcoef = cp_stControlPara.swObsSpdPLLM;
  201. // obs_voObsCoef(&obs_stObsCoefIn, &obs_stObsCoefPu);
  202. /* Speed PI coefficient calculate */
  203. asr_stSpdPICoefIn.uwUbVt = VBASE;
  204. asr_stSpdPICoefIn.uwIbAp = IBASE;
  205. asr_stSpdPICoefIn.uwFbHz = FBASE;
  206. asr_stSpdPICoefIn.uwFTbsHz = FTBS_HZ;
  207. asr_stSpdPICoefIn.uwPairs = cp_stMotorPara.swMotrPolePairs;
  208. asr_stSpdPICoefIn.uwMtJm = cp_stMotorPara.swJD;
  209. asr_stSpdPICoefIn.uwMtFlxWb = cp_stMotorPara.swFluxWb;
  210. asr_stSpdPICoefIn.uwMcoef = cp_stControlPara.swAsrPIM;
  211. asr_stSpdPICoefIn.uwWvcHz = cp_stControlPara.swAsrPIBandwidth;
  212. asr_stSpdPICoefIn.uwRatioJm = cp_stControlPara.swAsrSpdInerRate;
  213. asr_voSpdPICoef(&asr_stSpdPICoefIn, &asr_stSpdPICoef);
  214. /* 拖拽参数初始化 */
  215. align_voCoef();
  216. /* Reduced Order Torque Observe coefficient calculate */
  217. torqobs_stCoefIn.uwUbVt = VBASE;
  218. torqobs_stCoefIn.uwIbAp = IBASE;
  219. torqobs_stCoefIn.uwFbHz = FBASE;
  220. torqobs_stCoefIn.uwFTbsHz = FTBS_HZ;
  221. torqobs_stCoefIn.uwPairs = cp_stMotorPara.swMotrPolePairs;
  222. torqobs_stCoefIn.uwMtJm = cp_stMotorPara.swJD << 2; // cp_stMotorPara.swJD;
  223. torqobs_stCoefIn.uwMtFlxWb = cp_stMotorPara.swFluxWb;
  224. torqobs_stCoefIn.uwWtcHz = 50; // cp_stControlPara.swAsrPIBandwidth;
  225. torqobs_stCoefIn.uwRatioJm = cp_stControlPara.swAsrSpdInerRate;
  226. torqobs_voCoef(&torqobs_stCoefIn, &torqobs_stCoef);
  227. mth_voLPFilterCoef(1000000 / 30, FTBS_HZ, &scm_stIqLoadLpf.uwKx); // 50Hz
  228. /* Full Order Torque Observer coefficient calculate */
  229. // LoadObsTheta_stCoefIn.uwFbHz = FBASE;
  230. // LoadObsTheta_stCoefIn.uwFluxbWb = cof_uwFluxbWb;
  231. // LoadObsTheta_stCoefIn.uwFluxWb = cp_stMotorPara.swFluxWb;
  232. // LoadObsTheta_stCoefIn.uwFTbcHz = FTBC_HZ;
  233. // LoadObsTheta_stCoefIn.uwJb = cof_uwJb;
  234. // LoadObsTheta_stCoefIn.uwMtJm = cp_stMotorPara.swJD << 2;
  235. // LoadObsTheta_stCoefIn.uwWtcHz = 200;
  236. // LoadObsTheta_stCoefIn.uwMCoef = 100;
  237. // LoadObsTheta_voCoef();
  238. /* Id PI coefficient calculate */
  239. acr_stCurIdPICoefIn.uwFbHz = FBASE;
  240. acr_stCurIdPICoefIn.uwUbVt = VBASE;
  241. acr_stCurIdPICoefIn.uwIbAp = IBASE;
  242. acr_stCurIdPICoefIn.uwLHm = cp_stMotorPara.uwLdmH;
  243. acr_stCurIdPICoefIn.uwMtRsOh = cp_stMotorPara.swRsOhm;
  244. acr_stCurIdPICoefIn.uwFTbcHz = FTBC_HZ;
  245. acr_stCurIdPICoefIn.uwRaCoef = cp_stControlPara.swAcrRaCoef; // Coefficient of Active Resistance
  246. acr_stCurIdPICoefIn.uwWicHz = cp_stControlPara.swAcrPIBandwidth; // Current loop frequency bandwidth
  247. acr_voCurPICoef(&acr_stCurIdPICoefIn, &acr_stCurIdPICoef);
  248. /* Iq PI coefficient calculate */
  249. acr_stCurIqPICoefIn.uwFbHz = FBASE;
  250. acr_stCurIqPICoefIn.uwUbVt = VBASE;
  251. acr_stCurIqPICoefIn.uwIbAp = IBASE;
  252. acr_stCurIqPICoefIn.uwLHm = cp_stMotorPara.uwLqmH;
  253. acr_stCurIqPICoefIn.uwMtRsOh = cp_stMotorPara.swRsOhm;
  254. acr_stCurIqPICoefIn.uwFTbcHz = FTBC_HZ;
  255. acr_stCurIqPICoefIn.uwRaCoef = cp_stControlPara.swAcrRaCoef;
  256. acr_stCurIqPICoefIn.uwWicHz = cp_stControlPara.swAcrPIBandwidth;
  257. acr_voCurPICoef(&acr_stCurIqPICoefIn, &acr_stCurIqPICoef);
  258. /* Current decoupling coefficient calculate */
  259. acr_stUdqDcpCoefIn.uwLdHm = cp_stMotorPara.uwLdmH;
  260. acr_stUdqDcpCoefIn.uwLqHm = cp_stMotorPara.uwLqmH;
  261. acr_stUdqDcpCoefIn.uwMtFlxWb = cp_stMotorPara.swFluxWb;
  262. acr_stUdqDcpCoefIn.uwUbVt = VBASE;
  263. acr_stUdqDcpCoefIn.uwFbHz = FBASE;
  264. acr_stUdqDcpCoefIn.uwIbAp = IBASE;
  265. acr_voUdqDcpCoef(&acr_stUdqDcpCoefIn, &acr_stUdqDcpCoef);
  266. /* Id feedback low pass filter coef */
  267. ulLpfTm = 1000000 / cp_stControlPara.swAcrCurFbLpfFre;
  268. mth_voLPFilterCoef(ulLpfTm, FTBC_HZ, &scm_stIdFbkLpf.uwKx);
  269. /* Iq feedback low pass filter coef */
  270. ulLpfTm = 1000000 / cp_stControlPara.swAcrCurFbLpfFre;
  271. mth_voLPFilterCoef(ulLpfTm, FTBC_HZ, &scm_stIqFbkLpf.uwKx);
  272. ulLpfTm = 1000000 / 100; //1000hz
  273. mth_voLPFilterCoef(ulLpfTm, FTBC_HZ, &scm_stIqRefforDesat.uwKx);
  274. ulLpfTm = 1000000 / 100; //1000hz
  275. mth_voLPFilterCoef(ulLpfTm, FTBC_HZ, &scm_stIqFbkforDesat.uwKx);
  276. /* Coefficient update only once */
  277. if (!scm_blCoefUpdateFlg)
  278. {
  279. /* Deadband compensation coefficient calculate */
  280. dbc_stDbCompCoefIn.uwDeadBandTimeNs = cp_stControlPara.swIPMDeadTimeNs; // unit: ns, Dead band time
  281. dbc_stDbCompCoefIn.uwPosSwOnTimeNs = cp_stControlPara.swIPMTurnOnNs; // unit: ns, IPM switch-on time at positive current
  282. dbc_stDbCompCoefIn.uwPosSwOffTimeNs = cp_stControlPara.swIPMTurnOnNs; // unit: ns, IPM switch-off time at positive current
  283. dbc_stDbCompCoefIn.uwNegSwOnTimeNs = cp_stControlPara.swIPMTurnOnNs; // unit: ns, IPM switch-on time at negative current
  284. dbc_stDbCompCoefIn.uwNegSwOffTimeNs = cp_stControlPara.swIPMTurnOnNs; // unit: ns, IPM switch-off time at negative current
  285. dbc_stDbCompCoefIn.ulPWMPerUs = PWM_PERIOD_US; // unit: 0.1us, PWM period
  286. dbc_stDbCompCoefIn.uwKcoefVtPerAp = cp_stControlPara.swDbcK; // Q6, Deadband compensation slope coefficient
  287. dbc_stDbCompCoefIn.uwVBaseVt = VBASE; // Q0, Vbase
  288. dbc_stDbCompCoefIn.uwIBaseAp = IBASE; // Q0, Ibase
  289. dbc_voDBCompCoef(&dbc_stDbCompCoefIn, &dbc_stDbCompCoef);
  290. /* Flux weakening coefficient calculate */
  291. #if(FLUX_MODE == 0)
  292. //spdflx_stCtrlCoefIn.swRSpeedPu = (((SLONG)cp_stMotorPara.swRSpeedRpm * (SLONG)cp_stMotorPara.swMotrPolePairs / 60)/ FBASE)*2^15; 化简为如下,避免溢出
  293. spdflx_stCtrlCoefIn.swRSpeedPu = (SWORD)((8192L)*(SLONG)cp_stMotorPara.swRSpeedRpm * (SLONG)cp_stMotorPara.swMotrPolePairs / (15 * FBASE));
  294. spdflx_stCtrlCoefIn.swIdMinPu = (SWORD)((16384L)*(SLONG)cp_stMotorPara.swIdMinA / IBASE);
  295. spdflx_stCtrlCoefIn.swIpeakMaxPu = (SWORD)((16384L)*(SLONG)cp_stMotorPara.swIpeakMaxA / IBASE);
  296. spdflx_voCoef(&spdflx_stCtrlCoefIn, &spdflx_stCtrlCoef);
  297. #elif(FLUX_MODE == 1)
  298. flx_stCtrlCoefIn.swIdMaxAp = (SWORD)cp_stMotorPara.swIdMaxA; // Q0,unit: 0.01A
  299. flx_stCtrlCoefIn.swIdMinAp = (SWORD)cp_stMotorPara.swIdMinA; // Q0,unit: 0.01A
  300. flx_stCtrlCoefIn.uwRsOhm = cp_stMotorPara.swRsOhm; // Q0,unit: 0.1mOhm
  301. flx_stCtrlCoefIn.swIdPIOutMinAp = (SWORD)cp_stControlPara.swFwIdPIOutMin; // Q0,unit: 0.01A
  302. flx_stCtrlCoefIn.uwCharCurCrossFreqHz = cp_stControlPara.swFwCharCurCrossFre; // Q0,unit: SQRT(1/2piR)
  303. flx_stCtrlCoefIn.uwCharCurDampRatio = cp_stControlPara.swFwCharCurDampRatio; // Q0,unit: SQRT(pi/2R)
  304. flx_stCtrlCoefIn.uwIdRegKpPu = cp_stControlPara.swFwIdKpPu; // Q16,unit: A/V2
  305. flx_stCtrlCoefIn.uwIdRegKiPu = cp_stControlPara.swFwIdKiPu; // Q16,unit: A/V2
  306. flx_stCtrlCoefIn.uwPWMDutyMax = cp_stControlPara.swFwPWMMaxDuty; // Q0,%
  307. flx_stCtrlCoefIn.uwVdcLpfFreqHz = cp_stControlPara.swFwVdcLPFFre; // Q0,unit: Hz
  308. flx_stCtrlCoefIn.uwVdcMinCalcTmMs = cp_stControlPara.swFwVdcMinCalTMms; // Q0,unit: ms
  309. flx_stCtrlCoefIn.uwFwCurLimAp = cp_stMotorPara.swIpeakMaxA; // Q0,unit: 0.01A
  310. flx_stCtrlCoefIn.uwIdMinLimRatio = cp_stControlPara.swFwIdMinLimRatio; // Q0,0.01
  311. flx_stCtrlCoefIn.uwUbVt = VBASE; // Q0,unit: 0.1V, Voltage base
  312. flx_stCtrlCoefIn.uwFreqTbcHz = FTBC_HZ; // Q0
  313. flx_stCtrlCoefIn.uwIBaseAp = IBASE; // Q0,unit: 0.01A, Base Current
  314. flx_stCtrlCoefIn.uwFBaseHz = FBASE; // Q0,unit: Hz, Base Frequency
  315. flx_voCoef(&flx_stCtrlCoefIn, &flx_stCtrlCoef);
  316. // fw_stFluxWeakeningCoefInPu
  317. // fw_voFluxWeakeningCoef(fw_stFluxWeakeningCoefInPu,flx_stCtrlCoef)
  318. #else
  319. //Config Error
  320. #endif
  321. /* Constant vlotage brake coefficient calculate */
  322. cvb_stBrakeCoefIn.uwVdcCvbVt = cp_stControlPara.swCvbConstantVolBrakeV;
  323. cvb_stBrakeCoefIn.uwLowSpdRpm = cp_stControlPara.swCvbConstantSpdLowRpm;
  324. cvb_stBrakeCoefIn.swIqRefMaxAp = cp_stMotorPara.swIpeakMaxA;
  325. cvb_stBrakeCoefIn.swIdRefMaxAp = cp_stMotorPara.swIdMaxA;
  326. cvb_stBrakeCoefIn.swIdRefMinAp = cp_stMotorPara.swIdMinA;
  327. cvb_stBrakeCoefIn.uwVBaseVt = VBASE;
  328. cvb_stBrakeCoefIn.uwIBaseAp = IBASE;
  329. cvb_stBrakeCoefIn.uwFBaseHz = FBASE;
  330. cvb_stBrakeCoefIn.uwMotorPairs = cp_stMotorPara.swMotrPolePairs;
  331. cvb_voBrakeCoef(&cvb_stBrakeCoefIn, &cvb_stBrakeCoef);
  332. /* Speed feedback low pass filter coef */
  333. ulLpfTm = 1000000 / cp_stControlPara.swAsrSpdFbLPFFre;
  334. mth_voLPFilterCoef(ulLpfTm, FTBC_HZ, &scm_stSpdFbkLpf.uwKx);
  335. /* Power limit coef */
  336. ulLpfTm = 1000000 / cp_stControlPara.swPwrLimitLPFFre;
  337. mth_voLPFilterCoef(ulLpfTm, FTBC_HZ, &scm_stMotoPwrInLpf.uwKx);
  338. ulLpfTm = 1000000 / 10;
  339. mth_voLPFilterCoef(ulLpfTm, FTBC_HZ, &scm_stPCBTempLpf.uwKx);
  340. ulLpfTm = 1000000 / 10;
  341. mth_voLPFilterCoef(ulLpfTm, FTBC_HZ, &scm_stMotorTempLpf.uwKx);
  342. // /* Torque Sensor limit coef */
  343. // ulLpfTm = 1000000 / torsensor_stTorSensorCof.uwTorSensorLPFFrq;
  344. // mth_voLPFilterCoef(ulLpfTm, FTBC_HZ, &scm_stTorSensorLpf.uwKx);
  345. // /* Bike Throttle limit coef */
  346. // ulLpfTm = 1000000 / bikethrottle_stBikeThrottleCof.uwThrottleVolLPFFrq;
  347. // mth_voLPFilterCoef(ulLpfTm, FTBC_HZ, &scm_stBikeThrottleLpf.uwKx);
  348. pwr_stPwrLimCofIn.swPwrLimW = cp_stControlPara.swPwrLimitValWtCALC; // Q0, unit: 0.1w, Power limit value
  349. pwr_stPwrLimCofIn.uwPwrErrW = cp_stControlPara.swPwrLimitErrWt; // Q0, unit: 0.1w, Start power limit when "VAL - ERR"
  350. pwr_stPwrLimCofIn.swIqMaxAp = cp_stMotorPara.swIpeakMaxA; // Q0, unit: 0.01A, Max phase current (peak value)
  351. pwr_stPwrLimCofIn.uwIBaseAp = IBASE; // Q0,unit: 0.01A, Base Current
  352. pwr_stPwrLimCofIn.uwUbVt = VBASE; // Q0,unit: 0.1V, Voltage base
  353. pwr_stPwrLimCofIn.uwPwrLimPIKp = cp_stControlPara.swPwrLimitKpPu;
  354. pwr_stPwrLimCofIn.uwPwrLimPIKi = cp_stControlPara.swPwrLimitKiPu;
  355. pwr_stPwrLimCofIn.uwPwrLimSTARTCe = cp_stControlPara.swAlmPwrLimitStartTempVal;
  356. pwr_stPwrLimCofIn.uwPwrLimENDCe = cp_stControlPara.swAlmOverHeatCeVal;
  357. pwr_stPwrLimCofIn.uwPwrLimMotTempSTARTCe = cp_stControlPara.swAlmPwrLimitMotorStartTempVal;
  358. pwr_stPwrLimCofIn.uwPwrLimMotTempENDCe = cp_stControlPara.swAlmMotorOverHeatCeVal;
  359. pwr_stPwrLimCofIn.uwPwrLimStartBatCap = PWRLIM_START_BATCAP;
  360. pwr_stPwrLimCofIn.uwPwrLimEndBatCap = PWRLIM_END_BATCAP;
  361. pwr_voPwrLimCof(&pwr_stPwrLimCofIn, &pwr_stPwrLimCof);
  362. /*Accelaration&Decelaration limit*/
  363. if (abs(scm_swSpdRefPu) < USER_MOTOR_300RPM2PU)
  364. {
  365. cmd_stCmdCoefIn.ulAccelPu = ulAccel100rpmpsPu; // Q29
  366. }
  367. else
  368. {
  369. cmd_stCmdCoefIn.ulAccelPu = ulAccel100rpmpsPu; // Q29
  370. }
  371. cmd_stCmdCoefIn.ulDecelPu = USER_MOTOR_3000RPMPS2PU_Q29; // Q29
  372. cmd_stCmdCoefIn.swBrakeSpdDeltaPu = USER_MOTOR_100RPM2PU;
  373. cmd_voCmdCoef(&cmd_stCmdCoefIn, &cmd_stCmdCoef);
  374. pwm_stGenCoefIn.uwPWMDutyMax = cp_stControlPara.swPWMMaxDuty;
  375. pwm_stGenCoefIn.uwPWM7To5Duty = cp_stControlPara.swPWM7to5Duty;
  376. pwm_stGenCoefIn.uwPWMMinSample1Pu = cp_stControlPara.swPWMMinSampleDuty1;
  377. pwm_stGenCoefIn.uwPWMMinSample2Pu = cp_stControlPara.swPWMMinSampleDuty2;
  378. pwm_stGenCoefIn.uwPWMMinSample3Pu = cp_stControlPara.swPWMMinSampleDuty3;
  379. pwm_stGenCoefIn.uwSampleSteadyPu = cp_stControlPara.swPWMSampleToSteady;
  380. pwm_stGenCoefIn.uwSingelResisSamplePu = cp_stControlPara.swPWMSampleSigR;
  381. pwm_stGenCoefIn.uwOvmNo = cp_stControlPara.swPWMOverMdlMode;
  382. pwm_stGenCoefIn.uwPWMPd = HW_PWM_PERIOD;
  383. pwm_voGenCoef(&pwm_stGenCoefIn, &pwm_stGenCoef);
  384. scm_uwAcrLimCof = (UWORD)((ULONG)cp_stControlPara.swPWMMaxDuty * cp_stControlPara.uwAcrCurOutLim / 1000); // Q15
  385. scm_uwUdcpLimCof = (UWORD)((ULONG)cp_stControlPara.swPWMMaxDuty * cp_stControlPara.uwAcrUdcpOutLim / 1000); // Q15
  386. }
  387. }
  388. /***************************************************************
  389. Function: scm_voSpdCtrMdTbs;
  390. Description: Speed control mode TBS scheduler
  391. Call by: tbs_voIsr();
  392. Input Variables: N/A
  393. Output/Return Variables: N/A
  394. Subroutine Call: ...;
  395. Reference: N/A
  396. ****************************************************************/
  397. SWORD testIqref;
  398. void scm_voSpdCtrMdTbs(void)
  399. {
  400. SWORD swIqLowerPu;
  401. /* Speed feedback LPF */
  402. if (cp_stFlg.ThetaGetModelSelect == ANG_OBSERVER)
  403. {
  404. // mth_voLPFilter(obs_stObsOutPu.swElecFreqPu, &scm_stSpdFbkLpf);
  405. }
  406. else if (cp_stFlg.ThetaGetModelSelect == ANG_RESOLVER)
  407. {
  408. // mth_voLPFilter(spi_stResolverOut.swSpdFbkPu, &scm_stSpdFbkLpf);
  409. }
  410. else if (cp_stFlg.ThetaGetModelSelect == ANG_SWITCHHALL)
  411. {
  412. scm_stSpdFbkLpf.slY.sw.hi = switchhall_stOut.swLowSpdLpfPu;
  413. }
  414. else
  415. {}
  416. /* Speed feedback Absolute */
  417. scm_uwSpdFbkLpfAbsPu = abs(scm_stSpdFbkLpf.slY.sw.hi);
  418. /*============================================================
  419. Speed command generator to generate speed ramp
  420. =============================================================*/
  421. if (curSpeed_state.state == ClzLoop || curSpeed_state.state == Open2Clz)
  422. {
  423. cmd_stCmdIn.swSpdCmdRpm = uart_slSpdRefRpm;
  424. cmd_stCmdIn.swSpdNowPu = scm_stSpdFbkLpf.slY.sw.hi;
  425. cmd_voCmdOut(&cmd_stCmdIn, &cmd_stCmdCoef, &cmd_stCmdOut);
  426. scm_swRotateDir = cmd_stCmdOut.swNewCmdDir;
  427. scm_swSpdRefPu = cmd_stCmdOut.swIntRefPu; // cmd_stCmdGenOut.Out.swSpdRefPu;
  428. }
  429. else if (curSpeed_state.state == StartUp)
  430. {
  431. SWORD tempSpeed = 0;
  432. tempSpeed = (cp_stControlPara.swDragSpdHz * 60 / cp_stMotorPara.swMotrPolePairs);
  433. if (cp_stFlg.RunModelSelect == ClZLOOP)
  434. {
  435. if (uart_slSpdRefRpm > 0)
  436. {
  437. cmd_stCmdIn.swSpdCmdRpm = tempSpeed;
  438. }
  439. else
  440. {
  441. cmd_stCmdIn.swSpdCmdRpm = -tempSpeed;
  442. }
  443. }
  444. else if (cp_stFlg.RunModelSelect == VFContorl || cp_stFlg.RunModelSelect == IFContorl)
  445. {
  446. if (uart_slSpdRefRpm > 0)
  447. {
  448. cmd_stCmdIn.swSpdCmdRpm = tempSpeed;
  449. }
  450. else
  451. {
  452. cmd_stCmdIn.swSpdCmdRpm = -tempSpeed;
  453. }
  454. // if(cp_stFlg.RotateDirectionSelect == ForwardRotate)
  455. // {
  456. // cmd_stCmdIn.swSpdCmdRpm = tempSpeed;
  457. // }
  458. // else
  459. // {
  460. // cmd_stCmdIn.swSpdCmdRpm = -tempSpeed;
  461. // }
  462. }
  463. else
  464. {}
  465. cmd_stCmdIn.swSpdNowPu = scm_stSpdFbkLpf.slY.sw.hi;
  466. cmd_voCmdOut(&cmd_stCmdIn, &cmd_stCmdCoef, &cmd_stCmdOut);
  467. scm_swRotateDir = cmd_stCmdOut.swNewCmdDir;
  468. scm_swSpdRefPu = cmd_stCmdOut.swIntRefPu; // cmd_stCmdGenOut.Out.swSpdRefPu;
  469. }
  470. else
  471. {
  472. cmd_stCmdIn.swSpdCmdRpm = 0;
  473. cmd_stCmdIn.swSpdNowPu = scm_stSpdFbkLpf.slY.sw.hi;
  474. cmd_voCmdOut(&cmd_stCmdIn, &cmd_stCmdCoef, &cmd_stCmdOut);
  475. scm_swRotateDir = cmd_stCmdOut.swNewCmdDir;
  476. scm_swSpdRefPu = cmd_stCmdOut.swIntRefPu; // cmd_stCmdGenOut.Out.swSpdRefPu;
  477. }
  478. /*=======================================================================
  479. Speed PI Controller
  480. =======================================================================*/
  481. asr_stSpdPIIn.swSpdRefPu = scm_swSpdRefPu; // Q15
  482. // asr_stSpdPIIn.swSpdFdbPu = switchhall_stOut.swLowSpdPu;
  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 = (flx_stCtrlOut.swIqLimPu < abs(pwr_stPwrLimOut2.swIqLimPu)) ? flx_stCtrlOut.swIqLimPu : abs(pwr_stPwrLimOut2.swIqLimPu);
  491. swIqLowerPu = (swIqLowerPu < abs(cvb_stBrakeOut.swIqLimPu)) ? swIqLowerPu : abs(cvb_stBrakeOut.swIqLimPu);
  492. }
  493. if (scm_swRotateDir > 0)
  494. {
  495. asr_stSpdPIIn.swIqMaxPu = swIqLowerPu;
  496. // asr_stSpdPIIn.swIqMinPu = -swIqLowerPu;
  497. asr_stSpdPIIn.swIqMinPu = 0;
  498. }
  499. else
  500. {
  501. asr_stSpdPIIn.swIqMaxPu = 0;
  502. // asr_stSpdPIIn.swIqMaxPu = swIqLowerPu;
  503. asr_stSpdPIIn.swIqMinPu = -swIqLowerPu;
  504. }
  505. asr_voSpdPI(&asr_stSpdPIIn, &asr_stSpdPICoef, &asr_stSpdPIOut);
  506. // swCurRefrompu = (abs(asr_stSpdPIOut.swIqRefPu) < abs(uart_swTorqRefNm)) ? abs(asr_stSpdPIOut.swIqRefPu) : abs(uart_swTorqRefNm);
  507. // swCurRefrompu = -swCurRefrompu;
  508. swCurRefrompu = asr_stSpdPIOut.swIqRefPu;
  509. /* New ASR */
  510. // asrnew_stSpdPIIn.swSpdRefPu = scm_swSpdRefPu; // Q15
  511. // asrnew_stSpdPIIn.swSpdFdbPu = scm_stSpdFbkLpf.slY.sw.hi; // Q15
  512. // if (scm_swRotateDir > 0)
  513. // {
  514. // asrnew_stSpdPIIn.swIqMaxPu = swIqLowerPu;
  515. // asrnew_stSpdPIIn.swIqMinPu = 0;//-swIqLowerPu;
  516. // }
  517. // else
  518. // {
  519. // asrnew_stSpdPIIn.swIqMaxPu = swIqLowerPu;
  520. // asrnew_stSpdPIIn.swIqMinPu = 0;//-swIqLowerPu;
  521. // }
  522. // asrnew_voSpdPI(&asrnew_stSpdPIIn, &asrnew_stSpdPICoef, &asrnew_stSpdPIOut);
  523. // swCurRefrompu = asrnew_stSpdPIOut.swIqRefPu;
  524. // swCurRefrompu = testIqref;
  525. curSpeed_state.Tbs_hook();
  526. }
  527. SWORD deltC, switchCNT, switchflg;
  528. SWORD swTmpSpdRate = 0;
  529. LPF_OUT swTmpSpdRateLpf;
  530. SWORD swTmpSpdFbkPuZ1 = 0;
  531. SLONG slTmpAcc;
  532. SWORD swTestIqref;
  533. void scm_voTorqCtrMdTbs(void)
  534. {
  535. SWORD swIqLowerPu;
  536. /* Speed feedback LPF */
  537. if (cp_stFlg.ThetaGetModelSelect == ANG_OBSERVER)
  538. {
  539. // mth_voLPFilter(obs_stObsOutPu.swElecFreqPu, &scm_stSpdFbkLpf);
  540. }
  541. else if (cp_stFlg.ThetaGetModelSelect == ANG_RESOLVER)
  542. {
  543. // mth_voLPFilter(spi_stResolverOut.swSpdFbkPu, &scm_stSpdFbkLpf);
  544. }
  545. else if (cp_stFlg.ThetaGetModelSelect == ANG_SWITCHHALL)
  546. {
  547. scm_stSpdFbkLpf.slY.sw.hi = switchhall_stOut.swLowSpdLpfPu;
  548. }
  549. else
  550. {}
  551. /* Speed feedback Absolute */
  552. scm_uwSpdFbkLpfAbsPu = abs(scm_stSpdFbkLpf.slY.sw.hi);
  553. // /*============================================================
  554. // Speed command generator to generate speed ramp
  555. // =============================================================*/
  556. // cmd_stCmdIn.swSpdCmdRpm = -(((SLONG)cadence_stFreGetOut.uwLPFFrequencyPu * 8000) >> 10) * 6000 >> 15;
  557. // cmd_stCmdIn.swSpdNowPu = scm_stSpdFbkLpf.slY.sw.hi;
  558. // cmd_voCmdOut(&cmd_stCmdIn, &cmd_stCmdCoef, &cmd_stCmdOut);
  559. // /*=======================================================================
  560. // Get speed command
  561. // =======================================================================*/
  562. // scm_swRotateDir = cmd_stCmdOut.swNewCmdDir;
  563. // scm_swSpdRefPu = cmd_stCmdOut.swIntRefPu; //cmd_stCmdGenOut.Out.swSpdRefPu;
  564. /*=======================================================================
  565. Speed PI Controller
  566. =======================================================================*/
  567. swIqLowerPu = (flx_stCtrlOut.swIqLimPu < abs(pwr_stPwrLimOut2.swIqLimPu)) ? flx_stCtrlOut.swIqLimPu : abs(pwr_stPwrLimOut2.swIqLimPu);
  568. swIqLowerPu = (swIqLowerPu < abs(cvb_stBrakeOut.swIqLimPu)) ? swIqLowerPu : abs(cvb_stBrakeOut.swIqLimPu);
  569. // if (uart_swTorqRefNm > swIqLowerPu)
  570. // {
  571. // uart_swTorqRefNm = swIqLowerPu;
  572. // }
  573. // else if (uart_swTorqRefNm < -swIqLowerPu)
  574. // {
  575. // uart_swTorqRefNm = -swIqLowerPu;
  576. // }
  577. // else
  578. // {}
  579. // swCurRefrompu = uart_swTorqRefNm;
  580. /* Torque observe */
  581. if (scm_swRotateDir > 0)
  582. {
  583. torqobs_stCalIn.swIqMaxPu = swIqLowerPu;
  584. torqobs_stCalIn.swIqMinPu = -swIqLowerPu;
  585. }
  586. else
  587. {
  588. torqobs_stCalIn.swIqMaxPu = swIqLowerPu;
  589. torqobs_stCalIn.swIqMinPu = -swIqLowerPu;
  590. }
  591. torqobs_stCalIn.swIqfbkPu = scm_swIqFdbLpfPu;
  592. torqobs_stCalIn.swSpdPu = switchhall_stOut.swLowSpdPu;
  593. torqobs_voCal(&torqobs_stCalIn, &torqobs_stCoef, &torqobs_stCalOut);
  594. mth_voLPFilter((torqobs_stCalOut.swIqLoadPu + scm_swIqFdbLpfPu), &scm_stIqLoadLpf);
  595. // mth_voLPFilter(LoadObsTheta_Y.swIqCompPu, &scm_stIqLoadLpf);
  596. ///////test////////
  597. // mth_voLPFilterCoef(1000000 / 15, FTBS_HZ, &swTmpSpdRateLpf.uwKx); //30Hz,TBS
  598. // mth_voLPFilter(LoadObsTheta_Y.swIqCompPu, &swTmpSpdRateLpf);
  599. /* Spd Fbk Compensation Calculate */
  600. // swTmpSpdRate = switchhall_stOut.swLowSpdPu - swTmpSpdFbkPuZ1; //Q15
  601. // mth_voLPFilterCoef(1000000 / 30, FTBS_HZ, &swTmpSpdRateLpf.uwKx); //30Hz,TBS
  602. // mth_voLPFilter(swTmpSpdRate, &swTmpSpdRateLpf);
  603. // swTmpSpdFbkPuZ1 = switchhall_stOut.swLowSpdPu;
  604. // slTmpAcc = (SLONG)swTmpSpdRateLpf.slY.sw.hi * FTBS_HZ / FBASE; //Q15
  605. /* Iqref Compensation */
  606. if (((uart_swTorqRefNm < -200) || (uart_swTorqRefNm > 200)))
  607. {
  608. /* Without Comp */
  609. swTestIqref = uart_swTorqRefNm;
  610. /* Open Loop */
  611. // swTestIqref = uart_swTorqRefNm - (((SLONG)slTmpAcc* cof_uwJmPu << 11) / cof_uwFluxPu); //Q15+Q0+Q11-Q12=Q14
  612. /* Observer */
  613. // swTestIqref = uart_swTorqRefNm - scm_stIqLoadLpf.slY.sw.hi;
  614. // swTestIqref = uart_swTorqRefNm - swTmpSpdRateLpf.slY.sw.hi;
  615. }
  616. else
  617. {
  618. swTestIqref = uart_swTorqRefNm;
  619. }
  620. if (swTestIqref > swIqLowerPu)
  621. {
  622. swTestIqref = swIqLowerPu;
  623. }
  624. else if (swTestIqref < -swIqLowerPu)
  625. {
  626. swTestIqref = -swIqLowerPu;
  627. }
  628. else
  629. {}
  630. swCurRefrompu = swTestIqref;
  631. curSpeed_state.Tbs_hook();
  632. }
  633. /***************************************************************
  634. Function: scm_voSpdCtrMdUpTbc;
  635. Description: Speed control mode TBC scheduler
  636. Call by: tbc_voIsr();
  637. Input Variables: N/A
  638. Output/Return Variables: N/A
  639. Subroutine Call: ...;
  640. Reference: N/A
  641. ****************************************************************/
  642. CRD_PARK_IN Test_U_in;
  643. CRD_PARK_OUT Test_U_out;
  644. void scm_voSpdCtrMdUpTbc(void)
  645. {
  646. /*=======================================================================
  647. Max voltage of current PI out
  648. =======================================================================*/
  649. scm_swVsLimPu = (SWORD)((ULONG)adc_stUpOut.uwVdcLpfPu * scm_uwAcrLimCof >> 15); // Q14+Q15-Q15=Q14
  650. scm_swVsDcpLimPu_Assist = (SWORD)((ULONG)adc_stUpOut.uwVdcLpfPu * scm_uwUdcpLimCof >> 15); // Q14+Q15-Q15=Q14
  651. scm_swVsDcpLimPu = scm_swVsDcpLimPu_Assist;
  652. /*=======================================================================
  653. Voltage get
  654. =======================================================================*/
  655. /* Get Ualpha & Ubeta from command voltage */
  656. scm_swUalphaPu = pwm_stGenOut.swUalphaPu - scm_swUalphaCompPu; // Q14
  657. scm_swUbetaPu = pwm_stGenOut.swUbetaPu - scm_swUbetaCompPu; // Q14
  658. /*=======================================================================
  659. Startup control FSM
  660. =======================================================================*/
  661. scm_voSpdCtrMdFSM();
  662. curSpeed_state.Tbcup_hook();
  663. }
  664. /***************************************************************
  665. Function: scm_voSpdCtrMdTbc;
  666. Description: Speed control mode TBC scheduler
  667. Call by: tbc_voIsr();
  668. Input Variables: N/A
  669. Output/Return Variables: N/A
  670. Subroutine Call: ...;
  671. Reference: N/A
  672. ****************************************************************/
  673. UWORD DCPswitch = 0;
  674. UWORD testtheta = 0;
  675. SWORD IQqqqqq = 0, SwitchFlggg = 1;
  676. SLONG IQCNT = 0;
  677. UWORD uwIqStopCnt;
  678. SLONG swUqmax,swUqmin;
  679. SLONG swUdmax,swUdmin;
  680. UWORD UqDecCount = 0, UdDecCount = 0;
  681. void scm_voSpdCtrMdDownTbc(void)
  682. {
  683. /*=======================================================================
  684. Clark transformation for phase current
  685. =======================================================================*/
  686. crd_stClarkIn.swAPu = adc_stDownOut.swIaPu; // Q14
  687. crd_stClarkIn.swBPu = adc_stDownOut.swIbPu; // Q14
  688. crd_stClarkIn.swCPu = adc_stDownOut.swIcPu; // Q14
  689. crd_voClark(&crd_stClarkIn, &crd_stCurClarkOut);
  690. /*=======================================================================
  691. Code Of spdFSM
  692. =======================================================================*/
  693. curSpeed_state.Tbcdown_hook();
  694. // if(SwitchFlggg == 0)
  695. // {
  696. // IQCNT++;
  697. // scm_swIqRefPu = -4000;
  698. // if(IQCNT > 2000)
  699. // {
  700. // IQCNT=0;
  701. // SwitchFlggg =1;
  702. // }
  703. // }
  704. // else
  705. // {
  706. // scm_swIqRefPu = IQqqqqq;
  707. // }
  708. //
  709. /*=======================================================================
  710. Current loop control
  711. =======================================================================*/
  712. /* Get Id & Iq for current PI control */
  713. /*=======================================================================
  714. Park transformation for current
  715. =======================================================================*/
  716. crd_stParkIn.swAlphaPu = crd_stCurClarkOut.swAlphaPu; // Q14
  717. crd_stParkIn.swBetaPu = crd_stCurClarkOut.swBetaPu; // Q14
  718. crd_stParkIn.uwThetaPu = scm_uwAngParkPu; // Q15
  719. crd_voPark(&crd_stParkIn, &crd_stCurParkOut);
  720. /*=======================================================================
  721. Current feedback LPF
  722. =======================================================================*/
  723. mth_voLPFilter(crd_stCurParkOut.swDPu, &scm_stIdFbkLpf);
  724. mth_voLPFilter(crd_stCurParkOut.swQPu, &scm_stIqFbkLpf);
  725. scm_swIdFdbLpfPu = scm_stIdFbkLpf.slY.sw.hi;
  726. scm_swIqFdbLpfPu = scm_stIqFbkLpf.slY.sw.hi;
  727. // scm_swIdFdbLpfPu = crd_stCurParkOut.swDPu;
  728. // scm_swIqFdbLpfPu = crd_stCurParkOut.swQPu;
  729. /*=======================================================================
  730. Calculate input power of motor
  731. =======================================================================*/
  732. scm_swSystemPwrInPu =
  733. ((((SLONG)adc_stUpOut.uwVdcLpfPu * (SLONG)adc_stUpOut.uwIbusAvgLpfPu) >> 13) * (SLONG)683) >> 10; // power = udc*idc; Q14+Q14-Q13=Q15
  734. scm_swMotorPwrInPu = ((SLONG)Test_U_out.swDPu * scm_swIdFdbLpfPu + (SLONG)Test_U_out.swQPu * scm_swIqFdbLpfPu) >> 13; // Q14+Q14-Q13=Q15
  735. mth_voLPFilter(scm_swMotorPwrInPu, &scm_stMotoPwrInLpf);
  736. scm_swMotorPwrInLpfWt = scm_stMotoPwrInLpf.slY.sw.hi * cof_uwPbWt >> 15; // unit: 0.1w
  737. /*=======================================================================
  738. Id current PI control
  739. =======================================================================*/
  740. DCPswitch = 0; // 0 with forwardFeedBack 1 without forwardFeedBack
  741. acr_stCurIdPIIn.swCurRefPu = scm_swIdRefPu; // Q14
  742. acr_stCurIdPIIn.swCurFdbPu = scm_swIdFdbLpfPu;
  743. if (DCPswitch == 1)
  744. {
  745. acr_stCurIdPIIn.swUmaxPu = scm_swVsDcpLimPu; // Q14
  746. acr_stCurIdPIIn.swUminPu = -scm_swVsDcpLimPu; // Q14
  747. }
  748. else if (DCPswitch == 0)
  749. {
  750. if(switch_flg.SysRun_Flag == FALSE)
  751. {
  752. if(UdDecCount>=100) // each 100/8000s decrease to 1000/1024*U
  753. {
  754. UdDecCount = 0;
  755. acr_stCurIdPIIn.swUmaxPu = (SWORD)(((SLONG)swUdmax*1020)>>10);
  756. acr_stCurIdPIIn.swUminPu = (SWORD)(((SLONG)swUdmin*1020)>>10);
  757. }
  758. else
  759. {
  760. UdDecCount++;
  761. acr_stCurIdPIIn.swUmaxPu = swUdmax; // Q14
  762. acr_stCurIdPIIn.swUminPu = swUdmin; // Q14
  763. }
  764. }
  765. else
  766. {
  767. acr_stCurIdPIIn.swUmaxPu = scm_swVsDcpLimPu - acr_stUdqDcpOut.swUdPu; // Q14
  768. acr_stCurIdPIIn.swUminPu = -scm_swVsDcpLimPu - acr_stUdqDcpOut.swUdPu; // Q14
  769. }
  770. }
  771. else
  772. {}
  773. swUdmin = acr_stCurIqPIIn.swUminPu;
  774. swUdmax = acr_stCurIqPIIn.swUmaxPu;
  775. acr_voCurPI(&acr_stCurIdPIIn, &acr_stCurIdPICoef, &acr_stCurIdPIOut);
  776. /*=======================================================================
  777. Iq current PI control
  778. =======================================================================*/
  779. mth_voLPFilter(scm_swIqRefPu, &scm_stIqRefforDesat);
  780. mth_voLPFilter(scm_swIqFdbLpfPu, &scm_stIqFbkforDesat);
  781. //-------------limit min vault
  782. if (cp_stFlg.RotateDirectionSelect == ForwardRotate)
  783. {
  784. if(acr_stUdqDcpOut.swUqPu<=0)
  785. acr_stUdqDcpOut.swUqPu=0;
  786. }
  787. else if (cp_stFlg.RotateDirectionSelect == BackwardRotate)
  788. {
  789. if(acr_stUdqDcpOut.swUqPu>=0)
  790. acr_stUdqDcpOut.swUqPu=0;
  791. }
  792. //------------------
  793. if (DCPswitch == 1)
  794. {
  795. acr_stCurIqPIIn.swUmaxPu = scm_swVsDcpLimPu; // Q14
  796. acr_stCurIqPIIn.swUminPu = -scm_swVsDcpLimPu; // Q14
  797. }
  798. else if (DCPswitch == 0)
  799. {
  800. if(event_blCurrentAssFlag == TRUE)
  801. {
  802. if (cp_stFlg.RotateDirectionSelect == ForwardRotate)
  803. {
  804. if (((SLONG)ass_stCadAssCalOut.swVoltLimitPu - (SLONG)acr_stUdqDcpOut.swUqPu) > 0)
  805. {
  806. acr_stCurIqPIIn.swUmaxPu = ass_stCadAssCalOut.swVoltLimitPu - acr_stUdqDcpOut.swUqPu; // Q14
  807. }
  808. else
  809. {
  810. acr_stCurIqPIIn.swUmaxPu = 0;
  811. }
  812. if(ass_stCadAssCalOut.blPreStopFlag == TRUE)
  813. {
  814. acr_stCurIqPIIn.swUminPu = 0;
  815. }
  816. else
  817. {
  818. acr_stCurIqPIIn.swUminPu = -scm_swVsDcpLimPu - acr_stUdqDcpOut.swUqPu;
  819. }
  820. }
  821. else if (cp_stFlg.RotateDirectionSelect == BackwardRotate)
  822. {
  823. if (((SLONG)ass_stCadAssCalOut.swVoltLimitPu - (SLONG)acr_stUdqDcpOut.swUqPu) < 0)
  824. {
  825. acr_stCurIqPIIn.swUminPu = ass_stCadAssCalOut.swVoltLimitPu - acr_stUdqDcpOut.swUqPu; // Q14
  826. }
  827. else
  828. {
  829. acr_stCurIqPIIn.swUminPu = 0;
  830. }
  831. if(ass_stCadAssCalOut.blPreStopFlag == TRUE )
  832. {
  833. acr_stCurIqPIIn.swUmaxPu = 0;
  834. }
  835. else
  836. {
  837. acr_stCurIqPIIn.swUmaxPu = scm_swVsDcpLimPu - acr_stUdqDcpOut.swUqPu;
  838. }
  839. }
  840. else
  841. {
  842. /* 方向错误 */
  843. }
  844. }
  845. else
  846. {
  847. if(switch_flg.SysRun_Flag == FALSE)
  848. {
  849. if(UqDecCount>=100) // each 100/8000s decrease to 1000/1024*U
  850. {
  851. UqDecCount = 0;
  852. acr_stCurIqPIIn.swUmaxPu = (SWORD)(((SLONG)swUqmax*1010)>>10);
  853. acr_stCurIqPIIn.swUminPu = (SWORD)(((SLONG)swUqmin*1010)>>10);
  854. }
  855. else
  856. {
  857. UqDecCount++;
  858. acr_stCurIqPIIn.swUmaxPu = swUqmax; // Q14
  859. acr_stCurIqPIIn.swUminPu = swUqmin; // Q14
  860. }
  861. }
  862. else
  863. {
  864. acr_stCurIqPIIn.swUmaxPu = scm_swVsDcpLimPu - acr_stUdqDcpOut.swUqPu; // Q14
  865. acr_stCurIqPIIn.swUminPu = -scm_swVsDcpLimPu - acr_stUdqDcpOut.swUqPu; // Q14
  866. }
  867. }
  868. }
  869. else
  870. {}
  871. swUqmin = acr_stCurIqPIIn.swUminPu;
  872. swUqmax = acr_stCurIqPIIn.swUmaxPu;
  873. #if 0
  874. if(0 == scm_swIqRefPu)
  875. {
  876. uwIqStopCnt++;
  877. if(uwIqStopCnt >= 500)
  878. {
  879. uwIqStopCnt = 500;
  880. }
  881. }
  882. else
  883. {
  884. uwIqStopCnt = 0;
  885. }
  886. if((500 == uwIqStopCnt) && (scm_uwSpdFbkLpfAbsPu < 1500))
  887. {
  888. if((cp_stFlg.RotateDirectionSelect == BackwardRotate)
  889. && (scm_swIqFdbLpfPu > 0))
  890. {
  891. acr_stCurIqPIIn.swCurRefPu = 0; // Q14
  892. acr_stCurIqPIIn.swCurFdbPu = 0;
  893. acr_stCurIqPIOut.swURefPu=0;
  894. acr_stCurIqPIOut.slURefPu=0;
  895. scm_swUqRefPu=0;
  896. }
  897. else if((cp_stFlg.RotateDirectionSelect == ForwardRotate)
  898. && (scm_swIqFdbLpfPu < 0))
  899. {
  900. acr_stCurIqPIIn.swCurRefPu = 0; // Q14
  901. acr_stCurIqPIIn.swCurFdbPu = 0;
  902. acr_stCurIqPIOut.swURefPu=0;
  903. acr_stCurIqPIOut.slURefPu=0;
  904. scm_swUqRefPu=0;
  905. }
  906. else
  907. {
  908. acr_stCurIqPIIn.swCurRefPu = scm_swIqRefPu; // Q14
  909. acr_stCurIqPIIn.swCurFdbPu = scm_swIqFdbLpfPu;
  910. }
  911. }
  912. else
  913. {
  914. acr_stCurIqPIIn.swCurRefPu = scm_swIqRefPu; // Q14
  915. acr_stCurIqPIIn.swCurFdbPu = scm_swIqFdbLpfPu;
  916. }
  917. #else
  918. acr_stCurIqPIIn.swCurRefPu = scm_swIqRefPu; // Q14
  919. acr_stCurIqPIIn.swCurFdbPu = scm_swIqFdbLpfPu;
  920. #endif
  921. acr_voCurPI(&acr_stCurIqPIIn, &acr_stCurIqPICoef, &acr_stCurIqPIOut);
  922. // if ((DCPswitch == 1) && (scm_uwSpdFbkLpfAbsPu > 30922)) // Q15 2000rpm
  923. // {
  924. // acr_stCurIdPIOut.slURefPu = acr_stCurIdPIOut.slURefPu - ((SLONG)acr_stUdqDcpOut.swUdPu << 15);
  925. // acr_stCurIqPIOut.slURefPu = acr_stCurIqPIOut.slURefPu - ((SLONG)acr_stUdqDcpOut.swUqPu << 15);
  926. // acr_stCurIdPIOut.swURefPu = acr_stCurIdPIOut.swURefPu - acr_stUdqDcpOut.swUdPu;
  927. // acr_stCurIqPIOut.swURefPu = acr_stCurIqPIOut.swURefPu - acr_stUdqDcpOut.swUqPu;
  928. // DCPswitch = 0;
  929. // }
  930. // if ((DCPswitch == 0) && (scm_uwSpdFbkLpfAbsPu < 8192))
  931. // {
  932. // acr_stCurIdPIOut.slURefPu = acr_stCurIdPIOut.slURefPu + ((SLONG)acr_stUdqDcpOut.swUdPu << 15);
  933. // acr_stCurIqPIOut.slURefPu = acr_stCurIqPIOut.slURefPu + ((SLONG)acr_stUdqDcpOut.swUqPu << 15);
  934. // acr_stCurIdPIOut.swURefPu = acr_stCurIdPIOut.swURefPu + acr_stUdqDcpOut.swUdPu;
  935. // acr_stCurIqPIOut.swURefPu = acr_stCurIqPIOut.swURefPu + acr_stUdqDcpOut.swUqPu;
  936. // DCPswitch = 1;
  937. // }
  938. if (DCPswitch == 1)
  939. {
  940. scm_swUqRefPu = acr_stCurIqPIOut.swURefPu; // Q14
  941. scm_swUdRefPu = acr_stCurIdPIOut.swURefPu; // Q14
  942. }
  943. else if (DCPswitch == 0)
  944. {
  945. scm_swUqRefPu = acr_stCurIqPIOut.swURefPu + acr_stUdqDcpOut.swUqPu; // Q14
  946. scm_swUdRefPu = acr_stCurIdPIOut.swURefPu + acr_stUdqDcpOut.swUdPu; // Q14
  947. }
  948. else
  949. {}
  950. if(event_blCurrentAssFlag == TRUE)
  951. {
  952. if (cp_stFlg.RotateDirectionSelect == ForwardRotate)
  953. {
  954. if (scm_swUqRefPu > ass_stCadAssCalOut.swVoltLimitPu)
  955. {
  956. scm_swUqRefPu = ass_stCadAssCalOut.swVoltLimitPu; // Q14=Q14
  957. }
  958. }
  959. else if (cp_stFlg.RotateDirectionSelect == BackwardRotate)
  960. {
  961. if (scm_swUqRefPu < ass_stCadAssCalOut.swVoltLimitPu)
  962. {
  963. scm_swUqRefPu = ass_stCadAssCalOut.swVoltLimitPu; // Q14=Q14
  964. }
  965. }
  966. else
  967. {
  968. /* 方向错误 */
  969. }
  970. }
  971. else
  972. {}
  973. /*=======================================================================
  974. IPark transformation for current
  975. =======================================================================*/
  976. #if(EMCDEAL_EN!=0)
  977. if(EcmDeal.EmcModeFlag==FALSE)
  978. {
  979. EcmDeal.swUdRefPu=scm_swUdRefPu;
  980. EcmDeal.swUqRefPu=scm_swUqRefPu;
  981. }
  982. else
  983. {
  984. scm_swUdRefPu=EcmDeal.swUdRefPu;
  985. scm_swUqRefPu=EcmDeal.swUqRefPu;
  986. }
  987. #endif
  988. //-----------------2024
  989. // scm_swUdRefPu=0;
  990. // if (cp_stFlg.RotateDirectionSelect == ForwardRotate)
  991. // {
  992. // if(bikethrottle_stBikeThrottleOut.uwThrottlePercent>250)
  993. // {
  994. // scm_swUqRefPu=bikethrottle_stBikeThrottleOut.uwThrottlePercent*10-2000;
  995. // }
  996. // else
  997. // {
  998. // if(scm_swUqRefPu>0)
  999. // scm_swUqRefPu--;
  1000. // else if(scm_swUqRefPu<0)
  1001. // scm_swUqRefPu=0;
  1002. //
  1003. //
  1004. // }
  1005. //
  1006. // }
  1007. // else if (cp_stFlg.RotateDirectionSelect == BackwardRotate)
  1008. // {
  1009. // if(bikethrottle_stBikeThrottleOut.uwThrottlePercent>250)
  1010. // {
  1011. // scm_swUqRefPu=-bikethrottle_stBikeThrottleOut.uwThrottlePercent*10+2000;
  1012. // }
  1013. // else
  1014. // {
  1015. // if(scm_swUqRefPu<0)
  1016. // scm_swUqRefPu++;
  1017. // else if(scm_swUqRefPu>0)
  1018. // scm_swUqRefPu=0;
  1019. //
  1020. //
  1021. // }
  1022. // }
  1023. //----------------------
  1024. crd_stIParkIn.swDPu = scm_swUdRefPu;
  1025. crd_stIParkIn.swQPu = scm_swUqRefPu;
  1026. crd_stIParkIn.uwThetaPu = scm_uwAngIParkPu;
  1027. crd_voIPark(&crd_stIParkIn, &crd_stVltIParkOut);
  1028. /*=======================================================================
  1029. Deadband compensation
  1030. =======================================================================*/
  1031. #if (0)
  1032. dbc_stDbCompIn.swIaPu = adc_stDownOut.swIaPu; // Q14
  1033. dbc_stDbCompIn.swIbPu = adc_stDownOut.swIbPu; // Q14
  1034. dbc_stDbCompIn.swIcPu = adc_stDownOut.swIcPu; // Q14
  1035. dbc_stDbCompIn.uwVdcPu = adc_stUpOut.uwVdcLpfPu; // Q14
  1036. dbc_stDbCompIn.swWsPu = scm_stSpdFbkLpf.slY.sw.hi; // Q15
  1037. // dbc_stDbCompCoef.uwNegWinVoltDuty = mn_uwNegWinVoltDuty;
  1038. // dbc_stDbCompCoef.uwPosLostVoltDuty = mn_uwPosLostVoltDuty;
  1039. dbc_voDBComp(&dbc_stDbCompIn, &dbc_stDbCompCoef, &dbc_stDbCompOut);
  1040. #endif
  1041. scm_swUalphaRefPu = crd_stVltIParkOut.swAlphaPu + dbc_stDbCompOut.swUalphaCompPu; // Q14
  1042. scm_swUbetaRefPu = crd_stVltIParkOut.swBetaPu + dbc_stDbCompOut.swUbetaCompPu; // Q14
  1043. scm_swUalphaCompPu = dbc_stDbCompOut.swUalphaCompPu; // Q14
  1044. scm_swUbetaCompPu = dbc_stDbCompOut.swUbetaCompPu; // Q14
  1045. /*=======================================================================
  1046. PWM generate
  1047. =======================================================================*/
  1048. if (cp_stFlg.RunModelSelect == VFContorl)
  1049. {
  1050. SWORD swVFVolAmp = 0;
  1051. swVFVolAmp = ((SLONG)cp_stControlPara.swDragVolAp << 14) / VBASE;
  1052. if (cp_stFlg.RotateDirectionSelect == ForwardRotate)
  1053. {
  1054. crd_stIParkIn.swDPu = 0;
  1055. crd_stIParkIn.swQPu = swVFVolAmp;
  1056. }
  1057. else if (cp_stFlg.RotateDirectionSelect == BackwardRotate)
  1058. {
  1059. crd_stIParkIn.swDPu = 0;
  1060. crd_stIParkIn.swQPu = swVFVolAmp;
  1061. }
  1062. else
  1063. {}
  1064. crd_stIParkIn.uwThetaPu = scm_uwAngIParkPu; // scm_uwAngIParkPu;
  1065. crd_voIPark(&crd_stIParkIn, &crd_stVltIParkOut);
  1066. scm_swUalphaRefPu = crd_stVltIParkOut.swAlphaPu;
  1067. scm_swUbetaRefPu = crd_stVltIParkOut.swBetaPu;
  1068. }
  1069. pwm_stGenIn.swUalphaPu = scm_swUalphaRefPu; // Q14
  1070. pwm_stGenIn.swUbetaPu = scm_swUbetaRefPu; // Q14
  1071. pwm_stGenIn.uwVdcPu = adc_stUpOut.uwVdcLpfPu; // Q14
  1072. pwm_voGen(&pwm_stGenIn, &pwm_stGenCoef, &pwm_stGenOut);
  1073. // iPwm_SetCompareGroupValues16(0, pwm_stGenOut.uwNewTIM1COMPR);
  1074. // if (cp_stFlg.CurrentSampleModelSelect == SINGLERESISITANCE)
  1075. // {
  1076. // ULONG samplingTick[2];
  1077. // samplingTick[0] = pwm_stGenOut.uwFirstTrigCOMPR;
  1078. // samplingTick[1] = pwm_stGenOut.uwSecondTrigCOMPR;
  1079. // //iPwm_SyncMultiSamplingCountUp(0, &samplingTick[0], 2);
  1080. // }
  1081. Test_U_in.swAlphaPu = pwm_stGenOut.swUalphaPu - scm_swUalphaCompPu; // Q14
  1082. Test_U_in.swBetaPu = pwm_stGenOut.swUbetaPu - scm_swUbetaCompPu; // Q14
  1083. Test_U_in.uwThetaPu = scm_uwAngIParkPu; // Q15
  1084. crd_voPark(&Test_U_in, &Test_U_out);
  1085. //// pwm_stGenOut.uwNewTIM1COMPR[0] = 500;
  1086. //// pwm_stGenOut.uwNewTIM1COMPR[1] = 500;
  1087. //// pwm_stGenOut.uwNewTIM1COMPR[2] = 500;
  1088. //// pwm_stGenOut.uwNewTIM1COMPR[3] = 1700;
  1089. //// pwm_stGenOut.uwNewTIM1COMPR[4] = 1700;
  1090. //// pwm_stGenOut.uwNewTIM1COMPR[5] = 1700;
  1091. }
  1092. /*************************************************************************
  1093. Local Functions (N/A)
  1094. *************************************************************************/
  1095. /*************************************************************************
  1096. Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.
  1097. All rights reserved.
  1098. *************************************************************************/
  1099. #ifdef _SPDCTRMODE_C_
  1100. #undef _SPDCTRMODE_C_
  1101. #endif
  1102. /*************************************************************************
  1103. End of this File (EOF)!
  1104. Do not put anything after this part!
  1105. *************************************************************************/