pwm.c 7.2 KB

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