为何外部中断触发一次响应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编辑过 我以前也碰到过,那是检测货币机的,有投币的话会产生一宽度为100ms的脉冲,采用上升沿触发外部中断,但发现好像被触发多次(3次、4次、5次都有),也没弄明白为什么?改换采用查询方式! to chunnynee:
我看到你以前的帖子了,咱两同病相怜哦,呵呵~~~~~
玩了这么久单片机,使用INTO还是极少的,以前用BASCOM-AVR没这个问题的。 根据触发中断的脉冲宽度在软件上做一下防抖会不会好一些? 曾用CV产生的程序,解决上述问题.离开中断前用软件清中断标志试试. 试过手工清中断标志,不行,还是照样多次执行中断服务程序,软件防抖倒是没试过,今晚试试看,有结果再来汇报。 如果硬件没有防抖措施,软件也应该可以改善。 我用M16也是的,用来做红外解码,在51上用的好好的,在M16就不好用了 关注楼主解决方法.
我用电平变化中断也出现一触发不可收拾的情况,起先以为是上升、下降沿有毛刺,加了软件延迟还是不能解决,都愁死我了. 奇怪了,我在m8上用的好好的,没有出现这种情况啊。 进中断后再次查询就可以 看你外面接的是什么东西啊。如果是机械开关一类的,这种情况是肯定会有的。以前都是用定时查询加上软件防抖的,还真没用过中断来实现,不过估计也会出现这种情况。因为以前发现过AVR速度太快,外部信号变化速度不够就能够造成读取的信号不对。可以根据外部信号特点,在中断里面加点延时,或者关闭一会中断,然后用定时再打开。仿真是可能正常的。单片机的确是检测出了多个中断出现了。 测试中断程序添加延时防抖无效。
在i++后面添加了一条控制蜂鸣器的函数,中断触发条件设为低电平有效,则会多响应一次,蜂鸣器滴滴2声;
中断条件设为下降沿触发,则自动响应无限次,蜂鸣器一直响不停,到底是啥问题啊? 真的这样?要不都试一下,就是不知道你外部中断引脚上接的是什么东西啊。 一个接地的开关而已。 关注中。。。 彩虹老大:
接地开关最好硬件消抖,avr执行速度太快了,而且c语言里asm流程不清晰。
机械开关都有这个问题,按键应该遇见过的。 该不会是芯片不断复位吧? 赞同17楼,前天在中断里关闭全局中断然后再开,结果M16一直重启。楼主把中断里的cli()去掉试试。 gxlujd 彩虹大哥的程序有2个地方可以改进一下:
1:
SIGNAL (INT0_vect)
{
cli(); //这个语句可以不要,因为这个SIGNAL不允许中断镶套
flags=1; //中断标志
//请在这里加上清除中断标记的语句,防止中断期间由于按键抖动产生新的中断标记
}
2:
while(1)
{
if (flags)
{
// flags=0;
i++;
sei();
flags=0; //请把这个句放在最后这里,因为中断很可能又把flags=1了
}
} 终于搞定了,现在中断可以很可靠的触发了!!!
谢谢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编辑过 学习 找到一个电路,硬件去抖
http://cache.amobbs.com/bbs_upload782111/files_7/armok01150397.gif 可以加施密特触发器试试 感谢啊艺,受教了 :) I/O上加一个对GND的103-104会更好的 昨天没回来,今天回来专门看一下,学习到一些东西了,虽然我一般不用外部中断,尤其是对于这些机械开关,我对付机械开关除了消抖,还要对付市电干扰,一般都是用定时程序来完成,还是很可靠的。不过也要学习了,呵呵。谢谢楼上各位。 最近要研究外部中断,受教了! 学习学习 mark 标记 喜欢用定时查询的 学习了!!!! look 我是 新手 不过我记得 AVR的中断就算 中断标志不清0仍然可以 继续进入下次中断吧?
如果是这样
那进入中断后关使能DLEAY 一会再开 再退出应该就好了。 虽然是老帖子,可是大家遇到问题一样,我想说用光耦,可以更好的 做软件防抖
页:
[1]