这两天遇到一个在两同的操作系统版本上跑我写的相同PWM驱动,竟然是在RTT4.0.3上能跑过去,有PWM输出,在RTT4.0.5上就跑不过去,没PWM输出,于是下决心研究下(硬件环境
STM32F407VGT6)。
首先我从PWM初始化部分做了比较,发现了drv_pwm.c文件版本不同,在RTT4.0.3的版本是
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Iden
tifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-13 zylx first version
*/
而在RTT4.0.5版本是
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-13 zylx first version
* 2021-01-23 thread-liu Fix the timer clock frequency doubling problem
*/
然后发现RTT4.0.3中
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;
...
if (HAL_TIM_PWM_Init(tim) != HAL_OK)
{
LOG_E("%s pwm init failed", device->name);
result = -RT_ERROR;
goto __exit;
}
而RTT4.0.5中
static rt_err_t stm32_hw_pwm_init(struct stm32_pwm *device)
{
...
// if (HAL_TIM_Base_Init(tim) != HAL_OK)
// {
// LOG_E("%s pwm init failed", device->name);
// result = -RT_ERROR;
// goto __exit;
// }
if (HAL_TIM_PWM_Init(tim) != HAL_OK)
{
LOG_E("%s pwm init failed", device->name);
result = -RT_ERROR;
goto __exit;
}
请注意上面代码中注释掉的部分,在PWM初始化时初始化基本定义器的用意是什么?这个问题没想明白,但是它导致了tim被调用时产生了一个状态变化,那就是htim->State = HAL_TIM_STATE_READY使得tim状态从HAL_TIM_STATE_RESET变成HAL_TIM_STATE_READY,导致后面HAL_TIM_PWM_Init(tim)调用时,
HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim)
{
/* Check the TIM handle allocation */
if (htim == NULL)
{
return HAL_ERROR;
}
...
if (htim->State == HAL_TIM_STATE_RESET)
{
/* Allocate lock resource and initialize it */
htim->Lock = HAL_UNLOCKED;
、#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
/* Reset interrupt callbacks to legacy weak callbacks */
TIM_ResetCallback(htim);
if (htim->PWM_MspInitCallback == NULL)
{
htim->PWM_MspInitCallback = HAL_TIM_PWM_MspInit;
}
/* Init the low level hardware : GPIO, CLOCK, NVIC */
htim->PWM_MspInitCallback(htim);
、#else
/* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
** HAL_TIM_PWM_MspInit(htim);**
、#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
这个if (htim->State == HAL_TIM_STATE_RESET)条件不成立,影响到其内部HAL_TIM_PWM_MspInit(htim)不能被调用,从而导致下面函数不能被调用
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 */
}
}
使得TIM3的时钟不能打开,PWM 当然也不能输出。注释掉掉上面那部分基本定时器的初始化代码,就可以正常输出了。
原作者:apingrtt