| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- #include "hal/hal.h"
- #include "hal/pwm.h"
- #include "stm32f3xx_ll_tim.h"
- #include "stm32f3xx_ll_gpio.h"
- #include "stm32f3xx_ll_system.h"
- #define TIMxCCER_MASK_CH123 ((uint16_t) (LL_TIM_CHANNEL_CH1|LL_TIM_CHANNEL_CH1N|\
- LL_TIM_CHANNEL_CH2|LL_TIM_CHANNEL_CH2N|\
- LL_TIM_CHANNEL_CH3|LL_TIM_CHANNEL_CH3N))
- static TIM_HandleTypeDef htim1;
- static void HAL_TIM1_Pin_Init(void);
- void HAL_PWM_Init(int fs) {
- TIM_SlaveConfigTypeDef sSlaveConfig = {0};
- TIM_MasterConfigTypeDef sMasterConfig = {0};
- TIM_OC_InitTypeDef sConfigOC = {0};
- TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
-
- htim1.Instance = TIM1;
- htim1.Init.Prescaler = 0;
- htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;
- htim1.Init.Period = (TIM_CLOCK / fs /2);
- htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
- htim1.Init.RepetitionCounter = 0;
- htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
- if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
- {
- Error_Handler();
- }
- if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
- {
- Error_Handler();
- }
- sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;
- sSlaveConfig.InputTrigger = TIM_TS_ITR1;
- if (HAL_TIM_SlaveConfigSynchronization(&htim1, &sSlaveConfig) != HAL_OK)
- {
- Error_Handler();
- }
- sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC4REF;
- sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
- sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
- if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
- {
- Error_Handler();
- }
- sConfigOC.OCMode = TIM_OCMODE_PWM1;
- sConfigOC.Pulse = (TIM_CLOCK / fs) / 4; //运行后,根据svpwm重新设置
- sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
- sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
- sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
- sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
- sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
- if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
- {
- Error_Handler();
- }
- if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
- {
- Error_Handler();
- }
- if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
- {
- Error_Handler();
- }
- /* 触发ADC采样的配置 */
- sConfigOC.OCMode = TIM_OCMODE_PWM2;
- sConfigOC.Pulse = (TIM_CLOCK / fs) / 2 - 5; //运行后,根据pwm,sector信息,重新设置采样点
- if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
- {
- Error_Handler();
- }
- /* 刹车配置 */
- sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_ENABLE;
- sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;
- sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_1;
- sBreakDeadTimeConfig.DeadTime = 0;
- sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
- sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
- sBreakDeadTimeConfig.BreakFilter = 0;
- sBreakDeadTimeConfig.Break2State = TIM_BREAK2_ENABLE;
- sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_LOW;
- sBreakDeadTimeConfig.Break2Filter = 0xF;
- sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
- if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
- {
- Error_Handler();
- }
- /* TIM1 Counter Clock stopped when the core is halted */
- LL_DBGMCU_APB2_GRP1_FreezePeriph( LL_DBGMCU_APB2_GRP1_TIM1_STOP );
- HAL_TIM1_Pin_Init();
- }
- void PWM_TimerEnable(void){
- TIM_TypeDef * TIMx = htim1.Instance;
- uint32_t Brk2Timeout = 1000;
-
- LL_TIM_SetTriggerOutput(TIMx, LL_TIM_TRGO_RESET);
-
- /* Enables the TIMx Preload on CC1 Register */
- LL_TIM_OC_EnablePreload( TIMx, LL_TIM_CHANNEL_CH1 );
- /* Enables the TIMx Preload on CC2 Register */
- LL_TIM_OC_EnablePreload( TIMx, LL_TIM_CHANNEL_CH2 );
- /* Enables the TIMx Preload on CC3 Register */
- LL_TIM_OC_EnablePreload( TIMx, LL_TIM_CHANNEL_CH3 );
- /* Enables the TIMx Preload on CC4 Register */
- LL_TIM_OC_EnablePreload( TIMx, LL_TIM_CHANNEL_CH4 );
- /* Prepare timer for synchronization */
- LL_TIM_GenerateEvent_UPDATE( TIMx );
- LL_TIM_SetCounter( TIMx, 0);
- LL_TIM_ClearFlag_BRK( TIMx );
- while ((LL_TIM_IsActiveFlag_BRK2 (TIMx) == 1u) && (Brk2Timeout != 0u) )
- {
- LL_TIM_ClearFlag_BRK2( TIMx );
- Brk2Timeout--;
- }
- LL_TIM_EnableIT_BRK( TIMx );
- /* Enable PWM channel */
- LL_TIM_CC_EnableChannel( TIMx, TIMxCCER_MASK_CH123 );
- /* TIM1_BRK_IRQn interrupt configuration */
- HAL_NVIC_EnableIRQ(TIM1_BRK_TIM15_IRQn);
- HAL_NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn);
- LL_TIM_EnableCounter(TIMx);
- }
- void PWM_UpdateDuty(u32 duty1, u32 duty2, u32 duty3, u32 sample_point ) {
- TIM_TypeDef * TIMx = htim1.Instance;
- //LL_TIM_DisableUpdateEvent(TIMx);
- LL_TIM_OC_SetCompareCH1(TIMx, duty1);
- LL_TIM_OC_SetCompareCH2(TIMx, duty2);
- LL_TIM_OC_SetCompareCH3(TIMx, duty3);
- LL_TIM_OC_SetCompareCH4(TIMx, sample_point);
- #if 0
- /* wait for a new PWM period */
- LL_TIM_ClearFlag_UPDATE( TIMx );
- LL_TIM_EnableUpdateEvent(TIMx);
- #if 0
- while ( LL_TIM_IsActiveFlag_UPDATE( TIMx ) == 0u )
- {}
- /* Clear Update Flag */
- LL_TIM_ClearFlag_UPDATE( TIMx );
- #endif
- #endif
- }
- void PWM_Disable_Channels(void) {
- TIM_TypeDef * TIMx = htim1.Instance;
- LL_TIM_CC_DisableChannel(TIMx, TIMxCCER_MASK_CH123);
- }
- void PWM_Enable_Channels(void) {
- TIM_TypeDef * TIMx = htim1.Instance;
- LL_TIM_CC_EnableChannel(TIMx, TIMxCCER_MASK_CH123);
- }
- void PWM_Start(void) {
- TIM_TypeDef * TIMx = htim1.Instance;
- /* Set all duty to 50% */
- LL_TIM_OC_SetCompareCH1(TIMx, ((uint32_t) FOC_PWM_Half_Period / (uint32_t) 2));
- LL_TIM_OC_SetCompareCH2(TIMx, ((uint32_t) FOC_PWM_Half_Period / (uint32_t) 2));
- LL_TIM_OC_SetCompareCH3(TIMx, ((uint32_t) FOC_PWM_Half_Period / (uint32_t) 2));
- LL_TIM_OC_SetCompareCH4(TIMx, ((uint32_t) FOC_PWM_Half_Period - (uint32_t) 5));
- /* wait for a new PWM period */
- LL_TIM_ClearFlag_UPDATE( TIMx );
- while ( LL_TIM_IsActiveFlag_UPDATE( TIMx ) == 0u )
- {}
- /* Clear Update Flag */
- LL_TIM_ClearFlag_UPDATE( TIMx );
- /* Main PWM Output Enable */
- TIMx->BDTR |= LL_TIM_OSSI_ENABLE;
- LL_TIM_EnableAllOutputs ( TIMx );
- if ( ( TIMx->CCER & TIMxCCER_MASK_CH123 ) != 0u )
- {
- LL_GPIO_SetOutputPin( PWM_EN_U_GPIO_Port, PWM_EN_U_Pin );
- LL_GPIO_SetOutputPin( PWM_EN_V_GPIO_Port, PWM_EN_V_Pin );
- LL_GPIO_SetOutputPin( PWM_EN_W_GPIO_Port, PWM_EN_W_Pin );
- }
- else
- {
- /* It is executed during calibration phase the EN signal shall stay off */
- LL_GPIO_ResetOutputPin( PWM_EN_U_GPIO_Port, PWM_EN_U_Pin );
- LL_GPIO_ResetOutputPin( PWM_EN_V_GPIO_Port, PWM_EN_V_Pin );
- LL_GPIO_ResetOutputPin( PWM_EN_W_GPIO_Port, PWM_EN_W_Pin );
- }
- /* Clear Update Flag */
- LL_TIM_ClearFlag_UPDATE( TIMx );
- /* Enable Update IRQ */
- LL_TIM_EnableIT_UPDATE( TIMx );
- }
- void PWM_Stop(void) {
- TIM_TypeDef * TIMx = htim1.Instance;
-
- /* Disable UPDATE ISR */
- LL_TIM_DisableIT_UPDATE( TIMx );
-
- /* Main PWM Output Disable */
- LL_TIM_DisableAllOutputs( TIMx );
- LL_GPIO_ResetOutputPin( PWM_EN_U_GPIO_Port, PWM_EN_U_Pin );
- LL_GPIO_ResetOutputPin( PWM_EN_V_GPIO_Port, PWM_EN_V_Pin );
- LL_GPIO_ResetOutputPin( PWM_EN_W_GPIO_Port, PWM_EN_W_Pin );
- /* wait for a new PWM period to flush last HF task */
- LL_TIM_ClearFlag_UPDATE( TIMx );
- while ( LL_TIM_IsActiveFlag_UPDATE( TIMx ) == 0u )
- {}
- /* Clear Update Flag */
- LL_TIM_ClearFlag_UPDATE( TIMx );
- }
- void PWM_TurnOnLowSides(void)
- {
- TIM_TypeDef * TIMx = htim1.Instance;
- /* Clear Update Flag */
- LL_TIM_ClearFlag_UPDATE( TIMx );
- /*Turn on the three low side switches */
- LL_TIM_OC_SetCompareCH1( TIMx, 0u );
- LL_TIM_OC_SetCompareCH2( TIMx, 0u );
- LL_TIM_OC_SetCompareCH3( TIMx, 0u );
- /* Wait until next update */
- while ( LL_TIM_IsActiveFlag_UPDATE( TIMx ) == 0u )
- {}
- /* Main PWM Output Enable */
- LL_TIM_EnableAllOutputs( TIMx );
- LL_GPIO_SetOutputPin( PWM_EN_U_GPIO_Port, PWM_EN_U_Pin );
- LL_GPIO_SetOutputPin( PWM_EN_V_GPIO_Port, PWM_EN_V_Pin );
- LL_GPIO_SetOutputPin( PWM_EN_W_GPIO_Port, PWM_EN_W_Pin );
- return;
- }
- static void HAL_TIM1_Pin_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
-
- GPIO_InitStruct.Pin = PWM_UH_Pin;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_PULLDOWN;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
- GPIO_InitStruct.Alternate = GPIO_AF6_TIM1;
- HAL_GPIO_Init(PWM_UH_GPIO_Port, &GPIO_InitStruct);
- GPIO_InitStruct.Pin = PWM_VH_Pin;
- HAL_GPIO_Init(PWM_VH_GPIO_Port, &GPIO_InitStruct);
- GPIO_InitStruct.Pin = PWM_WH_Pin;
- HAL_GPIO_Init(PWM_WH_GPIO_Port, &GPIO_InitStruct);
- }
|