为什么RESET之后 定时器的中断总会被无端端的触发一次?

2019-07-20 12:19发布

void EXTI4_IRQHandler(void){
        delay_ms(10);
        if(SW3) //判断中断来源,确定是switch3
        {
                BUZZER=1;  //打开蜂鸣器
                TIM3->ARR=3000;  //设置timer时长,arr=3000是300ms
                TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);  //使能timer的中断触发
                TIM_Cmd(TIM3,ENABLE);  //使能timer
        }
        EXTI_ClearITPendingBit(EXTI_Line4);  //清理标志位
}


void TIM3_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)  //判断中断类型
        {
                BUZZER=0;  //关闭蜂鸣器
                LED1=0; delay_ms(100); LED1=1; //闪一下LED
                TIM_Cmd(TIM3,DISABLE);  //关闭timer
                TIM_ITConfig(TIM3,TIM_IT_Update,DISABLE);  //关闭timer的触发
        }
        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清理标志位
}


很简单的一个小程序,功能是:按键(触发外部中断)之后,蜂鸣器响300ms(触发定时器中断)之后,关闭蜂鸣器并闪一下LED(示意定时器中断已被触发)。

功能测试基本正常,唯一的问题就是,reset之后第一次按键的时候不响,只有led闪。第二次及之后的按键,就一切正常了,先响后亮。
好像程序运行的第一次触发定时器中断时,没有按照“arr=3000”设定的300ms来跑,而是直接就触发了。

整个project打包放在附件了,LED1上拉在PF9(低电平时亮),蜂鸣器下拉在PD11(高电平时响),多谢各位大佬。




友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
17602515236
1楼-- · 2019-07-20 13:45
 精彩回答 2  元偷偷看……
NULLFF
2楼-- · 2019-07-20 18:12
17602515236 发表于 2017-8-26 22:03
先清除中断标注位再开启中断源和使能定时器

大神! 你怎么知道的…… 谢谢救命之恩!我已经debug好几天了,被你一语点醒梦中人
TimEagleZhao
3楼-- · 2019-07-20 18:23
NULLFF 发表于 2017-8-26 21:32
不知道,不过如果你确定是你想的那样,那就简单了。上电后配置定时器,先让定时器运行,随后立即清除相应的 ...

谢谢谢谢!!!!你们都能一眼看出问题哦!早就该来论坛上问问题了,这几天研究了好久timer和interrupt的工作原理和register设置都没意识到问题
TimEagleZhao
4楼-- · 2019-07-20 19:29
 精彩回答 2  元偷偷看……
TimEagleZhao
5楼-- · 2019-07-20 20:06
本帖最后由 TimEagleZhao 于 2017-8-27 01:21 编辑
NULLFF 发表于 2017-8-26 21:32
不知道,不过如果你确定是你想的那样,那就简单了。上电后配置定时器,先让定时器运行,随后立即清除相应的 ...

想顺便请教:
TIM_ITConfig(TIM3,TIM_IT_Update,DISABLE); 开关定时器的时候这个东西的enable和disable有什么所谓吗?还是只需要用TIM_Cmd函数使能/禁用那个timer就好了?
我发现如果直接在初始化的时候用TIM_ITConfig使能中断更新,而在后面只enable disable那个TIM_Cmd函数的话,reset之后也会莫名其妙地不用按键就会先触发一次定时器中断,然后就一切正常


像这样:
void EXTI4_IRQHandler(void){
        delay_ms(10);
        if(SW3) //判断中断来源,确定是switch3
        {
                BUZZER=1;  //打开蜂鸣器
                TIM3->ARR=3000;  //设置timer时长,arr=3000是300ms
                //TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);  //使能timer的中断触发
                TIM_Cmd(TIM3,ENABLE);  //使能timer
        }
        EXTI_ClearITPendingBit(EXTI_Line4);  //清理标志位
}


void TIM3_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)  //判断中断类型
        {
                BUZZER=0;  //关闭蜂鸣器
                LED1=0; delay_ms(100); LED1=1; //闪一下LED
                TIM_Cmd(TIM3,DISABLE);  //关闭timer
                //TIM_ITConfig(TIM3,TIM_IT_Update,DISABLE);  //关闭timer的触发
        }
        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清理标志位
}


然后初始化的时候enable它

TimEagleZhao
6楼-- · 2019-07-20 21:04
本帖最后由 TimEagleZhao 于 2017-8-27 01:22 编辑

.................

一周热门 更多>