pwm.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. #include "hal/hal.h"
  2. #include "hal/pwm.h"
  3. #include "stm32f3xx_ll_tim.h"
  4. #include "stm32f3xx_ll_gpio.h"
  5. #include "stm32f3xx_ll_system.h"
  6. #define TIMxCCER_MASK_CH123 ((uint16_t) (LL_TIM_CHANNEL_CH1|LL_TIM_CHANNEL_CH1N|\
  7. LL_TIM_CHANNEL_CH2|LL_TIM_CHANNEL_CH2N|\
  8. LL_TIM_CHANNEL_CH3|LL_TIM_CHANNEL_CH3N))
  9. static TIM_HandleTypeDef htim1;
  10. static void HAL_TIM1_Pin_Init(void);
  11. void HAL_PWM_Init(int fs) {
  12. TIM_SlaveConfigTypeDef sSlaveConfig = {0};
  13. TIM_MasterConfigTypeDef sMasterConfig = {0};
  14. TIM_OC_InitTypeDef sConfigOC = {0};
  15. TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
  16. htim1.Instance = TIM1;
  17. htim1.Init.Prescaler = 0;
  18. htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;
  19. htim1.Init.Period = (TIM_CLOCK / fs /2);
  20. htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  21. htim1.Init.RepetitionCounter = 0;
  22. htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  23. if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  24. {
  25. Error_Handler();
  26. }
  27. if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
  28. {
  29. Error_Handler();
  30. }
  31. sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;
  32. sSlaveConfig.InputTrigger = TIM_TS_ITR1;
  33. if (HAL_TIM_SlaveConfigSynchronization(&htim1, &sSlaveConfig) != HAL_OK)
  34. {
  35. Error_Handler();
  36. }
  37. sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC4REF;
  38. sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
  39. sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  40. if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  41. {
  42. Error_Handler();
  43. }
  44. sConfigOC.OCMode = TIM_OCMODE_PWM1;
  45. sConfigOC.Pulse = (TIM_CLOCK / fs) / 4; //运行后,根据svpwm重新设置
  46. sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  47. sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  48. sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  49. sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  50. sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  51. if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  52. {
  53. Error_Handler();
  54. }
  55. if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  56. {
  57. Error_Handler();
  58. }
  59. if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  60. {
  61. Error_Handler();
  62. }
  63. /* 触发ADC采样的配置 */
  64. sConfigOC.OCMode = TIM_OCMODE_PWM2;
  65. sConfigOC.Pulse = (TIM_CLOCK / fs) / 2 - 5; //运行后,根据pwm,sector信息,重新设置采样点
  66. if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
  67. {
  68. Error_Handler();
  69. }
  70. /* 刹车配置 */
  71. sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_ENABLE;
  72. sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;
  73. sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_1;
  74. sBreakDeadTimeConfig.DeadTime = 0;
  75. sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  76. sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  77. sBreakDeadTimeConfig.BreakFilter = 0;
  78. sBreakDeadTimeConfig.Break2State = TIM_BREAK2_ENABLE;
  79. sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_LOW;
  80. sBreakDeadTimeConfig.Break2Filter = 0xF;
  81. sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  82. if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  83. {
  84. Error_Handler();
  85. }
  86. /* TIM1 Counter Clock stopped when the core is halted */
  87. LL_DBGMCU_APB2_GRP1_FreezePeriph( LL_DBGMCU_APB2_GRP1_TIM1_STOP );
  88. HAL_TIM1_Pin_Init();
  89. }
  90. void PWM_TimerEnable(void){
  91. TIM_TypeDef * TIMx = htim1.Instance;
  92. uint32_t Brk2Timeout = 1000;
  93. LL_TIM_SetTriggerOutput(TIMx, LL_TIM_TRGO_RESET);
  94. /* Enables the TIMx Preload on CC1 Register */
  95. LL_TIM_OC_EnablePreload( TIMx, LL_TIM_CHANNEL_CH1 );
  96. /* Enables the TIMx Preload on CC2 Register */
  97. LL_TIM_OC_EnablePreload( TIMx, LL_TIM_CHANNEL_CH2 );
  98. /* Enables the TIMx Preload on CC3 Register */
  99. LL_TIM_OC_EnablePreload( TIMx, LL_TIM_CHANNEL_CH3 );
  100. /* Enables the TIMx Preload on CC4 Register */
  101. LL_TIM_OC_EnablePreload( TIMx, LL_TIM_CHANNEL_CH4 );
  102. /* Prepare timer for synchronization */
  103. LL_TIM_GenerateEvent_UPDATE( TIMx );
  104. LL_TIM_SetCounter( TIMx, 0);
  105. LL_TIM_ClearFlag_BRK( TIMx );
  106. while ((LL_TIM_IsActiveFlag_BRK2 (TIMx) == 1u) && (Brk2Timeout != 0u) )
  107. {
  108. LL_TIM_ClearFlag_BRK2( TIMx );
  109. Brk2Timeout--;
  110. }
  111. LL_TIM_EnableIT_BRK( TIMx );
  112. /* Enable PWM channel */
  113. LL_TIM_CC_EnableChannel( TIMx, TIMxCCER_MASK_CH123 );
  114. /* TIM1_BRK_IRQn interrupt configuration */
  115. HAL_NVIC_EnableIRQ(TIM1_BRK_TIM15_IRQn);
  116. HAL_NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn);
  117. LL_TIM_EnableCounter(TIMx);
  118. }
  119. void PWM_UpdateDuty(u32 duty1, u32 duty2, u32 duty3, u32 sample_point ) {
  120. TIM_TypeDef * TIMx = htim1.Instance;
  121. LL_TIM_DisableUpdateEvent(TIMx);
  122. LL_TIM_OC_SetCompareCH1(TIMx, duty1);
  123. LL_TIM_OC_SetCompareCH2(TIMx, duty2);
  124. LL_TIM_OC_SetCompareCH3(TIMx, duty3);
  125. LL_TIM_OC_SetCompareCH4(TIMx, sample_point);
  126. /* wait for a new PWM period */
  127. LL_TIM_ClearFlag_UPDATE( TIMx );
  128. LL_TIM_EnableUpdateEvent(TIMx);
  129. #if 0
  130. while ( LL_TIM_IsActiveFlag_UPDATE( TIMx ) == 0u )
  131. {}
  132. /* Clear Update Flag */
  133. LL_TIM_ClearFlag_UPDATE( TIMx );
  134. #endif
  135. }
  136. void PWM_Start(void) {
  137. TIM_TypeDef * TIMx = htim1.Instance;
  138. /* Set all duty to 50% */
  139. LL_TIM_OC_SetCompareCH1(TIMx, ((uint32_t) FOC_PWM_Half_Period / (uint32_t) 2));
  140. LL_TIM_OC_SetCompareCH2(TIMx, ((uint32_t) FOC_PWM_Half_Period / (uint32_t) 2));
  141. LL_TIM_OC_SetCompareCH3(TIMx, ((uint32_t) FOC_PWM_Half_Period / (uint32_t) 2));
  142. LL_TIM_OC_SetCompareCH4(TIMx, ((uint32_t) FOC_PWM_Half_Period - (uint32_t) 5));
  143. /* wait for a new PWM period */
  144. LL_TIM_ClearFlag_UPDATE( TIMx );
  145. while ( LL_TIM_IsActiveFlag_UPDATE( TIMx ) == 0u )
  146. {}
  147. /* Clear Update Flag */
  148. LL_TIM_ClearFlag_UPDATE( TIMx );
  149. /* Main PWM Output Enable */
  150. TIMx->BDTR |= LL_TIM_OSSI_ENABLE;
  151. LL_TIM_EnableAllOutputs ( TIMx );
  152. if ( ( TIMx->CCER & TIMxCCER_MASK_CH123 ) != 0u )
  153. {
  154. LL_GPIO_SetOutputPin( PWM_EN_U_GPIO_Port, PWM_EN_U_Pin );
  155. LL_GPIO_SetOutputPin( PWM_EN_V_GPIO_Port, PWM_EN_V_Pin );
  156. LL_GPIO_SetOutputPin( PWM_EN_W_GPIO_Port, PWM_EN_W_Pin );
  157. }
  158. else
  159. {
  160. /* It is executed during calibration phase the EN signal shall stay off */
  161. LL_GPIO_ResetOutputPin( PWM_EN_U_GPIO_Port, PWM_EN_U_Pin );
  162. LL_GPIO_ResetOutputPin( PWM_EN_V_GPIO_Port, PWM_EN_V_Pin );
  163. LL_GPIO_ResetOutputPin( PWM_EN_W_GPIO_Port, PWM_EN_W_Pin );
  164. }
  165. /* Clear Update Flag */
  166. LL_TIM_ClearFlag_UPDATE( TIMx );
  167. /* Enable Update IRQ */
  168. LL_TIM_EnableIT_UPDATE( TIMx );
  169. }
  170. void PWM_Stop(void) {
  171. TIM_TypeDef * TIMx = htim1.Instance;
  172. /* Disable UPDATE ISR */
  173. LL_TIM_DisableIT_UPDATE( TIMx );
  174. /* Main PWM Output Disable */
  175. LL_TIM_DisableAllOutputs( TIMx );
  176. LL_GPIO_ResetOutputPin( PWM_EN_U_GPIO_Port, PWM_EN_U_Pin );
  177. LL_GPIO_ResetOutputPin( PWM_EN_V_GPIO_Port, PWM_EN_V_Pin );
  178. LL_GPIO_ResetOutputPin( PWM_EN_W_GPIO_Port, PWM_EN_W_Pin );
  179. /* wait for a new PWM period to flush last HF task */
  180. LL_TIM_ClearFlag_UPDATE( TIMx );
  181. while ( LL_TIM_IsActiveFlag_UPDATE( TIMx ) == 0u )
  182. {}
  183. /* Clear Update Flag */
  184. LL_TIM_ClearFlag_UPDATE( TIMx );
  185. }
  186. void PWM_TurnOnLowSides(void)
  187. {
  188. TIM_TypeDef * TIMx = htim1.Instance;
  189. /* Clear Update Flag */
  190. LL_TIM_ClearFlag_UPDATE( TIMx );
  191. /*Turn on the three low side switches */
  192. LL_TIM_OC_SetCompareCH1( TIMx, 0u );
  193. LL_TIM_OC_SetCompareCH2( TIMx, 0u );
  194. LL_TIM_OC_SetCompareCH3( TIMx, 0u );
  195. /* Wait until next update */
  196. while ( LL_TIM_IsActiveFlag_UPDATE( TIMx ) == 0u )
  197. {}
  198. /* Main PWM Output Enable */
  199. LL_TIM_EnableAllOutputs( TIMx );
  200. LL_GPIO_SetOutputPin( PWM_EN_U_GPIO_Port, PWM_EN_U_Pin );
  201. LL_GPIO_SetOutputPin( PWM_EN_V_GPIO_Port, PWM_EN_V_Pin );
  202. LL_GPIO_SetOutputPin( PWM_EN_W_GPIO_Port, PWM_EN_W_Pin );
  203. return;
  204. }
  205. static void HAL_TIM1_Pin_Init(void)
  206. {
  207. GPIO_InitTypeDef GPIO_InitStruct = {0};
  208. GPIO_InitStruct.Pin = PWM_UH_Pin;
  209. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  210. GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  211. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  212. GPIO_InitStruct.Alternate = GPIO_AF6_TIM1;
  213. HAL_GPIO_Init(PWM_UH_GPIO_Port, &GPIO_InitStruct);
  214. GPIO_InitStruct.Pin = PWM_VH_Pin;
  215. HAL_GPIO_Init(PWM_VH_GPIO_Port, &GPIO_InitStruct);
  216. GPIO_InitStruct.Pin = PWM_WH_Pin;
  217. HAL_GPIO_Init(PWM_WH_GPIO_Port, &GPIO_InitStruct);
  218. }