搜索
bottom↓
回复: 36

为何外部中断触发一次响应N次?

[复制链接]

出0入0汤圆

发表于 2007-4-13 16:09:31 | 显示全部楼层 |阅读模式
请大家看看这个程序,按理说应该触发一次外部中断i只会加1,avrstudio仿真也通过了,可是实际测试i会不断自加,好像中断一触发就一发不可收拾,改变外部中断触发条件为低电平触发会出现触发一次i自加2次的情况,上升沿、下降沿、低电位和任意逻辑转变触发都试过了,没一种能达到目的的,不知是哪里出了问题?换了2片新的M16都是这样。



winavr20060421版+M16测试。



#include <avr/io.h>

#include <avr/interrupt.h>



volatile unsigned char flags=0;



SIGNAL (INT0_vect)

{

    cli();

    flags=1;      //中断标志

}



int main (void)

{

    unsigned char i=0;



    DDRA=0x00;      //IO均为带上拉的输入

    DDRB=0x00;

    DDRC=0x00;

    DDRD=0x00;

    PORTA=0xFF;

    PORTB=0xFF;

    PORTC=0xFF;

    PORTD=0xFF;



    MCUCR=(1<<ISC01);     //INT0下降沿触发

    GICR=(1<<INT0);       //使能INT0

    GIFR=(1<<INTF1)|(1<<INTF0)|(1<<INTF2);             //清标志



    sei();

       

    while(1)

    {

        if (flags)

        {

            flags=0;

            i++;

            sei();

        }

    }

}
-----此内容被gxlujd于2007-04-13,16:14:59编辑过

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2007-4-13 16:24:24 | 显示全部楼层
我以前也碰到过,那是检测货币机的,有投币的话会产生一宽度为100ms的脉冲,采用上升沿触发外部中断,但发现好像被触发多次(3次、4次、5次都有),也没弄明白为什么?改换采用查询方式!

出0入0汤圆

 楼主| 发表于 2007-4-13 16:31:15 | 显示全部楼层
to chunnynee:



我看到你以前的帖子了,咱两同病相怜哦,呵呵~~~~~

玩了这么久单片机,使用INTO还是极少的,以前用BASCOM-AVR没这个问题的。

出0入42汤圆

发表于 2007-4-13 16:37:27 | 显示全部楼层
根据触发中断的脉冲宽度在软件上做一下防抖会不会好一些?

出0入0汤圆

发表于 2007-4-13 16:51:36 | 显示全部楼层
曾用CV产生的程序,解决上述问题.离开中断前用软件清中断标志试试.

出0入0汤圆

 楼主| 发表于 2007-4-13 16:57:22 | 显示全部楼层
试过手工清中断标志,不行,还是照样多次执行中断服务程序,软件防抖倒是没试过,今晚试试看,有结果再来汇报。

出0入0汤圆

发表于 2007-4-13 17:05:34 | 显示全部楼层
如果硬件没有防抖措施,软件也应该可以改善。

出0入0汤圆

发表于 2007-4-13 17:35:51 | 显示全部楼层
我用M16也是的,用来做红外解码,在51上用的好好的,在M16就不好用了

出0入0汤圆

发表于 2007-4-13 18:20:34 | 显示全部楼层
关注楼主解决方法.



我用电平变化中断也出现一触发不可收拾的情况,起先以为是上升、下降沿有毛刺,加了软件延迟还是不能解决,都愁死我了.

出0入0汤圆

发表于 2007-4-13 18:32:37 | 显示全部楼层
奇怪了,我在m8上用的好好的,没有出现这种情况啊。

出0入0汤圆

发表于 2007-4-13 18:53:28 | 显示全部楼层
进中断后再次查询就可以

出0入0汤圆

发表于 2007-4-13 20:18:24 | 显示全部楼层
看你外面接的是什么东西啊。如果是机械开关一类的,这种情况是肯定会有的。以前都是用定时查询加上软件防抖的,还真没用过中断来实现,不过估计也会出现这种情况。因为以前发现过AVR速度太快,外部信号变化速度不够就能够造成读取的信号不对。可以根据外部信号特点,在中断里面加点延时,或者关闭一会中断,然后用定时再打开。仿真是可能正常的。单片机的确是检测出了多个中断出现了。

出0入0汤圆

 楼主| 发表于 2007-4-14 00:27:02 | 显示全部楼层
测试中断程序添加延时防抖无效。



在i++后面添加了一条控制蜂鸣器的函数,中断触发条件设为低电平有效,则会多响应一次,蜂鸣器滴滴2声;



中断条件设为下降沿触发,则自动响应无限次,蜂鸣器一直响不停,到底是啥问题啊?

出0入0汤圆

发表于 2007-4-14 01:13:22 | 显示全部楼层
真的这样?要不都试一下,就是不知道你外部中断引脚上接的是什么东西啊。

