rt-thread
rt-thread copied to clipboard
STM32F103BSP_使用Cubemex使能PWM时,勾选internal clock无法正常输出PWM波形,取消勾选后可以
版本信息:
- Cubemex: Version 6.0.1
- RT-Thread master
- BSP: stm32f103-atk-nano
重现:
对应生成的代码:
`/**
-
@brief TIM_PWM MSP Initialization
-
This function configures the hardware resources used in this example
-
@param htim_pwm: TIM_PWM handle pointer
-
@retval None / void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef htim_pwm) { if(htim_pwm->Instance==TIM3) { /* USER CODE BEGIN TIM3_MspInit 0 */
/* USER CODE END TIM3_MspInit 0 / / Peripheral clock enable / __HAL_RCC_TIM3_CLK_ENABLE(); / USER CODE BEGIN TIM3_MspInit 1 */
/* USER CODE END TIM3_MspInit 1 */ }
}
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(htim->Instance==TIM3) { /* USER CODE BEGIN TIM3_MspPostInit 0 */
/* USER CODE END TIM3_MspPostInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
/**TIM3 GPIO Configuration
PA6 ------> TIM3_CH1
PA7 ------> TIM3_CH2
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN TIM3_MspPostInit 1 */
/* USER CODE END TIM3_MspPostInit 1 */ }
}`
当不勾选internal clock时,如下图:
对应生成的代码:
``
/**
-
@brief TIM_Base MSP Initialization
-
This function configures the hardware resources used in this example
-
@param htim_base: TIM_Base handle pointer
-
@retval None / void HAL_TIM_Base_MspInit(TIM_HandleTypeDef htim_base) { if(htim_base->Instance==TIM3) { /* USER CODE BEGIN TIM3_MspInit 0 */
/* USER CODE END TIM3_MspInit 0 / / Peripheral clock enable / __HAL_RCC_TIM3_CLK_ENABLE(); / USER CODE BEGIN TIM3_MspInit 1 */
/* USER CODE END TIM3_MspInit 1 */ }
}
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(htim->Instance==TIM3) { /* USER CODE BEGIN TIM3_MspPostInit 0 */
/* USER CODE END TIM3_MspPostInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
/**TIM3 GPIO Configuration
PA6 ------> TIM3_CH1
PA7 ------> TIM3_CH2
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN TIM3_MspPostInit 1 */
/* USER CODE END TIM3_MspPostInit 1 */ }
}``
在rt-thread-master\bsp\stm32\libraries\HAL_Drivers\drv_pwm.c中的static rt_err_t stm32_hw_pwm_init(struct stm32_pwm device)方法里的第330行: 其使用了HAL_TIM_PWM_Init(tim)方法,该方法会默认调用void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef htim_pwm) 而不是void HAL_TIM_Base_MspInit(TIM_HandleTypeDef htim_base)方法,故当使能了internal clock后,PWM无输出*
`` static rt_err_t stm32_hw_pwm_init(struct stm32_pwm *device) { rt_err_t result = RT_EOK; TIM_HandleTypeDef *tim = RT_NULL; TIM_OC_InitTypeDef oc_config = {0}; TIM_MasterConfigTypeDef master_config = {0}; TIM_ClockConfigTypeDef clock_config = {0};
RT_ASSERT(device != RT_NULL);
tim = (TIM_HandleTypeDef *)&device->tim_handle;
/* configure the timer to pwm mode */
tim->Init.Prescaler = 0;
tim->Init.CounterMode = TIM_COUNTERMODE_UP;
tim->Init.Period = 0;
tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; #endif
if (HAL_TIM_PWM_Init(tim) != HAL_OK)
{
LOG_E("%s pwm init failed", device->name);
result = -RT_ERROR;
goto __exit;
}
clock_config.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(tim, &clock_config) != HAL_OK)
{
LOG_E("%s clock init failed", device->name);
result = -RT_ERROR;
goto __exit;
}
master_config.MasterOutputTrigger = TIM_TRGO_RESET;
master_config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(tim, &master_config) != HAL_OK)
{
LOG_E("%s master config failed", device->name);
result = -RT_ERROR;
goto __exit;
}
oc_config.OCMode = TIM_OCMODE_PWM1;
oc_config.Pulse = 0;
oc_config.OCPolarity = TIM_OCPOLARITY_HIGH;
oc_config.OCFastMode = TIM_OCFAST_DISABLE;
oc_config.OCNIdleState = TIM_OCNIDLESTATE_RESET;
oc_config.OCIdleState = TIM_OCIDLESTATE_RESET;
/* config pwm channel */
if (device->channel & 0x01)
{
if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_1) != HAL_OK)
{
LOG_E("%s channel1 config failed", device->name);
result = -RT_ERROR;
goto __exit;
}
}
if (device->channel & 0x02)
{
if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_2) != HAL_OK)
{
LOG_E("%s channel2 config failed", device->name);
result = -RT_ERROR;
goto __exit;
}
}
if (device->channel & 0x04)
{
if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_3) != HAL_OK)
{
LOG_E("%s channel3 config failed", device->name);
result = -RT_ERROR;
goto __exit;
}
}
if (device->channel & 0x08)
{
if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_4) != HAL_OK)
{
LOG_E("%s channel4 config failed", device->name);
result = -RT_ERROR;
goto __exit;
}
}
/* pwm pin configuration */
HAL_TIM_MspPostInit(tim);
/* enable update request source */
__HAL_TIM_URS_ENABLE(tim);
__exit: return result; }``
https://github.com/RT-Thread/rt-thread/pull/3578 , 可以看一下这个 PR, 欢迎提出解决方案。