stm32f10x_svpwm_3shunt.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. #include "stm32f10x_svpwm_3shunt.h"
  2. #include "MC_const.h"
  3. #include "adc.h"
  4. #include "pwm_driver.h"
  5. //全局变量定义
  6. uint16_t bSector;
  7. uint8_t PWM4Direction=0;
  8. typedef struct
  9. {
  10. uint16_t hTimePhA;
  11. uint16_t hTimePhB;
  12. uint16_t hTimePhC;
  13. uint16_t hTimePhD;
  14. }hTimePhase_Struct_t;
  15. hTimePhase_Struct_t hTimePhase;
  16. /**************************全局函数定义*************************/
  17. //3相电流校零
  18. void SVPWM_3ShuntCurrentReadingCalibration(MC_ErrorCode_Struct_t* p_MC_ErrorCode)
  19. {
  20. uint16_t bIndex;
  21. uint32_t ul_phase_a_offset_sum = 0;
  22. uint32_t ul_phase_b_offset_sum = 0;
  23. uint32_t ul_phase_c_offset_sum = 0;
  24. Disable_Pwm_Output();
  25. for(bIndex=0; bIndex < 10; bIndex++)
  26. {
  27. //wait the ADC1 JEOC pending flag */
  28. do
  29. {
  30. ;
  31. }while(SET != ADC2_ConvCpmplete_Flag);
  32. ///Clear the ADC1 JEOC pending flag */
  33. ADC2_ConvCpmplete_Flag = RESET;
  34. ul_phase_a_offset_sum = ADC2_Result[ADC2_RANK_CURRENT_A] + ul_phase_a_offset_sum;
  35. ul_phase_b_offset_sum = ADC2_Result[ADC2_RANK_CURRENT_B] + ul_phase_b_offset_sum;
  36. ul_phase_c_offset_sum = ADC2_Result[ADC2_RANK_CURRENT_C] + ul_phase_c_offset_sum;
  37. HAL_TIM_PWM_Start(&PWM_TIMER, TIM_CHANNEL_4);
  38. }
  39. ADC_3ShuntCurrent_OffSet.uw_phase_a_offset = ul_phase_a_offset_sum / 10;
  40. ADC_3ShuntCurrent_OffSet.uw_phase_b_offset = ul_phase_b_offset_sum / 10;
  41. ADC_3ShuntCurrent_OffSet.uw_phase_c_offset = ul_phase_c_offset_sum / 10;
  42. //判断零点值是否在正常范围内
  43. if(((ADC_3ShuntCurrent_OffSet.uw_phase_a_offset < 25000) || (ADC_3ShuntCurrent_OffSet.uw_phase_a_offset > 40000)) ||
  44. ((ADC_3ShuntCurrent_OffSet.uw_phase_b_offset < 25000) || (ADC_3ShuntCurrent_OffSet.uw_phase_b_offset > 40000)) ||
  45. ((ADC_3ShuntCurrent_OffSet.uw_phase_c_offset < 25000) || (ADC_3ShuntCurrent_OffSet.uw_phase_c_offset > 40000))
  46. )
  47. {
  48. p_MC_ErrorCode->ERROR_Bit.Fault_Circuit = 1;
  49. }
  50. Disable_Pwm_Output();
  51. }
  52. //母线电流校零
  53. void CurrentReadingCalibration(MC_ErrorCode_Struct_t* p_MC_ErrorCode)
  54. {
  55. static TrueOrFalse_Flag_Struct_t IsFirstEnterFlag = TRUE;
  56. static uint32_t PeriodTimeCnt = 0;
  57. static uint32_t LeaveTime = 0;
  58. uint32_t ul_current_offset_sum = 0;
  59. uint16_t bIndex;
  60. if(IsFirstEnterFlag == TRUE)
  61. {
  62. for(bIndex=0; bIndex < 10; bIndex++)
  63. {
  64. ul_current_offset_sum = ADC1_Result[ADC1_RANK_CURRENT] + ul_current_offset_sum;
  65. }
  66. uw_current_offset = ul_current_offset_sum / 10;
  67. PeriodTimeCnt = HAL_GetTick();
  68. LeaveTime = HAL_GetTick();
  69. IsFirstEnterFlag = FALSE;
  70. }
  71. else
  72. {
  73. if((HAL_GetTick() - LeaveTime) > 500)
  74. {
  75. PeriodTimeCnt = HAL_GetTick();
  76. }
  77. if((HAL_GetTick() - PeriodTimeCnt) > 2000)
  78. {
  79. for(bIndex=0; bIndex < 10; bIndex++)
  80. {
  81. ul_current_offset_sum = ADC1_Result[ADC1_RANK_CURRENT] + ul_current_offset_sum;
  82. }
  83. uw_current_offset = ul_current_offset_sum / 10;
  84. if((uw_current_offset < 1000) || (uw_current_offset > 3000))
  85. {
  86. p_MC_ErrorCode->ERROR_Bit.Fault_Circuit = 1;
  87. }
  88. PeriodTimeCnt = HAL_GetTick();
  89. }
  90. }
  91. LeaveTime = HAL_GetTick();
  92. }
  93. //3相占空比设置
  94. void SVPWM_3ShuntCalcDutyCycles (Volt_Components Stat_Volt_Input)
  95. {
  96. int32_t wX, wY, wZ, wUAlpha, wUBeta;
  97. uint16_t hDeltaDuty;
  98. wUAlpha = Stat_Volt_Input.qV_Component1 * T_SQRT3 ;
  99. wUBeta = -(Stat_Volt_Input.qV_Component2 * T);
  100. wX = wUBeta;
  101. wY = (wUBeta + wUAlpha) >> 1;
  102. wZ = (wUBeta - wUAlpha) >> 1;
  103. // Sector calculation from wX, wY, wZ
  104. if (wY<0)
  105. {
  106. if (wZ<0)
  107. {
  108. bSector = SECTOR_5;
  109. }
  110. else // wZ >= 0
  111. if (wX<=0)
  112. {
  113. bSector = SECTOR_4;
  114. }
  115. else // wX > 0
  116. {
  117. bSector = SECTOR_3;
  118. }
  119. }
  120. else // wY > 0
  121. {
  122. if (wZ>=0)
  123. {
  124. bSector = SECTOR_2;
  125. }
  126. else // wZ < 0
  127. if (wX<=0)
  128. {
  129. bSector = SECTOR_6;
  130. }
  131. else // wX > 0
  132. {
  133. bSector = SECTOR_1;
  134. }
  135. }
  136. PWM4Direction=0;
  137. switch(bSector)
  138. {
  139. case SECTOR_1:
  140. hTimePhase.hTimePhA = (T >> 3) + ((((T + wX) - wZ) >> 1) >> 17);
  141. hTimePhase.hTimePhB = hTimePhase.hTimePhA + (wZ >> 17);
  142. hTimePhase.hTimePhC = hTimePhase.hTimePhB - (wX >> 17);
  143. // hTimePhD = PWM_PERIOD - 1;
  144. // ADC Syncronization setting value
  145. if ((uint16_t)(PWM_PERIOD-hTimePhase.hTimePhA) > TW_AFTER)
  146. {
  147. hTimePhase.hTimePhD = PWM_PERIOD - 1;
  148. }
  149. else
  150. {
  151. hDeltaDuty = (uint16_t)(hTimePhase.hTimePhA - hTimePhase.hTimePhB);
  152. // Definition of crossing point
  153. if (hDeltaDuty > TW_DT_TR_TS)
  154. {
  155. hTimePhase.hTimePhD = hTimePhase.hTimePhA - TW_BEFORE; // Ts before Phase A
  156. }
  157. else if((uint16_t)(PWM_PERIOD-hTimePhase.hTimePhA) >TW_DT_TN_TS_HALF)
  158. {
  159. hTimePhase.hTimePhD = hTimePhase.hTimePhA + TW_AFTER; // DT + Tn after Phase A
  160. if (hTimePhase.hTimePhD >= PWM_PERIOD)
  161. {
  162. // Trigger of ADC at Falling Edge PWM4
  163. // OCR update
  164. //Set Polarity of CC4 Low
  165. PWM4Direction=1;
  166. hTimePhase.hTimePhD = (2 * PWM_PERIOD) - hTimePhase.hTimePhD-1;
  167. }
  168. }
  169. // else
  170. // {
  171. // while(1);
  172. // }
  173. }
  174. break;
  175. case SECTOR_2:
  176. hTimePhase.hTimePhA = (T >> 3) + ((((T + wY) - wZ) >> 1) >> 17);
  177. hTimePhase.hTimePhB = hTimePhase.hTimePhA + (wZ >> 17);
  178. hTimePhase.hTimePhC = hTimePhase.hTimePhA - (wY >> 17);
  179. // hTimePhD = PWM_PERIOD - 1;
  180. // ADC Syncronization setting value
  181. if ((uint16_t)(PWM_PERIOD-hTimePhase.hTimePhB) > TW_AFTER)
  182. {
  183. hTimePhase.hTimePhD = PWM_PERIOD - 1;
  184. }
  185. else
  186. {
  187. hDeltaDuty = (uint16_t)(hTimePhase.hTimePhB - hTimePhase.hTimePhA);
  188. // Definition of crossing point
  189. if (hDeltaDuty > TW_DT_TR_TS)
  190. {
  191. hTimePhase.hTimePhD = hTimePhase.hTimePhB - TW_BEFORE; // Ts before Phase B
  192. }
  193. else if((uint16_t)(PWM_PERIOD-hTimePhase.hTimePhB) > TW_DT_TN_TS_HALF)
  194. {
  195. hTimePhase.hTimePhD = hTimePhase.hTimePhB + TW_AFTER; // DT + Tn after Phase B
  196. if (hTimePhase.hTimePhD >= PWM_PERIOD)
  197. {
  198. PWM4Direction=1;
  199. hTimePhase.hTimePhD = (2 * PWM_PERIOD) - hTimePhase.hTimePhD-1;
  200. }
  201. }
  202. // else
  203. // {
  204. // while(1);
  205. // }
  206. }
  207. break;
  208. case SECTOR_3:
  209. hTimePhase.hTimePhA = (T >> 3) + ((((T - wX) + wY) >> 1) >> 17);
  210. hTimePhase.hTimePhC = hTimePhase.hTimePhA - (wY >> 17);
  211. hTimePhase.hTimePhB = hTimePhase.hTimePhC + (wX >> 17);
  212. // hTimePhD = PWM_PERIOD - 1;
  213. // ADC Syncronization setting value
  214. if ((uint16_t)(PWM_PERIOD-hTimePhase.hTimePhB) > TW_AFTER)
  215. {
  216. hTimePhase.hTimePhD = PWM_PERIOD - 1;
  217. }
  218. else
  219. {
  220. hDeltaDuty = (uint16_t)(hTimePhase.hTimePhB - hTimePhase.hTimePhC);
  221. // Definition of crossing point
  222. if (hDeltaDuty > TW_DT_TR_TS)
  223. {
  224. hTimePhase.hTimePhD = hTimePhase.hTimePhB - TW_BEFORE; // Ts before Phase B
  225. }
  226. else if((uint16_t)(PWM_PERIOD-hTimePhase.hTimePhB) > TW_DT_TN_TS_HALF)
  227. {
  228. hTimePhase.hTimePhD = hTimePhase.hTimePhB + TW_AFTER; // DT + Tn after Phase B
  229. if (hTimePhase.hTimePhD >= PWM_PERIOD)
  230. {
  231. // Trigger of ADC at Falling Edge PWM4
  232. // OCR update
  233. //Set Polarity of CC4 Low
  234. PWM4Direction=1;
  235. hTimePhase.hTimePhD = (2 * PWM_PERIOD) - hTimePhase.hTimePhD-1;
  236. }
  237. }
  238. // else
  239. // {
  240. // while(1);
  241. // }
  242. }
  243. break;
  244. case SECTOR_4:
  245. hTimePhase.hTimePhA = (T>> 3) + ((((T + wX) - wZ) >> 1) >> 17);
  246. hTimePhase.hTimePhB = hTimePhase.hTimePhA + (wZ >> 17);
  247. hTimePhase.hTimePhC = hTimePhase.hTimePhB - (wX >> 17);
  248. // hTimePhD = PWM_PERIOD - 1;
  249. // ADC Syncronization setting value
  250. if ((uint16_t)(PWM_PERIOD-hTimePhase.hTimePhC) > TW_AFTER)
  251. {
  252. hTimePhase.hTimePhD = PWM_PERIOD - 1;
  253. }
  254. else
  255. {
  256. hDeltaDuty = (uint16_t)(hTimePhase.hTimePhC - hTimePhase.hTimePhB);
  257. // Definition of crossing point
  258. if (hDeltaDuty > TW_DT_TR_TS)
  259. {
  260. hTimePhase.hTimePhD = hTimePhase.hTimePhC - TW_BEFORE; // Ts before Phase C
  261. }
  262. else if((uint16_t)(PWM_PERIOD-hTimePhase.hTimePhC) > TW_DT_TN_TS_HALF)
  263. {
  264. hTimePhase.hTimePhD = hTimePhase.hTimePhC + TW_AFTER; // DT + Tn after Phase C
  265. if (hTimePhase.hTimePhD >= PWM_PERIOD)
  266. {
  267. // Trigger of ADC at Falling Edge PWM4
  268. // OCR update
  269. //Set Polarity of CC4 Low
  270. PWM4Direction=1;
  271. hTimePhase.hTimePhD = (2 * PWM_PERIOD) - hTimePhase.hTimePhD-1;
  272. }
  273. }
  274. // else
  275. // {
  276. // while(1);
  277. // }
  278. }
  279. break;
  280. case SECTOR_5:
  281. hTimePhase.hTimePhA = (T >> 3) + ((((T + wY) - wZ) >> 1) >> 17);
  282. hTimePhase.hTimePhB = hTimePhase.hTimePhA + (wZ >> 17);
  283. hTimePhase.hTimePhC = hTimePhase.hTimePhA - (wY >> 17);
  284. // hTimePhD = PWM_PERIOD - 1;
  285. // ADC Syncronization setting value
  286. if ((uint16_t)(PWM_PERIOD-hTimePhase.hTimePhC) > TW_AFTER)
  287. {
  288. hTimePhase.hTimePhD = PWM_PERIOD - 1;
  289. }
  290. else
  291. {
  292. hDeltaDuty = (uint16_t)(hTimePhase.hTimePhC - hTimePhase.hTimePhA);
  293. // Definition of crossing point
  294. if (hDeltaDuty > TW_DT_TR_TS)
  295. {
  296. hTimePhase.hTimePhD = hTimePhase.hTimePhC - TW_BEFORE; // Ts before Phase C
  297. }
  298. else if((uint16_t)(PWM_PERIOD-hTimePhase.hTimePhC) > TW_DT_TN_TS_HALF)
  299. {
  300. hTimePhase.hTimePhD = hTimePhase.hTimePhC + TW_AFTER; // DT + Tn after Phase C
  301. if (hTimePhase.hTimePhD >= PWM_PERIOD)
  302. {
  303. // Trigger of ADC at Falling Edge PWM4
  304. // OCR update
  305. //Set Polarity of CC4 Low
  306. PWM4Direction=1;
  307. hTimePhase.hTimePhD = (2 * PWM_PERIOD) - hTimePhase.hTimePhD-1;
  308. }
  309. }
  310. // else
  311. // {
  312. // while(1);
  313. // }
  314. }
  315. break;
  316. case SECTOR_6:
  317. hTimePhase.hTimePhA = (T >> 3) + ((((T - wX) + wY) >> 1) >> 17);
  318. hTimePhase.hTimePhC = hTimePhase.hTimePhA - (wY >> 17);
  319. hTimePhase.hTimePhB = hTimePhase.hTimePhC + (wX >> 17);
  320. hTimePhase.hTimePhD = PWM_PERIOD - 1;
  321. // ADC Syncronization setting value
  322. if ((uint16_t)(PWM_PERIOD-hTimePhase.hTimePhA) > TW_AFTER)
  323. {
  324. hTimePhase.hTimePhD = PWM_PERIOD - 1;
  325. }
  326. else
  327. {
  328. hDeltaDuty = (uint16_t)(hTimePhase.hTimePhA - hTimePhase.hTimePhC);
  329. // Definition of crossing point
  330. if (hDeltaDuty > TW_DT_TR_TS)
  331. {
  332. hTimePhase.hTimePhD = hTimePhase.hTimePhA - TW_BEFORE; // Ts before Phase A
  333. }
  334. else if((uint16_t)(PWM_PERIOD-hTimePhase.hTimePhA) > TW_DT_TN_TS_HALF)
  335. {
  336. hTimePhase.hTimePhD = hTimePhase.hTimePhA + TW_AFTER; // DT + Tn after Phase A
  337. if (hTimePhase.hTimePhD >= PWM_PERIOD)
  338. {
  339. // Trigger of ADC at Falling Edge PWM4
  340. // OCR update
  341. //Set Polarity of CC4 Low
  342. PWM4Direction=1;
  343. hTimePhase.hTimePhD = (2 * PWM_PERIOD) - hTimePhase.hTimePhD-1;
  344. }
  345. }
  346. // else
  347. // {
  348. // while(1);
  349. // }
  350. }
  351. break;
  352. default:
  353. break;
  354. }
  355. if (PWM4Direction == 0)
  356. {
  357. //Set Polarity of CC4 High
  358. Set_Pwm_Chanle4_Polarity(TIM_OCPOLARITY_HIGH);
  359. // Set_Pwm_Chanle4_Polarity(TIM_OCPOLARITY_LOW);
  360. }
  361. else
  362. {
  363. //Set Polarity of CC4 Low
  364. Set_Pwm_Chanle4_Polarity(TIM_OCPOLARITY_LOW);
  365. // Set_Pwm_Chanle4_Polarity(TIM_OCPOLARITY_HIGH);
  366. }
  367. // Set_Pwm_Chanle4_Polarity(TIM_OCPOLARITY_LOW);
  368. hTimePhase.hTimePhD=PWM_PERIOD-20;
  369. //Load compare registers values
  370. Set_Pwm_Chanle1_Compare(hTimePhase.hTimePhA);
  371. Set_Pwm_Chanle2_Compare(hTimePhase.hTimePhB);
  372. Set_Pwm_Chanle3_Compare(hTimePhase.hTimePhC);
  373. Set_Pwm_Chanle4_Compare(hTimePhase.hTimePhD);
  374. }
  375. //读取三相电流
  376. Curr_Components SVPWM_3ShuntGetPhaseCurrentValues(void)
  377. {
  378. Curr_Components Local_Stator_Currents = {0, 0};
  379. int16_t wAux;
  380. switch (bSector)
  381. {
  382. case 4:
  383. case 5: //Current on Phase C not accessible
  384. wAux =-(ADC_3ShuntCurrent.uw_phase_a);
  385. //Saturation of Ia
  386. if (wAux < -32768)
  387. {
  388. Local_Stator_Currents.qI_Component1= -32768;
  389. }
  390. else if (wAux > 32767)
  391. {
  392. Local_Stator_Currents.qI_Component1= 32767;
  393. }
  394. else
  395. {
  396. Local_Stator_Currents.qI_Component1= wAux;
  397. }
  398. wAux =-(ADC_3ShuntCurrent.uw_phase_b);
  399. // Saturation of Ib
  400. if (wAux < -32768)
  401. {
  402. Local_Stator_Currents.qI_Component2= -32768;
  403. }
  404. else if (wAux > 32767)
  405. {
  406. Local_Stator_Currents.qI_Component2= 32767;
  407. }
  408. else
  409. {
  410. Local_Stator_Currents.qI_Component2= wAux;
  411. }
  412. break;
  413. case 6:
  414. case 1:
  415. wAux =-(ADC_3ShuntCurrent.uw_phase_b);
  416. //Saturation of Ib
  417. if (wAux < -32768)
  418. {
  419. Local_Stator_Currents.qI_Component2= -32768;
  420. }
  421. else if (wAux > 32767)
  422. {
  423. Local_Stator_Currents.qI_Component2= 32767;
  424. }
  425. else
  426. {
  427. Local_Stator_Currents.qI_Component2= wAux;
  428. }
  429. //Ia = -Ib - Ic;
  430. wAux = ADC_3ShuntCurrent.uw_phase_c - Local_Stator_Currents.qI_Component2;
  431. if (wAux> 32767)
  432. {
  433. Local_Stator_Currents.qI_Component1 = 32767;
  434. }
  435. else if (wAux <-32768)
  436. {
  437. Local_Stator_Currents.qI_Component1 = -32768;
  438. }
  439. else
  440. {
  441. Local_Stator_Currents.qI_Component1 = wAux;
  442. }
  443. break;
  444. case 2:
  445. case 3:
  446. // Current on Phase B not accessible
  447. wAux =-(ADC_3ShuntCurrent.uw_phase_a);
  448. // Saturation of Ia
  449. if (wAux> 32767)
  450. {
  451. Local_Stator_Currents.qI_Component1=32767;
  452. }
  453. else if (wAux <-32768)
  454. {
  455. Local_Stator_Currents.qI_Component1 = -32768;
  456. }
  457. else
  458. {
  459. Local_Stator_Currents.qI_Component1 = wAux;
  460. }
  461. wAux = ADC_3ShuntCurrent.uw_phase_c - Local_Stator_Currents.qI_Component1; //Ib = -Ia - Ic;
  462. //Saturation of Ib
  463. if (wAux < -32768)
  464. {
  465. Local_Stator_Currents.qI_Component2= -32768;
  466. }
  467. else if (wAux > 32767)
  468. {
  469. Local_Stator_Currents.qI_Component2= 32767;
  470. }
  471. else
  472. {
  473. Local_Stator_Currents.qI_Component2= wAux;
  474. }
  475. break;
  476. default:
  477. break;
  478. }
  479. Local_Stator_Currents.qI_Component1 = Local_Stator_Currents.qI_Component1 >> 4;
  480. Local_Stator_Currents.qI_Component2 = Local_Stator_Currents.qI_Component2 >> 4;
  481. return(Local_Stator_Currents);
  482. }
  483. //读母线电流
  484. int16_t GetCurrentValues(void)
  485. {
  486. int16_t Result;
  487. Result = ADC1_Result[ADC1_RANK_CURRENT] - (int16_t)uw_current_offset;
  488. return Result;
  489. }