gxlujd 发表于 2007-4-13 16:09:31

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

请大家看看这个程序,按理说应该触发一次外部中断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编辑过

chunnynee 发表于 2007-4-13 16:24:24

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

gxlujd 发表于 2007-4-13 16:31:15

to chunnynee:



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

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

nsza 发表于 2007-4-13 16:37:27

根据触发中断的脉冲宽度在软件上做一下防抖会不会好一些?

tidal 发表于 2007-4-13 16:51:36

曾用CV产生的程序,解决上述问题.离开中断前用软件清中断标志试试.

gxlujd 发表于 2007-4-13 16:57:22

试过手工清中断标志,不行,还是照样多次执行中断服务程序,软件防抖倒是没试过,今晚试试看,有结果再来汇报。

Cocal 发表于 2007-4-13 17:05:34

如果硬件没有防抖措施,软件也应该可以改善。

xczhaony 发表于 2007-4-13 17:35:51

我用M16也是的,用来做红外解码,在51上用的好好的,在M16就不好用了

fzdz 发表于 2007-4-13 18:20:34

关注楼主解决方法.



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

luxinsun 发表于 2007-4-13 18:32:37

奇怪了,我在m8上用的好好的,没有出现这种情况啊。

jjcool 发表于 2007-4-13 18:53:28

进中断后再次查询就可以

ssyniuej 发表于 2007-4-13 20:18:24

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

gxlujd 发表于 2007-4-14 00:27:02

测试中断程序添加延时防抖无效。



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



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

ssyniuej 发表于 2007-4-14 01:13:22

真的这样?要不都试一下,就是不知道你外部中断引脚上接的是什么东西啊。

gxlujd 发表于 2007-4-14 01:20:39

一个接地的开关而已。

TonyCai 发表于 2007-4-14 01:33:27

关注中。。。

JAMESKING 发表于 2007-4-14 02:34:54

彩虹老大:

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

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

donkey 发表于 2007-4-14 08:22:17

该不会是芯片不断复位吧?

cpu100 发表于 2007-4-14 09:09:51

赞同17楼,前天在中断里关闭全局中断然后再开,结果M16一直重启。楼主把中断里的cli()去掉试试。

panxiaoyi 发表于 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了

      }

    }

gxlujd 发表于 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多次触发的条件,哪怕是很短的一个逻辑空隙。



再次谢谢大家的帮助!./emotion/em105.gif


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

hualang0929 发表于 2007-4-14 12:20:16

学习

lionmilk 发表于 2007-4-14 13:40:40

找到一个电路,硬件去抖

http://cache.amobbs.com/bbs_upload782111/files_7/armok01150397.gif

ghost2 发表于 2007-4-14 13:56:38

可以加施密特触发器试试

Cocal 发表于 2007-4-14 14:43:42

感谢啊艺,受教了 :)

xiaobendan 发表于 2007-4-15 07:44:54

I/O上加一个对GND的103-104会更好的

ssyniuej 发表于 2007-4-15 20:32:33

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

joycat 发表于 2010-10-21 20:51:14

最近要研究外部中断,受教了!

worldly_guest 发表于 2010-10-21 21:35:13

学习学习

litteworm 发表于 2010-10-23 23:20:45

mark

lzbpli 发表于 2011-8-6 08:33:38

标记

Inside 发表于 2011-8-12 19:51:35

喜欢用定时查询的

talentandy008 发表于 2011-9-6 17:18:29

学习了!!!!

ifare 发表于 2012-1-13 15:53:36

look

iom16v.h 发表于 2012-1-15 00:06:49

我是 新手 不过我记得 AVR的中断就算 中断标志不清0仍然可以 继续进入下次中断吧?

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

bbssilverkey 发表于 2013-4-23 16:12:04

虽然是老帖子,可是大家遇到问题一样,我想说用光耦,可以更好的

huangshuyi 发表于 2013-4-24 14:56:01

做软件防抖
页: [1]
查看完整版本: 为何外部中断触发一次响应N次?