OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3238|回复: 9

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

[复制链接]

1

主题

8

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2017-7-17
在线时间
4 小时
发表于 2017-8-26 19:20:41 | 显示全部楼层 |阅读模式
1金钱
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(高电平时响),多谢各位大佬。




template.zip

10.82 MB, 下载次数: 142

最佳答案

查看完整内容[请看2#楼]

先清除中断标注位再开启中断源和使能定时器
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

72

帖子

0

精华

初级会员

Rank: 2

积分
198
金钱
198
注册时间
2017-7-25
在线时间
39 小时
发表于 2017-8-26 19:20:42 | 显示全部楼层
先清除中断标注位再开启中断源和使能定时器
回复

使用道具 举报

头像被屏蔽

12

主题

167

帖子

0

精华

禁止访问

积分
517
金钱
517
注册时间
2017-5-30
在线时间
110 小时
发表于 2017-8-26 21:32:55 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2017-7-17
在线时间
4 小时
 楼主| 发表于 2017-8-27 00:47:24 | 显示全部楼层
17602515236 发表于 2017-8-26 22:03
先清除中断标注位再开启中断源和使能定时器

大神! 你怎么知道的…… 谢谢救命之恩!我已经debug好几天了,被你一语点醒梦中人
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2017-7-17
在线时间
4 小时
 楼主| 发表于 2017-8-27 00:49:04 | 显示全部楼层
NULLFF 发表于 2017-8-26 21:32
不知道,不过如果你确定是你想的那样,那就简单了。上电后配置定时器,先让定时器运行,随后立即清除相应的 ...

谢谢谢谢!!!!你们都能一眼看出问题哦!早就该来论坛上问问题了,这几天研究了好久timer和interrupt的工作原理和register设置都没意识到问题
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2017-7-17
在线时间
4 小时
 楼主| 发表于 2017-8-27 01:05:16 | 显示全部楼层
本帖最后由 TimEagleZhao 于 2017-8-27 01:22 编辑
17602515236 发表于 2017-8-26 19:20
先清除中断标注位再开启中断源和使能定时器

想顺便请教:
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它
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2017-7-17
在线时间
4 小时
 楼主| 发表于 2017-8-27 01:05:31 | 显示全部楼层
本帖最后由 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它

回复

使用道具 举报

1

主题

8

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2017-7-17
在线时间
4 小时
 楼主| 发表于 2017-8-27 01:09:46 | 显示全部楼层
本帖最后由 TimEagleZhao 于 2017-8-27 01:22 编辑

.................
回复

使用道具 举报

头像被屏蔽

12

主题

167

帖子

0

精华

禁止访问

积分
517
金钱
517
注册时间
2017-5-30
在线时间
110 小时
发表于 2017-8-27 09:07:14 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2017-7-17
在线时间
4 小时
 楼主| 发表于 2017-8-27 12:47:47 | 显示全部楼层
NULLFF 发表于 2017-8-27 09:07
大哥,是你的思维能力不行吧?你应该有xx-Link吧?没有自己面壁去。
程序运行一步步查看,然后如果你看 ...

说得对 我这不才刚第三天嘛 还不太会用那个jlink的断点debug 现在去学一下 好像真的蛮重要的!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-18 06:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表