spdctrmode.c 47 KB

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