欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

STM32F407定时器溢出中断问题——进入中断次数异常

程序员文章站 2022-04-01 15:37:17
...

在STM32F407上使用定时器3产生1ms定时中断,timer3初始化代码如下:

void TIM3_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);             //使能TIM3时钟

    TIM_TimeBaseInitStructure.TIM_Period = arr;                     //自动重装载值
    TIM_TimeBaseInitStructure.TIM_Prescaler=psc;                    //定时器分频
    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;   //向上计数模式
    TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; 

    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);              //初始化TIM3

    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);                        //允许定时器3更新中断
    TIM_Cmd(TIM3,ENABLE);                                           //使能定时器3

    NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;                   //定时器3中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01;      //抢占优先级1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03;             //子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

初始化1ms定时中断:

TIM3_Int_Init(10-1,8400-1);     //定时器时钟84M,分频系数8400,所以84M/8400=10Khz的计数频率,计数10次为1ms   

timer3定时中断服务程序:

//定时器3中断服务函数
void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
    {
        Key_Counter();                          //按键扫描延时操作
    }

    LED_Out = !LED_Out
    TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
}

通过LED闪烁频率,验证中断频率设置是否正确。然而……

STM32F407定时器溢出中断问题——进入中断次数异常
系统上电后,示波器观察到的LED管脚波形,频率1KHz,占空比99%(正常应为500Hz,占空比50%)。
STM32F407定时器溢出中断问题——进入中断次数异常
LED低电平脉宽只有560ns。

STM32F407定时器溢出中断问题——进入中断次数异常
系统重新复位后,示波器观察到的LED管脚波形,频率1KHz,占空比小于1%(正常应为500Hz,占空比50%)。

STM32F407定时器溢出中断问题——进入中断次数异常
这下LED高电平脉宽只有约560ns。

不断试验,中断代码做如下更改:

//定时器3中断服务函数
void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
    {
        Key_Counter();                          //按键扫描延时操作
    }

    TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
    LED_Out = !LED_Out;
}

即先清除中断,再输出LED,波形输出如下:
STM32F407定时器溢出中断问题——进入中断次数异常
修改代码后,LED引脚正常波形。

问题虽然解决了,但是目前仍然不知道造成该问题的最终原因。
待后续发现……

网上找到两个类似的问题:
关于STM32F407的定时器中断的诡异问题
STM32F407 定时器TIM3 出现