pwm.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889
  1. /************************************************************************
  2. Project: Welling Motor Control Paltform
  3. Filename: pwm.c
  4. Partner Filename: pwm.h
  5. Description: SVPWM and over voltage modulation
  6. Complier: IAR Embedded Workbench for ARM 7.80.4
  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 _PWM_C_
  20. #define _PWM_C_
  21. #endif
  22. /************************************************************************
  23. Include File
  24. ************************************************************************/
  25. #include "user.h"
  26. /************************************************************************
  27. Private Variables
  28. *************************************************************************/
  29. static SWORD pwm_pvt_sw1st_Cur_Smpl_Ct = 0;
  30. static SWORD pwm_pvt_sw2nd_Cur_Smpl_Ct = 0;
  31. static SWORD pwm_pvt_swMin_Double_Cur_Smpl_Pu = 0;
  32. static SWORD pwm_pvt_swMin_Cur_Smpl_Ct = 0;
  33. static SWORD pwm_pvt_swMin_Cur_Smpl_Pu = 0;
  34. /************************************************************************
  35. Constant Table:
  36. ************************************************************************/
  37. /************************************************************************
  38. Exported Functions:
  39. ************************************************************************/
  40. /************************************************************************
  41. Function: pwm_voInit;
  42. Description: pwm generation initial;
  43. Call by: functions in main loop;
  44. Input Variables: N/A;
  45. Output/Return Variables: N/A;
  46. Subroutine Call: N/A;
  47. Reference: N/A;
  48. ************************************************************************/
  49. void pwm_voInit(void)
  50. {
  51. pwm_sw1stCurSmplCt = cp_stControlPara.swPWM1STSampleCnt; // min time for ADC one channel of Current
  52. pwm_sw2ndCurSmplCt = cp_stControlPara.swPWM2NDSampleCnt; // the time of second current sample trig lag the second comparator
  53. pwm_swMinDoubleCurSmplPu = cp_stControlPara.swPWMMinEffVectorPu << 1; // min time of Two valid voltage vector
  54. pwm_swMinCurSmplCt = cp_stControlPara.swPWMMinEffVectorCnt; // min counts of one valid voltage vector
  55. pwm_swMinCurSmplPu = cp_stControlPara.swPWMMinEffVectorCnt; // min time of one valid voltage vector
  56. pwm_pvt_sw1st_Cur_Smpl_Ct = pwm_sw1stCurSmplCt;
  57. pwm_pvt_sw2nd_Cur_Smpl_Ct = pwm_sw2ndCurSmplCt;
  58. pwm_pvt_swMin_Double_Cur_Smpl_Pu = pwm_swMinDoubleCurSmplPu;
  59. pwm_pvt_swMin_Cur_Smpl_Ct = pwm_swMinCurSmplCt;
  60. pwm_pvt_swMin_Cur_Smpl_Pu = pwm_swMinCurSmplPu;
  61. pwm_stGenOut.swUalphaPu = 0; // Q14
  62. pwm_stGenOut.swUbetaPu = 0; // Q14
  63. pwm_stGenOut.uwNewSectorNum = 0;
  64. pwm_stGenOut.uwNewTIM1COMPR[0] = HW_HHPWM_PERIOD;
  65. pwm_stGenOut.uwNewTIM1COMPR[1] = HW_HHPWM_PERIOD;
  66. pwm_stGenOut.uwNewTIM1COMPR[2] = HW_HHPWM_PERIOD;
  67. pwm_stGenOut.uwNewTIM1COMPR[3] = HW_HHPWM_PERIOD;
  68. pwm_stGenOut.uwNewTIM1COMPR[4] = HW_HHPWM_PERIOD;
  69. pwm_stGenOut.uwNewTIM1COMPR[5] = HW_HHPWM_PERIOD;
  70. pwm_stGenOut.uwFirstTrigCOMPR = HW_HHHPWM_PERIOD;
  71. pwm_stGenOut.uwSecondTrigCOMPR = HW_HHPWM_PERIOD + HW_HHHPWM_PERIOD;
  72. pwm_stGenOut.uwOldTrig = 0;
  73. pwm_stGenOut.uwNewTrig = 0;
  74. pwm_stGenOut.uwSampleArea = IgnoreNone;
  75. pwm_stGenOut.uwRDSONTrig = 129;
  76. pwm_stGenOut.uwSigRTrig = HW_HHHPWM_PERIOD;
  77. }
  78. /************************************************************************
  79. Function: pwm_voGenCoef;
  80. Description: pwm generation coefficient initial;
  81. Call by: functions in main loop;
  82. Input Variables: PWM_COF_IN;
  83. Output/Return Variables: PWM_CALC_COF;
  84. Subroutine Call: N/A;
  85. Reference: N/A;
  86. ************************************************************************/
  87. void pwm_voGenCoef(PWM_COF_IN *in, PWM_CALC_COF *coef)
  88. {
  89. if (in->uwPWMDutyMax > 1000)
  90. {
  91. in->uwPWMDutyMax = 1000;
  92. }
  93. else if (in->uwPWMDutyMax == 0)
  94. {
  95. in->uwPWMDutyMax = 1;
  96. }
  97. else
  98. {
  99. //do noting
  100. }
  101. if (in->uwPWM7To5Duty > 1000)
  102. {
  103. in->uwPWM7To5Duty = 1000;
  104. }
  105. else if (in->uwPWM7To5Duty == 0)
  106. {
  107. in->uwPWM7To5Duty = 1;
  108. }
  109. else
  110. {
  111. //do noting
  112. }
  113. if (in->uwOvmNo > 2)
  114. {
  115. in->uwOvmNo = 2;
  116. }
  117. if (in->uwPWMPd > 31250)
  118. {
  119. in->uwPWMPd = 31250;
  120. }
  121. else if (in->uwPWMPd < 4)
  122. {
  123. in->uwPWMPd = 4;
  124. }
  125. else
  126. {
  127. //do nothing
  128. }
  129. coef->uwPWMDutyMaxPu = (UWORD)((((ULONG)in->uwPWMDutyMax - 3) << 14) / 1000); // Q14
  130. coef->uwPWM7To5DutyPu = (UWORD)(((ULONG)in->uwPWM7To5Duty << 14) / 1000); // Q14
  131. coef->uwPWMMinSample1Pu = (UWORD)(((ULONG)in->uwPWMMinSample1Pu << 14) / 1000); // Q14, unit:Pu two zero vector
  132. coef->uwPWMMinSample2Pu = (UWORD)(((ULONG)in->uwPWMMinSample2Pu << 14) / 1000); // Q14, unit:Pu (one zero vector + sample time)*2
  133. coef->uwPWMMinSample3Pu = (UWORD)(((ULONG)in->uwPWMMinSample3Pu << 14) / 1000); // Q14, unit:Pu (one Singel Resistance steady time + sample time)*2
  134. coef->uwOvmNo = in->uwOvmNo;
  135. coef->uwPWMPd = in->uwPWMPd;
  136. coef->uwHPWMPd = in->uwPWMPd >> 1;
  137. coef->uwHHPWMPd = in->uwPWMPd >> 2;
  138. coef->ulPWMPerInv = ((ULONG)1 << 21) / in->uwPWMPd; // Q21, 1/PWM period
  139. coef->uwMaxCmpCt = (UWORD)(((ULONG)in->uwPWMDutyMax * coef->uwHPWMPd) / 1000); // Q14
  140. coef->uwSampleSteadyCt = (UWORD)(((ULONG)in->uwSampleSteadyPu * coef->uwHPWMPd) / 1000);
  141. coef->uwSingelResisSampleCt = (UWORD)(((ULONG)in->uwSingelResisSamplePu * coef->uwHPWMPd) / 1000);
  142. }
  143. /************************************************************************
  144. Function: pwm_voGen;
  145. Description: pwm generation;
  146. Call by: functions in TBC;
  147. Input Variables: PWM_GEN_IN, PWM_CALC_COF;
  148. Output/Return Variables: PWM_GEN_OUT;
  149. Subroutine Call: N/A;
  150. Reference: N/A;
  151. ************************************************************************/
  152. void pwm_voGen(PWM_GEN_IN *in, const PWM_CALC_COF *coef, PWM_GEN_OUT *out) /* parasoft-suppress METRICS-28 "本项目圈复杂度无法更改,后续避免" */
  153. { /* parasoft-suppress GJB5369-4_2_2_2 "本项目函数行数无法更改,后续应避免" */
  154. SLONG slL1, slL2, slL3;
  155. SLONG slKsvpwm;
  156. SLONG slX, slY, slZ;
  157. SWORD swT1, swT2;
  158. SWORD swOvmT1, swOvmT2;
  159. UWORD uwSector;
  160. SWORD swUaPu, swUbPu, swUcPu;
  161. SWORD swPWMPRD1, swPWMPRD2, swPWMPRD3;
  162. // SWORD swPWMPRD11,swPWMPRD21,swPWMPRD31,swPWMPRD12,swPWMPRD22,swPWMPRD32;
  163. SWORD tmp_swPeriodA, tmp_swPeriodB, tmp_swPeriodC;
  164. /*==============================================================================
  165. Sector Determination
  166. L1 = Ubeta
  167. L2 = sqrt(3)/2 * Ualfa - 1/2 * Ubeta
  168. L3 = -sqrt(3)/2 * Ualfa - 1/2 * Ubeta
  169. ==============================================================================*/
  170. slL1 = in->swUbetaPu + 1; // Q14
  171. slL2 = ((in->swUalphaPu * PWM_SQRT3 >> 14) - in->swUbetaPu) >> 1; // Q14
  172. slL3 = (-(in->swUalphaPu * PWM_SQRT3 >> 14) - in->swUbetaPu) >> 1; // Q14
  173. uwSector = 0;
  174. if (slL1 > 0)
  175. {
  176. uwSector += 1;
  177. }
  178. if (slL2 > 0)
  179. {
  180. uwSector += 2;
  181. }
  182. if (slL3 > 0)
  183. {
  184. uwSector += 4;
  185. }
  186. /*======================================================================
  187. Base Voltage Vector Period(t1/t2) calculation according to sector
  188. X = 2/sqrt(3)*Ts*slv1
  189. Y = -2/sqrt(3)*Ts*slv3
  190. Z = -2/sqrt(3)*Ts*slv2
  191. =======================================================================*/
  192. if (in->uwVdcPu < 10)
  193. {
  194. in->uwVdcPu = 10;
  195. }
  196. slKsvpwm = (PWM_SQRT3 << 15) / in->uwVdcPu; // Q15=Q14+Q15-Q14
  197. slX = slKsvpwm * (slL1 - 1) >> 15; // Q14
  198. slY = -slKsvpwm * slL3 >> 15; // Q14
  199. slZ = -slKsvpwm * slL2 >> 15; // Q14
  200. switch (uwSector)
  201. {
  202. case 3:
  203. swT1 = -(SWORD)slZ; // Q14, t1
  204. swT2 = (SWORD)slX; // Q14, t2
  205. break;
  206. case 1:
  207. swT1 = (SWORD)slZ; // Q14, t1
  208. swT2 = (SWORD)slY; // Q14, t2
  209. break;
  210. case 5:
  211. swT1 = (SWORD)slX; // Q14, t1
  212. swT2 = -(SWORD)slY; // Q14, t2
  213. break;
  214. case 4:
  215. swT1 = -(SWORD)slX; // Q14, t1
  216. swT2 = (SWORD)slZ; // Q14, t2
  217. break;
  218. case 6:
  219. swT1 = -(SWORD)slY; // Q14, t1
  220. swT2 = -(SWORD)slZ; // Q14, t2
  221. break;
  222. case 2:
  223. swT1 = (SWORD)slY; // Q14, t1
  224. swT2 = -(SWORD)slX; // Q14, t2
  225. break;
  226. default:
  227. swT1 = 0;
  228. swT2 = 0;
  229. break;
  230. }
  231. /*================================================================
  232. Over voltage modulation
  233. ================================================================*/
  234. switch (coef->uwOvmNo)
  235. {
  236. case 0:
  237. /* SVPWM over modulation: min phase error */
  238. if ((swT1 + swT2) > coef->uwPWMDutyMaxPu)
  239. {
  240. swOvmT1 = (SWORD)(swT1 * (SLONG)coef->uwPWMDutyMaxPu / (swT1 + swT2)); // Q14=Q14+Q14-Q14
  241. swOvmT2 = (SWORD)coef->uwPWMDutyMaxPu - swOvmT1;
  242. out->blOvmFlag = TRUE;
  243. }
  244. else
  245. {
  246. swOvmT1 = swT1;
  247. swOvmT2 = swT2;
  248. out->blOvmFlag = FALSE;
  249. }
  250. break;
  251. case 1:
  252. /* SVPWM over modulation: min amplitude error */
  253. if ((swT1 + swT2) > coef->uwPWMDutyMaxPu)
  254. {
  255. swOvmT1 = swT1 - ((swT1 + swT2 - (SWORD)coef->uwPWMDutyMaxPu) >> 1);
  256. swOvmT2 = swT2 - ((swT1 + swT2 - (SWORD)coef->uwPWMDutyMaxPu) >> 1);
  257. if (swOvmT1 < 0)
  258. {
  259. swOvmT1 = 0;
  260. swOvmT2 = (SWORD)coef->uwPWMDutyMaxPu;
  261. }
  262. if (swOvmT2 < 0)
  263. {
  264. swOvmT2 = 0;
  265. swOvmT1 = (SWORD)coef->uwPWMDutyMaxPu;
  266. }
  267. out->blOvmFlag = TRUE;
  268. }
  269. else
  270. {
  271. swOvmT1 = swT1;
  272. swOvmT2 = swT2;
  273. out->blOvmFlag = FALSE;
  274. }
  275. break;
  276. case 2:
  277. /* SVPWM over modulation: amplitude and phase optimum */
  278. if ((swT1 + swT2) > coef->uwPWMDutyMaxPu)
  279. {
  280. if (swT1 > swT2)
  281. {
  282. if (swT1 > coef->uwPWMDutyMaxPu)
  283. {
  284. swOvmT1 = (SWORD)coef->uwPWMDutyMaxPu;
  285. }
  286. else
  287. {
  288. swOvmT1 = swT1;
  289. }
  290. swOvmT2 = (SWORD)coef->uwPWMDutyMaxPu - swOvmT1;
  291. }
  292. else
  293. {
  294. if (swT2 > (SWORD)coef->uwPWMDutyMaxPu)
  295. {
  296. swOvmT2 = (SWORD)coef->uwPWMDutyMaxPu;
  297. }
  298. else
  299. {
  300. swOvmT2 = swT2;
  301. }
  302. swOvmT1 = (SWORD)coef->uwPWMDutyMaxPu - swOvmT2;
  303. }
  304. out->blOvmFlag = TRUE;
  305. }
  306. else
  307. {
  308. swOvmT1 = swT1;
  309. swOvmT2 = swT2;
  310. out->blOvmFlag = FALSE;
  311. }
  312. break;
  313. default:
  314. /* SVPWM over modulation: amplitude and phase optimum */
  315. if ((swT1 + swT2) > coef->uwPWMDutyMaxPu)
  316. {
  317. if (swT1 > swT2)
  318. {
  319. if (swT1 > coef->uwPWMDutyMaxPu)
  320. {
  321. swOvmT1 =(SWORD) coef->uwPWMDutyMaxPu;
  322. }
  323. else
  324. {
  325. swOvmT1 = swT1;
  326. }
  327. swOvmT2 = (SWORD)coef->uwPWMDutyMaxPu - swOvmT1;
  328. }
  329. else
  330. {
  331. if (swT2 > coef->uwPWMDutyMaxPu)
  332. {
  333. swOvmT2 = (SWORD)coef->uwPWMDutyMaxPu;
  334. }
  335. else
  336. {
  337. swOvmT2 = swT2;
  338. }
  339. swOvmT1 = (SWORD)coef->uwPWMDutyMaxPu - swOvmT2;
  340. }
  341. out->blOvmFlag = TRUE;
  342. }
  343. else
  344. {
  345. swOvmT1 = swT1;
  346. swOvmT2 = swT2;
  347. out->blOvmFlag = FALSE;
  348. }
  349. break;
  350. }
  351. if(cp_stFlg.CurrentSampleModelSelect == COMBINATION)
  352. {
  353. /*================================================================
  354. Calculate compare value
  355. ================================================================*/
  356. if ((swOvmT1 + swOvmT2) > (SWORD)coef->uwPWM7To5DutyPu) /* Five SVPWM */
  357. {
  358. swPWMPRD1 = (SWORD)coef->uwHPWMPd;
  359. swPWMPRD2 = (SWORD)(((SLONG)16384 - swOvmT2) * (SWORD)coef->uwHPWMPd >> 14);
  360. swPWMPRD3 = (SWORD)(((SLONG)16384 - swOvmT1 - swOvmT2) * (SWORD)coef->uwHPWMPd >> 14);
  361. }
  362. else /* Seven SVPWM */
  363. {
  364. swPWMPRD1 = (SWORD)(((SLONG)16384 + swOvmT1 + swOvmT2) * (SWORD)coef->uwHHPWMPd >> 14);
  365. swPWMPRD2 = (SWORD)(((SLONG)16384 + swOvmT1 - swOvmT2) * (SWORD)coef->uwHHPWMPd >> 14);
  366. swPWMPRD3 = (SWORD)(((SLONG)16384 - swOvmT1 - swOvmT2) * (SWORD)coef->uwHHPWMPd >> 14);
  367. }
  368. if (swOvmT2 > coef->uwPWMMinSample3Pu)
  369. {
  370. out->blSampleCalibFlag = TRUE;
  371. //out->uwSigRTrig = swPWMPRD2 + coef->uwSingelResisSampleCt;
  372. out->uwSigRTrig = swPWMPRD1 - coef->uwSingelResisSampleCt;
  373. }
  374. else
  375. {
  376. out->blSampleCalibFlag = FALSE;
  377. out->uwSigRTrig = HW_HHHPWM_PERIOD;
  378. }
  379. out->uwSingelRSampleAreaLast = out->uwSingelRSampleArea;
  380. if(1)//hw_blChrgOvrFlg == TRUE)
  381. {
  382. switch (uwSector)
  383. {
  384. case 3:
  385. out->uwNewTIM1COMPR[0] = swPWMPRD3;
  386. out->uwNewTIM1COMPR[1] = swPWMPRD2;
  387. out->uwNewTIM1COMPR[2] = swPWMPRD1;
  388. out->uwNewTIM1COMPR[3] = swPWMPRD3;
  389. out->uwNewTIM1COMPR[4] = swPWMPRD2;
  390. out->uwNewTIM1COMPR[5] = swPWMPRD1;
  391. if (out->blSampleCalibFlag == TRUE)
  392. {
  393. out->uwSingelRSampleArea = SampleC;
  394. }
  395. else
  396. {
  397. out->uwSingelRSampleArea = SampleNone;
  398. }
  399. break;
  400. case 1:
  401. out->uwNewTIM1COMPR[0] = swPWMPRD2;
  402. out->uwNewTIM1COMPR[1] = swPWMPRD3;
  403. out->uwNewTIM1COMPR[2] = swPWMPRD1;
  404. out->uwNewTIM1COMPR[3] = swPWMPRD2;
  405. out->uwNewTIM1COMPR[4] = swPWMPRD3;
  406. out->uwNewTIM1COMPR[5] = swPWMPRD1;
  407. if (out->blSampleCalibFlag == TRUE)
  408. {
  409. out->uwSingelRSampleArea = SampleC;
  410. }
  411. else
  412. {
  413. out->uwSingelRSampleArea = SampleNone;
  414. }
  415. break;
  416. case 5:
  417. out->uwNewTIM1COMPR[0] = swPWMPRD1;
  418. out->uwNewTIM1COMPR[1] = swPWMPRD3;
  419. out->uwNewTIM1COMPR[2] = swPWMPRD2;
  420. out->uwNewTIM1COMPR[3] = swPWMPRD1;
  421. out->uwNewTIM1COMPR[4] = swPWMPRD3;
  422. out->uwNewTIM1COMPR[5] = swPWMPRD2;
  423. if (out->blSampleCalibFlag == TRUE)
  424. {
  425. out->uwSingelRSampleArea = SampleA;
  426. }
  427. else
  428. {
  429. out->uwSingelRSampleArea = SampleNone;
  430. }
  431. break;
  432. case 4:
  433. out->uwNewTIM1COMPR[0] = swPWMPRD1;
  434. out->uwNewTIM1COMPR[1] = swPWMPRD2;
  435. out->uwNewTIM1COMPR[2] = swPWMPRD3;
  436. out->uwNewTIM1COMPR[3] = swPWMPRD1;
  437. out->uwNewTIM1COMPR[4] = swPWMPRD2;
  438. out->uwNewTIM1COMPR[5] = swPWMPRD3;
  439. if (out->blSampleCalibFlag == TRUE)
  440. {
  441. out->uwSingelRSampleArea = SampleA;
  442. }
  443. else
  444. {
  445. out->uwSingelRSampleArea = SampleNone;
  446. }
  447. break;
  448. case 6:
  449. out->uwNewTIM1COMPR[0] = swPWMPRD2;
  450. out->uwNewTIM1COMPR[1] = swPWMPRD1;
  451. out->uwNewTIM1COMPR[2] = swPWMPRD3;
  452. out->uwNewTIM1COMPR[3] = swPWMPRD2;
  453. out->uwNewTIM1COMPR[4] = swPWMPRD1;
  454. out->uwNewTIM1COMPR[5] = swPWMPRD3;
  455. if (out->blSampleCalibFlag == TRUE)
  456. {
  457. out->uwSingelRSampleArea = SampleB;
  458. }
  459. else
  460. {
  461. out->uwSingelRSampleArea = SampleNone;
  462. }
  463. break;
  464. case 2:
  465. out->uwNewTIM1COMPR[0] = swPWMPRD3;
  466. out->uwNewTIM1COMPR[1] = swPWMPRD1;
  467. out->uwNewTIM1COMPR[2] = swPWMPRD2;
  468. out->uwNewTIM1COMPR[3] = swPWMPRD3;
  469. out->uwNewTIM1COMPR[4] = swPWMPRD1;
  470. out->uwNewTIM1COMPR[5] = swPWMPRD2;
  471. if (out->blSampleCalibFlag == TRUE)
  472. {
  473. out->uwSingelRSampleArea = SampleB;
  474. }
  475. else
  476. {
  477. out->uwSingelRSampleArea = SampleNone;
  478. }
  479. break;
  480. default:
  481. out->uwNewTIM1COMPR[0] = coef->uwHHPWMPd;
  482. out->uwNewTIM1COMPR[1] = coef->uwHHPWMPd;
  483. out->uwNewTIM1COMPR[2] = coef->uwHHPWMPd;
  484. out->uwNewTIM1COMPR[3] = coef->uwHHPWMPd;
  485. out->uwNewTIM1COMPR[4] = coef->uwHHPWMPd;
  486. out->uwNewTIM1COMPR[5] = coef->uwHHPWMPd;
  487. out->uwSingelRSampleArea = SampleNone;
  488. break;
  489. }
  490. }
  491. /* Calculate actual output voltage */
  492. out->uwNewSectorNum = uwSector;
  493. out->uwPWMNewSectorNum = out->uwNewSectorNum;
  494. tmp_swPeriodA = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[0] - (SWORD)out->uwNewTIM1COMPR[3];
  495. tmp_swPeriodB = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[1] - (SWORD)out->uwNewTIM1COMPR[4];
  496. tmp_swPeriodC = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[2] - (SWORD)out->uwNewTIM1COMPR[5];
  497. swUaPu = (SWORD)(((((SLONG)tmp_swPeriodA * (SLONG)coef->ulPWMPerInv) >> 5) * (SWORD)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14
  498. swUbPu = (SWORD)(((((SLONG)tmp_swPeriodB * (SLONG)coef->ulPWMPerInv) >> 5) * (SWORD)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14
  499. swUcPu = (SWORD)(((((SLONG)tmp_swPeriodC * (SLONG)coef->ulPWMPerInv) >> 5) * (SWORD)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14
  500. out->swUalphaPu = (swUaPu + swUaPu - swUbPu - swUcPu) * PWM_1DIV3 >> 14; // Q14=Q14+Q14-Q14
  501. out->swUbetaPu = (swUbPu - swUcPu) * PWM_SQRT3_INV >> 14; // Q14=Q14+Q14-Q14
  502. out->uwRDSONTrig = 129;
  503. }
  504. else if(cp_stFlg.CurrentSampleModelSelect == SINGLERESISITANCE)
  505. {
  506. SWORD swPWMPRD11=0;
  507. SWORD swPWMPRD21=0;
  508. SWORD swPWMPRD31=0;
  509. SWORD swPWMPRD12=0;
  510. SWORD swPWMPRD22=0;
  511. SWORD swPWMPRD32=0;
  512. /*1/4 of zero vector in the middle,and others apart in the beginning and ending*/
  513. swPWMPRD1 = (SWORD)((((SLONG)16384 * 3 + swOvmT1 + swOvmT2) * (SWORD)coef->uwPWMPd) >> 17); // Q14
  514. swPWMPRD2 = (SWORD)((((SLONG)16384 * 3 + swOvmT1 - swOvmT2 * 3) * (SWORD)coef->uwPWMPd) >> 17);
  515. swPWMPRD3 = (SWORD)((((SLONG)16384 - swOvmT1 - swOvmT2) * 3 * (SWORD)coef->uwPWMPd) >> 17);
  516. swPWMPRD11 = swPWMPRD1;
  517. swPWMPRD21 = swPWMPRD2;
  518. swPWMPRD31 = swPWMPRD3;
  519. swPWMPRD12 = swPWMPRD1;
  520. swPWMPRD22 = swPWMPRD2;
  521. swPWMPRD32 = swPWMPRD3;
  522. /* comparision value correction when two vectors are both too short*/
  523. if ((swOvmT1 + swOvmT2) < (pwm_pvt_swMin_Double_Cur_Smpl_Pu << 1))
  524. {
  525. if ((swOvmT1 - pwm_pvt_swMin_Double_Cur_Smpl_Pu) < 0)
  526. {
  527. swPWMPRD31 = swPWMPRD2 - pwm_pvt_swMin_Cur_Smpl_Ct;
  528. swPWMPRD32 = (swPWMPRD3 << 1) - swPWMPRD31;
  529. }
  530. if ((swOvmT2 - pwm_pvt_swMin_Double_Cur_Smpl_Pu) < 0)
  531. {
  532. swPWMPRD11 = swPWMPRD2 + pwm_pvt_swMin_Cur_Smpl_Ct;
  533. swPWMPRD12 = (swPWMPRD1 << 1) - swPWMPRD11;
  534. }
  535. }
  536. else
  537. {
  538. if ((swOvmT2 - pwm_pvt_swMin_Double_Cur_Smpl_Pu) < 0)
  539. {
  540. if (((coef->uwHPWMPd + swPWMPRD1 - 2 * swPWMPRD2) <= pwm_pvt_swMin_Cur_Smpl_Ct) && ((swOvmT1 + swOvmT2) > coef->uwPWM7To5DutyPu))
  541. {
  542. swPWMPRD1 = (SWORD)((((SLONG)swOvmT1 + swOvmT2) * (SLONG)coef->uwPWMPd) >> 15);
  543. swPWMPRD2 = (SWORD)(((SLONG)swOvmT1 * (SLONG)coef->uwPWMPd) >> 15);
  544. swPWMPRD3 = 0;
  545. swPWMPRD11 = (SWORD)coef->uwHPWMPd;
  546. swPWMPRD12 = (swPWMPRD1 << 1) - swPWMPRD11;
  547. swPWMPRD31 = swPWMPRD3;
  548. swPWMPRD32 = swPWMPRD3;
  549. swPWMPRD22 = (SWORD)coef->uwHPWMPd;
  550. swPWMPRD21 = (swPWMPRD2 << 1) - swPWMPRD22;
  551. }
  552. else
  553. {
  554. swPWMPRD21 = swPWMPRD1 - pwm_pvt_swMin_Cur_Smpl_Ct;
  555. swPWMPRD22 = (swPWMPRD2 << 1) - swPWMPRD21;
  556. }
  557. }
  558. else if ((swOvmT1 - pwm_pvt_swMin_Double_Cur_Smpl_Pu) < 0)
  559. {
  560. if (((2 * swPWMPRD2 - swPWMPRD3) <= pwm_pvt_swMin_Cur_Smpl_Ct) && ((swOvmT1 + swOvmT2) > coef->uwPWM7To5DutyPu))
  561. {
  562. swPWMPRD1 = (SWORD)coef->uwHPWMPd;
  563. swPWMPRD2 = (SWORD)(((SLONG)16384 - swOvmT2) * (SWORD)coef->uwPWMPd >> 15);
  564. swPWMPRD3 = (SWORD)(((SLONG)16384 - swOvmT1 - swOvmT2) * (SWORD)coef->uwPWMPd >> 15);
  565. swPWMPRD11 = swPWMPRD1;
  566. swPWMPRD12 = swPWMPRD1;
  567. swPWMPRD22 = 0;
  568. swPWMPRD21 = (swPWMPRD2 << 1) - swPWMPRD22;
  569. swPWMPRD31 = 0;
  570. swPWMPRD32 = (swPWMPRD3 << 1) - swPWMPRD31;
  571. }
  572. else
  573. {
  574. swPWMPRD21 = swPWMPRD3 + pwm_pvt_swMin_Cur_Smpl_Ct;
  575. swPWMPRD22 = (swPWMPRD2 << 1) - swPWMPRD21;
  576. }
  577. }
  578. else
  579. {
  580. //do nothing
  581. }
  582. }
  583. out->uwOldTrig = out->uwNewTrig;
  584. out->uwNewTrig = swPWMPRD21;
  585. switch (uwSector)
  586. {
  587. case 3:
  588. out->uwNewTIM1COMPR[0] = swPWMPRD31;
  589. out->uwNewTIM1COMPR[1] = swPWMPRD21;
  590. out->uwNewTIM1COMPR[2] = swPWMPRD11;
  591. out->uwNewTIM1COMPR[3] = swPWMPRD32;
  592. out->uwNewTIM1COMPR[4] = swPWMPRD22;
  593. out->uwNewTIM1COMPR[5] = swPWMPRD12;
  594. out->uwFirstTrigCOMPR = swPWMPRD21 - pwm_pvt_sw1st_Cur_Smpl_Ct;
  595. out->uwSecondTrigCOMPR = swPWMPRD21 + pwm_pvt_sw2nd_Cur_Smpl_Ct;
  596. break;
  597. case 1:
  598. out->uwNewTIM1COMPR[0] = swPWMPRD21;
  599. out->uwNewTIM1COMPR[1] = swPWMPRD31;
  600. out->uwNewTIM1COMPR[2] = swPWMPRD11;
  601. out->uwNewTIM1COMPR[3] = swPWMPRD22;
  602. out->uwNewTIM1COMPR[4] = swPWMPRD32;
  603. out->uwNewTIM1COMPR[5] = swPWMPRD12;
  604. out->uwFirstTrigCOMPR = swPWMPRD21 - pwm_pvt_sw1st_Cur_Smpl_Ct;
  605. out->uwSecondTrigCOMPR = swPWMPRD21 + pwm_pvt_sw2nd_Cur_Smpl_Ct;
  606. break;
  607. case 5:
  608. out->uwNewTIM1COMPR[0] = swPWMPRD11;
  609. out->uwNewTIM1COMPR[1] = swPWMPRD31;
  610. out->uwNewTIM1COMPR[2] = swPWMPRD21;
  611. out->uwNewTIM1COMPR[3] = swPWMPRD12;
  612. out->uwNewTIM1COMPR[4] = swPWMPRD32;
  613. out->uwNewTIM1COMPR[5] = swPWMPRD22;
  614. out->uwFirstTrigCOMPR = swPWMPRD21 - pwm_pvt_sw1st_Cur_Smpl_Ct;
  615. out->uwSecondTrigCOMPR = swPWMPRD21 + pwm_pvt_sw2nd_Cur_Smpl_Ct;
  616. break;
  617. case 4:
  618. out->uwNewTIM1COMPR[0] = swPWMPRD11;
  619. out->uwNewTIM1COMPR[1] = swPWMPRD21;
  620. out->uwNewTIM1COMPR[2] = swPWMPRD31;
  621. out->uwNewTIM1COMPR[3] = swPWMPRD12;
  622. out->uwNewTIM1COMPR[4] = swPWMPRD22;
  623. out->uwNewTIM1COMPR[5] = swPWMPRD32;
  624. out->uwFirstTrigCOMPR = swPWMPRD21 - pwm_pvt_sw1st_Cur_Smpl_Ct;
  625. out->uwSecondTrigCOMPR = swPWMPRD21 + pwm_pvt_sw2nd_Cur_Smpl_Ct;
  626. break;
  627. case 6:
  628. out->uwNewTIM1COMPR[0] = swPWMPRD21;
  629. out->uwNewTIM1COMPR[1] = swPWMPRD11;
  630. out->uwNewTIM1COMPR[2] = swPWMPRD31;
  631. out->uwNewTIM1COMPR[3] = swPWMPRD22;
  632. out->uwNewTIM1COMPR[4] = swPWMPRD12;
  633. out->uwNewTIM1COMPR[5] = swPWMPRD32;
  634. out->uwFirstTrigCOMPR = swPWMPRD21 - pwm_pvt_sw1st_Cur_Smpl_Ct;
  635. out->uwSecondTrigCOMPR = swPWMPRD21 + pwm_pvt_sw2nd_Cur_Smpl_Ct;
  636. break;
  637. case 2:
  638. out->uwNewTIM1COMPR[0] = swPWMPRD31;
  639. out->uwNewTIM1COMPR[1] = swPWMPRD11;
  640. out->uwNewTIM1COMPR[2] = swPWMPRD21;
  641. out->uwNewTIM1COMPR[3] = swPWMPRD32;
  642. out->uwNewTIM1COMPR[4] = swPWMPRD12;
  643. out->uwNewTIM1COMPR[5] = swPWMPRD22;
  644. out->uwFirstTrigCOMPR = swPWMPRD21 - pwm_pvt_sw1st_Cur_Smpl_Ct;
  645. out->uwSecondTrigCOMPR = swPWMPRD21 + pwm_pvt_sw2nd_Cur_Smpl_Ct;
  646. break;
  647. default:
  648. out->uwNewTIM1COMPR[0] = coef->uwHHPWMPd;
  649. out->uwNewTIM1COMPR[1] = coef->uwHHPWMPd;
  650. out->uwNewTIM1COMPR[2] = coef->uwHHPWMPd;
  651. out->uwNewTIM1COMPR[3] = coef->uwHHPWMPd;
  652. out->uwNewTIM1COMPR[4] = coef->uwHHPWMPd;
  653. out->uwNewTIM1COMPR[5] = coef->uwHHPWMPd;
  654. out->uwFirstTrigCOMPR = coef->uwHHPWMPd >> 1;
  655. out->uwSecondTrigCOMPR = coef->uwHPWMPd - coef->uwHHPWMPd >> 1;
  656. break;
  657. }
  658. out->uwNewSectorNum = uwSector;
  659. out->uwPWMNewSectorNum = out->uwNewSectorNum;
  660. tmp_swPeriodA = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[0] - (SWORD)out->uwNewTIM1COMPR[3];
  661. tmp_swPeriodB = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[1] - (SWORD)out->uwNewTIM1COMPR[4];
  662. tmp_swPeriodC = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[2] - (SWORD)out->uwNewTIM1COMPR[5];
  663. swUaPu = (SWORD)(((tmp_swPeriodA * (SLONG)coef->ulPWMPerInv >> 5) * (SWORD)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14
  664. swUbPu = (SWORD)(((tmp_swPeriodB * (SLONG)coef->ulPWMPerInv >> 5) * (SWORD)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14
  665. swUcPu = (SWORD)(((tmp_swPeriodC * (SLONG)coef->ulPWMPerInv >> 5) * (SWORD)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14
  666. out->swUalphaPu = (swUaPu + swUaPu - swUbPu - swUcPu) * PWM_1DIV3 >> 14; // Q14=Q14+Q14-Q14
  667. out->swUbetaPu = (swUbPu - swUcPu) * PWM_SQRT3_INV >> 14; // Q14=Q14+Q14-Q14
  668. }
  669. else if(cp_stFlg.CurrentSampleModelSelect == RDSON)
  670. {
  671. /*================================================================
  672. Calculate compare value
  673. ================================================================*/
  674. if ((swOvmT1 + swOvmT2) > coef->uwPWM7To5DutyPu) /* Five SVPWM */
  675. {
  676. swPWMPRD1 = (SWORD)coef->uwHPWMPd;
  677. swPWMPRD2 = (SWORD)((((SLONG)16384 - swOvmT2) * (SWORD)coef->uwHPWMPd) >> 14);
  678. swPWMPRD3 = (SWORD)((((SLONG)16384 - swOvmT1 - swOvmT2) * (SWORD)coef->uwHPWMPd) >> 14);
  679. }
  680. else /* Seven SVPWM */
  681. {
  682. swPWMPRD1 = (SWORD)((((SLONG)16384 + swOvmT1 + swOvmT2) * (SWORD)coef->uwHHPWMPd) >> 14);
  683. swPWMPRD2 = (SWORD)((((SLONG)16384 + swOvmT1 - swOvmT2) * (SWORD)coef->uwHHPWMPd) >> 14);
  684. swPWMPRD3 = (SWORD)((((SLONG)16384 - swOvmT1 - swOvmT2) * (SWORD)coef->uwHHPWMPd) >> 14);
  685. }
  686. switch (uwSector)
  687. {
  688. case 3:
  689. out->uwNewTIM1COMPR[0] = swPWMPRD3;
  690. out->uwNewTIM1COMPR[1] = swPWMPRD2;
  691. out->uwNewTIM1COMPR[2] = swPWMPRD1;
  692. out->uwNewTIM1COMPR[3] = swPWMPRD3;
  693. out->uwNewTIM1COMPR[4] = swPWMPRD2;
  694. out->uwNewTIM1COMPR[5] = swPWMPRD1;
  695. break;
  696. case 1:
  697. out->uwNewTIM1COMPR[0] = swPWMPRD2;
  698. out->uwNewTIM1COMPR[1] = swPWMPRD3;
  699. out->uwNewTIM1COMPR[2] = swPWMPRD1;
  700. out->uwNewTIM1COMPR[3] = swPWMPRD2;
  701. out->uwNewTIM1COMPR[4] = swPWMPRD3;
  702. out->uwNewTIM1COMPR[5] = swPWMPRD1;
  703. break;
  704. case 5:
  705. out->uwNewTIM1COMPR[0] = swPWMPRD1;
  706. out->uwNewTIM1COMPR[1] = swPWMPRD3;
  707. out->uwNewTIM1COMPR[2] = swPWMPRD2;
  708. out->uwNewTIM1COMPR[3] = swPWMPRD1;
  709. out->uwNewTIM1COMPR[4] = swPWMPRD3;
  710. out->uwNewTIM1COMPR[5] = swPWMPRD2;
  711. break;
  712. case 4:
  713. out->uwNewTIM1COMPR[0] = swPWMPRD1;
  714. out->uwNewTIM1COMPR[1] = swPWMPRD2;
  715. out->uwNewTIM1COMPR[2] = swPWMPRD3;
  716. out->uwNewTIM1COMPR[3] = swPWMPRD1;
  717. out->uwNewTIM1COMPR[4] = swPWMPRD2;
  718. out->uwNewTIM1COMPR[5] = swPWMPRD3;
  719. break;
  720. case 6:
  721. out->uwNewTIM1COMPR[0] = swPWMPRD2;
  722. out->uwNewTIM1COMPR[1] = swPWMPRD1;
  723. out->uwNewTIM1COMPR[2] = swPWMPRD3;
  724. out->uwNewTIM1COMPR[3] = swPWMPRD2;
  725. out->uwNewTIM1COMPR[4] = swPWMPRD1;
  726. out->uwNewTIM1COMPR[5] = swPWMPRD3;
  727. break;
  728. case 2:
  729. out->uwNewTIM1COMPR[0] = swPWMPRD3;
  730. out->uwNewTIM1COMPR[1] = swPWMPRD1;
  731. out->uwNewTIM1COMPR[2] = swPWMPRD2;
  732. out->uwNewTIM1COMPR[3] = swPWMPRD3;
  733. out->uwNewTIM1COMPR[4] = swPWMPRD1;
  734. out->uwNewTIM1COMPR[5] = swPWMPRD2;
  735. break;
  736. default:
  737. out->uwNewTIM1COMPR[0] = coef->uwHHPWMPd;
  738. out->uwNewTIM1COMPR[1] = coef->uwHHPWMPd;
  739. out->uwNewTIM1COMPR[2] = coef->uwHHPWMPd;
  740. out->uwNewTIM1COMPR[3] = coef->uwHHPWMPd;
  741. out->uwNewTIM1COMPR[4] = coef->uwHHPWMPd;
  742. out->uwNewTIM1COMPR[5] = coef->uwHHPWMPd;
  743. break;
  744. }
  745. /* Calculate actual output voltage */
  746. out->uwNewSectorNum = uwSector;
  747. out->uwPWMNewSectorNum = out->uwNewSectorNum;
  748. tmp_swPeriodA = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[0] - (SWORD)out->uwNewTIM1COMPR[3];
  749. tmp_swPeriodB = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[1] - (SWORD)out->uwNewTIM1COMPR[4];
  750. tmp_swPeriodC = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[2] - (SWORD)out->uwNewTIM1COMPR[5];
  751. swUaPu = (SWORD)((((tmp_swPeriodA * (SLONG)coef->ulPWMPerInv) >> 5) * (SLONG)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14
  752. swUbPu = (SWORD)((((tmp_swPeriodB * (SLONG)coef->ulPWMPerInv) >> 5) * (SLONG)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14
  753. swUcPu = (SWORD)((((tmp_swPeriodC * (SLONG)coef->ulPWMPerInv) >> 5) * (SLONG)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14
  754. out->swUalphaPu = (swUaPu + swUaPu - swUbPu - swUcPu) * PWM_1DIV3 >> 14; // Q14=Q14+Q14-Q14
  755. out->swUbetaPu = (swUbPu - swUcPu) * PWM_SQRT3_INV >> 14; // Q14=Q14+Q14-Q14
  756. if ((16384 - swOvmT1 - swOvmT2) > coef->uwPWMMinSample1Pu)
  757. {
  758. out->uwSampleArea = IgnoreNone;
  759. out->uwRDSONTrig = 129;
  760. }
  761. else
  762. {
  763. if (swOvmT1 > coef->uwPWMMinSample1Pu)
  764. {
  765. switch (uwSector)
  766. {
  767. case 3:
  768. out->uwSampleArea = IgnoreA;
  769. break;
  770. case 1:
  771. out->uwSampleArea = IgnoreB;
  772. break;
  773. case 5:
  774. out->uwSampleArea = IgnoreB;
  775. break;
  776. case 4:
  777. out->uwSampleArea = IgnoreC;
  778. break;
  779. case 6:
  780. out->uwSampleArea = IgnoreC;
  781. break;
  782. case 2:
  783. out->uwSampleArea = IgnoreA;
  784. break;
  785. default:
  786. out->uwSampleArea = IgnoreNone;
  787. break;
  788. }
  789. out->uwRDSONTrig = swPWMPRD3 + coef->uwSampleSteadyCt;
  790. }
  791. else
  792. {
  793. switch (uwSector)
  794. {
  795. case 3:
  796. out->uwSampleArea = IgnoreAB;
  797. break;
  798. case 1:
  799. out->uwSampleArea = IgnoreAB;
  800. break;
  801. case 5:
  802. out->uwSampleArea = IgnoreBC;
  803. break;
  804. case 4:
  805. out->uwSampleArea = IgnoreBC;
  806. break;
  807. case 6:
  808. out->uwSampleArea = IgnoreAC;
  809. break;
  810. case 2:
  811. out->uwSampleArea = IgnoreAC;
  812. break;
  813. default:
  814. out->uwSampleArea = IgnoreNone;
  815. break;
  816. }
  817. out->uwRDSONTrig = swPWMPRD2 + coef->uwSampleSteadyCt;
  818. }
  819. }
  820. }
  821. else
  822. {
  823. //do nothing
  824. }
  825. }
  826. /************************************************************************
  827. Local Functions: N/A
  828. ************************************************************************/
  829. /************************************************************************
  830. Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.
  831. All rights reserved.
  832. ************************************************************************/
  833. #ifdef _PWM_C_
  834. #undef _PWM_C_ /* parasoft-suppress MISRA2004-19_6 "本项目中无法更改,后续避免使用" */
  835. #endif
  836. /************************************************************************
  837. End of this File (EOF)!
  838. Do not put anything after this part!
  839. ************************************************************************/