pwm.c 33 KB

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