今天遇到一个问题,我在MX中配置好定时器也打开了定时器的计数溢出NVIC后,在主函数使用HAL_TIM_PWM_Start_IT(&htim1, TIM_CHANNEL_1)
程序仍然无法进入定时器溢出中断。
配置定时器1通道1为PWM模式
配置定时器1,64倍分频 ,向上计数,计数溢出值10000,向自动重装使能
打开定时器1计数溢出中断
重定义定时器中断回调函数
主函数:
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM1_Init();
HAL_TIM_PWM_Start_IT(&htim1, TIM_CHANNEL_1);
运行仿真发现程序无法运行至定时器中断回调函数中的断点,随意在while循环中打个断点发现程序能运行至主循环中的断点,说明程序并没有卡死且是在一直运行的,只是没有进入定时器中断。
由于本人在不使用pwm输出时发现定时器能正确进入中断服务函数,所以猜测HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);函数并没有使能TIM1计数溢出中断。
于是我想到对比一下HAL_TIM_PWM_Start_IT(&htim1, TIM_CHANNEL_1);和HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
函数原型
HAL_TIM_PWM_Start_IT:
HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
{
HAL_StatusTypeDef status = HAL_OK;
uint32_t tmpsmcr;
/* Check the parameters */
assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
/* Check the TIM channel state */
if (TIM_CHANNEL_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
{
return HAL_ERROR;
}
/* Set the TIM channel state */
TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
switch (Channel)
{
case TIM_CHANNEL_1:
{
/* Enable the TIM Capture/Compare 1 interrupt */
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
break;
}
case TIM_CHANNEL_2:
{
/* Enable the TIM Capture/Compare 2 interrupt */
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
break;
}
case TIM_CHANNEL_3:
{
/* Enable the TIM Capture/Compare 3 interrupt */
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
break;
}
case TIM_CHANNEL_4:
{
/* Enable the TIM Capture/Compare 4 interrupt */
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4);
break;
}
default:
status = HAL_ERROR;
break;
}
if (status == HAL_OK)
{
/* Enable the Capture compare channel */
TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
{
/* Enable the main output */
__HAL_TIM_MOE_ENABLE(htim);
}
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
{
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
{
__HAL_TIM_ENABLE(htim);
}
}
else
{
__HAL_TIM_ENABLE(htim);
}
}
/* Return function status */
return status;
}
HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim)函数原型:
HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim)
{
uint32_t tmpsmcr;
/* Check the parameters */
assert_param(IS_TIM_INSTANCE(htim->Instance));
/* Check the TIM state */
if (htim->State != HAL_TIM_STATE_READY)
{
return HAL_ERROR;
}
/* Set the TIM state */
htim->State = HAL_TIM_STATE_BUSY;
/* Enable the TIM Update interrupt */
__HAL_TIM_ENABLE_IT(htim, TIM_IT_UPDATE);
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
{
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
{
__HAL_TIM_ENABLE(htim);
}
}
else
{
__HAL_TIM_ENABLE(htim);
}
/* Return function status */
return HAL_OK;
}
果然发现HAL_TIM_PWM_Start_IT(&htim1, TIM_CHANNEL_1);函数中并没有 __HAL_TIM_ENABLE_IT(htim, TIM_IT_UPDATE);语句,由此可以断定PWM_Start_IT中并没有打开定时器中断。
在主函数中加入__HAL_TIM_ENABLE_IT(&htim1, TIM_IT_UPDATE);程序即可正确进入中断。
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM1_Init();
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
__HAL_TIM_ENABLE_IT(&htim1, TIM_IT_UPDATE);
while(1)
{
}