pwm.c 34 KB

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