rt-thread icon indicating copy to clipboard operation
rt-thread copied to clipboard

STM32F103BSP_使用Cubemex使能PWM时,勾选internal clock无法正常输出PWM波形,取消勾选后可以

Open bixia opened this issue 4 years ago • 1 comments

版本信息:

  • Cubemex: Version 6.0.1
  • RT-Thread master
  • BSP: stm32f103-atk-nano

重现: image 对应生成的代码: `/**

  • @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时,如下图: image 对应生成的代码: `` /**

  • @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; }``

bixia avatar Nov 22 '20 11:11 bixia

https://github.com/RT-Thread/rt-thread/pull/3578 , 可以看一下这个 PR, 欢迎提出解决方案。

liukangcc avatar Nov 23 '20 01:11 liukangcc