出0入0汤圆

 楼主| 发表于 2007-4-14 01:20:39 | 显示全部楼层
一个接地的开关而已。

出0入10汤圆

发表于 2007-4-14 01:33:27 | 显示全部楼层
关注中。。。

出0入0汤圆

发表于 2007-4-14 02:34:54 | 显示全部楼层
彩虹老大:

接地开关最好硬件消抖,avr执行速度太快了,而且c语言里asm流程不清晰。

机械开关都有这个问题,按键应该遇见过的。

出0入0汤圆

发表于 2007-4-14 08:22:17 | 显示全部楼层
该不会是芯片不断复位吧?

出0入0汤圆

发表于 2007-4-14 09:09:51 | 显示全部楼层
赞同17楼,前天在中断里关闭全局中断然后再开,结果M16一直重启。楼主把中断里的cli()去掉试试。

出0入0汤圆

发表于 2007-4-14 10:23:24 | 显示全部楼层
gxlujd 彩虹大哥的程序有2个地方可以改进一下:

1:

SIGNAL (INT0_vect)

{

    cli();        //这个语句可以不要,因为这个SIGNAL不允许中断镶套

    flags=1;      //中断标志

    //请在这里加上清除中断标记的语句,防止中断期间由于按键抖动产生新的中断标记

}



2:

    while(1)

    {

        if (flags)

        {

         //   flags=0;

            i++;   

            sei();

            flags=0;     //请把这个句放在最后这里,因为中断很可能又把flags=1了

        }

    }

出0入0汤圆

 楼主| 发表于 2007-4-14 11:36:33 | 显示全部楼层
终于搞定了,现在中断可以很可靠的触发了!!!



谢谢panxiaoyi 啊艺提供的办法,做了以下改进:



SIGNAL (INT0_vect)  

{  

    flags=1;      //中断标志

    GIFR=(1<<INTF0);    //手工清中断标志,原来的cli()不要了,要了还碍事,得不到可靠的触发,很有可能触发了一次后就再也不响应了。

}



while(1)  

{  

    if (flags)  

    {   

        i++;     

        sei();

        flags=0;     //把这句从上头移下来以后,稳定多了,此句放的地方不同,效果大不一样!

    }  

}  





由现象来看,问题还是由于抖动造成的,得到的经验教训是外部中断涉及机械开关,也要十分小心的处理抖动造成的误触发,各个标志位也要在『十分适合的时候做更改』,AVR太快了,写程序一不留神就会给AVR多次触发的条件,哪怕是很短的一个逻辑空隙。



再次谢谢大家的帮助!


-----此内容被gxlujd于2007-04-14,11:38:53编辑过

出0入0汤圆

发表于 2007-4-14 12:20:16 | 显示全部楼层
学习

出0入0汤圆

发表于 2007-4-14 13:40:40 | 显示全部楼层
找到一个电路,硬件去抖

出0入0汤圆

发表于 2007-4-14 13:56:38 | 显示全部楼层
可以加施密特触发器试试

出0入0汤圆

发表于 2007-4-14 14:43:42 | 显示全部楼层
感谢啊艺,受教了 :)

出0入0汤圆

发表于 2007-4-15 07:44:54 | 显示全部楼层
I/O上加一个对GND的103-104会更好的

出0入0汤圆

发表于 2007-4-15 20:32:33 | 显示全部楼层
昨天没回来,今天回来专门看一下,学习到一些东西了,虽然我一般不用外部中断,尤其是对于这些机械开关,我对付机械开关除了消抖,还要对付市电干扰,一般都是用定时程序来完成,还是很可靠的。不过也要学习了,呵呵。谢谢楼上各位。

出0入0汤圆

发表于 2010-10-21 20:51:14 | 显示全部楼层
最近要研究外部中断,受教了!

出0入0汤圆

发表于 2010-10-21 21:35:13 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2010-10-23 23:20:45 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-6 08:33:38 | 显示全部楼层
标记

出0入0汤圆

发表于 2011-8-12 19:51:35 | 显示全部楼层
喜欢用定时查询的

出0入0汤圆

发表于 2011-9-6 17:18:29 | 显示全部楼层
学习了!!!!

出70入10汤圆

发表于 2012-1-13 15:53:36 | 显示全部楼层
look

出0入0汤圆

发表于 2012-1-15 00:06:49 | 显示全部楼层
我是 新手 不过我记得 AVR的中断就算 中断标志不清0仍然可以 继续进入下次中断吧?

如果是这样
那进入中断后关使能DLEAY 一会再开 再退出应该就好了。

出0入0汤圆

发表于 2013-4-23 16:12:04 | 显示全部楼层
虽然是老帖子,可是大家遇到问题一样,我想说用光耦,可以更好的

出0入0汤圆

发表于 2013-4-24 14:56:01 | 显示全部楼层
做软件防抖
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-27 01:25

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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