pwm.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  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. #if 0
  127. /* wait for a new PWM period */
  128. LL_TIM_ClearFlag_UPDATE( TIMx );
  129. LL_TIM_EnableUpdateEvent(TIMx);
  130. #if 0
  131. while ( LL_TIM_IsActiveFlag_UPDATE( TIMx ) == 0u )
  132. {}
  133. /* Clear Update Flag */
  134. LL_TIM_ClearFlag_UPDATE( TIMx );
  135. #endif
  136. #endif
  137. }
  138. void PWM_Disable_Channels(void) {
  139. TIM_TypeDef * TIMx = htim1.Instance;
  140. LL_TIM_CC_DisableChannel(TIMx, TIMxCCER_MASK_CH123);
  141. }
  142. void PWM_Enable_Channels(void) {
  143. TIM_TypeDef * TIMx = htim1.Instance;
  144. LL_TIM_CC_EnableChannel(TIMx, TIMxCCER_MASK_CH123);
  145. }
  146. void PWM_Start(void) {
  147. TIM_TypeDef * TIMx = htim1.Instance;
  148. /* Set all duty to 50% */
  149. LL_TIM_OC_SetCompareCH1(TIMx, ((uint32_t) FOC_PWM_Half_Period / (uint32_t) 2));
  150. LL_TIM_OC_SetCompareCH2(TIMx, ((uint32_t) FOC_PWM_Half_Period / (uint32_t) 2));
  151. LL_TIM_OC_SetCompareCH3(TIMx, ((uint32_t) FOC_PWM_Half_Period / (uint32_t) 2));
  152. LL_TIM_OC_SetCompareCH4(TIMx, ((uint32_t) FOC_PWM_Half_Period - (uint32_t) 5));
  153. /* wait for a new PWM period */
  154. LL_TIM_ClearFlag_UPDATE( TIMx );
  155. while ( LL_TIM_IsActiveFlag_UPDATE( TIMx ) == 0u )
  156. {}
  157. /* Clear Update Flag */
  158. LL_TIM_ClearFlag_UPDATE( TIMx );
  159. /* Main PWM Output Enable */
  160. TIMx->BDTR |= LL_TIM_OSSI_ENABLE;
  161. LL_TIM_EnableAllOutputs ( TIMx );
  162. if ( ( TIMx->CCER & TIMxCCER_MASK_CH123 ) != 0u )
  163. {
  164. LL_GPIO_SetOutputPin( PWM_EN_U_GPIO_Port, PWM_EN_U_Pin );
  165. LL_GPIO_SetOutputPin( PWM_EN_V_GPIO_Port, PWM_EN_V_Pin );
  166. LL_GPIO_SetOutputPin( PWM_EN_W_GPIO_Port, PWM_EN_W_Pin );
  167. }
  168. else
  169. {
  170. /* It is executed during calibration phase the EN signal shall stay off */
  171. LL_GPIO_ResetOutputPin( PWM_EN_U_GPIO_Port, PWM_EN_U_Pin );
  172. LL_GPIO_ResetOutputPin( PWM_EN_V_GPIO_Port, PWM_EN_V_Pin );
  173. LL_GPIO_ResetOutputPin( PWM_EN_W_GPIO_Port, PWM_EN_W_Pin );
  174. }
  175. /* Clear Update Flag */
  176. LL_TIM_ClearFlag_UPDATE( TIMx );
  177. /* Enable Update IRQ */
  178. LL_TIM_EnableIT_UPDATE( TIMx );
  179. }
  180. void PWM_Stop(void) {
  181. TIM_TypeDef * TIMx = htim1.Instance;
  182. /* Disable UPDATE ISR */
  183. LL_TIM_DisableIT_UPDATE( TIMx );
  184. /* Main PWM Output Disable */
  185. LL_TIM_DisableAllOutputs( TIMx );
  186. LL_GPIO_ResetOutputPin( PWM_EN_U_GPIO_Port, PWM_EN_U_Pin );
  187. LL_GPIO_ResetOutputPin( PWM_EN_V_GPIO_Port, PWM_EN_V_Pin );
  188. LL_GPIO_ResetOutputPin( PWM_EN_W_GPIO_Port, PWM_EN_W_Pin );
  189. /* wait for a new PWM period to flush last HF task */
  190. LL_TIM_ClearFlag_UPDATE( TIMx );
  191. while ( LL_TIM_IsActiveFlag_UPDATE( TIMx ) == 0u )
  192. {}
  193. /* Clear Update Flag */
  194. LL_TIM_ClearFlag_UPDATE( TIMx );
  195. }
  196. void PWM_TurnOnLowSides(void)
  197. {
  198. TIM_TypeDef * TIMx = htim1.Instance;
  199. /* Clear Update Flag */
  200. LL_TIM_ClearFlag_UPDATE( TIMx );
  201. /*Turn on the three low side switches */
  202. LL_TIM_OC_SetCompareCH1( TIMx, 0u );
  203. LL_TIM_OC_SetCompareCH2( TIMx, 0u );
  204. LL_TIM_OC_SetCompareCH3( TIMx, 0u );
  205. /* Wait until next update */
  206. while ( LL_TIM_IsActiveFlag_UPDATE( TIMx ) == 0u )
  207. {}
  208. /* Main PWM Output Enable */
  209. LL_TIM_EnableAllOutputs( TIMx );
  210. LL_GPIO_SetOutputPin( PWM_EN_U_GPIO_Port, PWM_EN_U_Pin );
  211. LL_GPIO_SetOutputPin( PWM_EN_V_GPIO_Port, PWM_EN_V_Pin );
  212. LL_GPIO_SetOutputPin( PWM_EN_W_GPIO_Port, PWM_EN_W_Pin );
  213. return;
  214. }
  215. static void HAL_TIM1_Pin_Init(void)
  216. {
  217. GPIO_InitTypeDef GPIO_InitStruct = {0};
  218. GPIO_InitStruct.Pin = PWM_UH_Pin;
  219. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  220. GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  221. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  222. GPIO_InitStruct.Alternate = GPIO_AF6_TIM1;
  223. HAL_GPIO_Init(PWM_UH_GPIO_Port, &GPIO_InitStruct);
  224. GPIO_InitStruct.Pin = PWM_VH_Pin;
  225. HAL_GPIO_Init(PWM_VH_GPIO_Port, &GPIO_InitStruct);
  226. GPIO_InitStruct.Pin = PWM_WH_Pin;
  227. HAL_GPIO_Init(PWM_WH_GPIO_Port, &GPIO_InitStruct);
  228. }