在项目开发中,采用高级定时器生成指定数量的PWM波,发现无法通过HAL_TIM_Base_Stop(&pwm_handle)函数来到达关闭定时器的作用。
HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim)
{
/* Check the parameters */
assert_param(IS_TIM_INSTANCE(htim->Instance));
/* Disable the Peripheral */
__HAL_TIM_DISABLE(htim);
/* Set the TIM state */
htim->State = HAL_TIM_STATE_READY;
/* Return function status */
return HAL_OK;
}
主要还是通过__HAL_TIM_DISABLE(htim);来关闭定时器。我们再点进去:
#define __HAL_TIM_DISABLE(__HANDLE__) \
do { \
if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxE_MASK) == 0UL) \
{ \
if(((__HANDLE__)->Instance->CCER & TIM_CCER_CCxNE_MASK) == 0UL) \
{ \
(__HANDLE__)->Instance->CR1 &= ~(TIM_CR1_CEN); \
} \
} \
} while(0)
#define TIM_CCER_CCxE_MASK ((uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E))
分析条件检查:
第一层条件:
if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxE_MASK) == 0UL)
这一行检查定时器的捕获/比较输出使能位(CCxE)。如果所有这些位都被清除,即等于0UL,则继续执行下一层检查。
第二层条件:
if(((__HANDLE__)->Instance->CCER & TIM_CCER_CCxNE_MASK) == 0UL)
这一行检查定时器的捕获/比较互补输出使能位(CCxNE)。如果所有这些位都被清除,即等于0UL,则继续执行禁用定时器的操作。
定时器禁用:
(__HANDLE__)->Instance->CR1 &= ~(TIM_CR1_CEN);
在满足上述两个条件后,定时器的控制寄存器CR1中的使能位TIM_CR1_CEN才会被清除,从而禁用定时器。
捕获/比较使能寄存器(TIMx_CCER)
该寄存器比较简单,要让 TIM1 的 CH1 输出 PWM 波,这里我们要使能 CC1E 位,该位是通道 1 输入/输出使能位,要想 PWM 从 IO 口输出,这个位必须设置为 1。 CC1P 位是设置通道 1 的输出极性,我们设置 0,即 OC1 高电平有效。
总结 :想停止用于生成PWM的定时器,必须要先把PWM的使能通道关闭,才可以关闭定时器。
如果不想关闭PWM使能通道的同时来关闭定时器,就采用寄存器操作来关闭定时器的使能位。
控制寄存器1(TIMx_CR1)
位 0(CEN),用于使能计数器的工作,必须要设置该位为 1,才可以开始计数。
所以我们采用:
TIM8->CR1 &= ~(1 << 0);
这样停止计时器了。