Keil C 中的关于中断程序退出状态问题

想完成如下功能:按9次按键,P1对应显示按键次数(二进制数)。当按第10下时,正常退出INT0程序,打开TIMER0,LED能正常闪烁。
可是如果我在INT0的最后不加延时delay(200)时,程序当按第10下时,P1端口却直接显示1了(应该显示10)。原先以为程序在跳出while时、结束中断时,检测到MODE是低电平,会再次触发INT0,可是我增加了for(;;)当按钮松掉时,离开INT0中断,还是不行。不知道为什么,请高手帮忙解答。
程序清单、仿真图如下
#include <at89x51.h> #include <intrins.h> unsigned char data sec100; unsigned char data flag;bit vkey,skey; sbit MODE=P2^6;sbit BLINK = P3^7;sbit LED = P2^3;
void delay(unsigned char ms) { while(ms--) {unsigned char i; for(i = 0; i< 250; i++); } }
void timer0() interrupt 1 { TH0=0xdc;TL0=0x00; //(f0=11.0592Mhz) sec100++;

if(sec100 >= 50){sec100 = 0;BLINK=0; delay(100);BLINK=1;} }
void int0() interrupt 0 { TR0=0; //禁止Timer0 IE=0; //禁止中断
flag=0; vkey=1; while(flag^0x0a){skey =MODE; //扫描按键状态 if (skey^vkey) //若skey与vkey相同,跳出循环,相异执行循环体 {delay(10); //去按键抖动 skey =MODE; //转回扫描按键状态 if (skey^vkey) //若skey与vkey相同,跳出循环,相异执行循环体 {vkey=skey; //将skey的值付给vkey if (skey==0) //MODE键按下 {flag++;}//调整标志位加1 } }
P1=flag; //P1实时显示flag 值}//while循环结束
//========以下两句,对结果没有影响,但理论上讲,应该是起作用的============for(skey=MODE;skey=0;delay(20),skey=MODE);//当按钮松掉时,离开INT0中断if(MODE=1)//======================================================{IE=0x8f; //CPU开中断,INT0,INT1,开中断LED=0; //TESTTR0=1; //Timer0启动}//delay(200);//这条语句写与不写结果不同. }
void main() {IE = 0x8f; //CPU开中断.IP = 0x04; //设置INT0为中断最高优先级IT0=0; //外部INT0,要求必须是电平触发方式TMOD = 0x11; TH0 = 0xdc;TL0 = 0x00;
TR0 = 1; //Timer0启动while(1); }

你的困惑根源在于对按键按下/抬起瞬间的状态认识不足。
事实上,在按键按下/抬起瞬间,按键端口上会有一个持续抖动的电平(类似于不规则锯齿波,你可以上网查找一下),因此在一段时间之内P2.6上采集的电平将是不断变化的0-1-0序列。你所增加的for(;;)只判断一种电平,所以也并不能起到去抖的作用。

一般较通用的按键处理流程是:当INT0#检测到跳变沿中断时,置一个标志,关闭EX0中断使能;主循环中凭借此标志延时20~100ms去抖(说白了就是避过按键电平不稳定的这段时间),然后重新采集P2.6状态,仍旧是低电平才判定为有效按键变化。
对于连接线较长或者易受干扰的场合,按键处理应增加至少一阶的数字滤波。
温馨提示:内容为网友见解,仅供参考
无其他回答

Keil C 中的关于中断程序退出状态问题
一般较通用的按键处理流程是:当INT0#检测到跳变沿中断时,置一个标志,关闭EX0中断使能;主循环中凭借此标志延时20~100ms去抖(说白了就是避过按键电平不稳定的这段时间),然后重新采集P2.6状态,仍旧是低电平才判定为有效按键变化。对于连接线较长或者易受干扰的场合,按键处理应增加至少一阶的数...

用keil调试运行到中断里面的最后两条程序就卡住了 然后就退出调试状态...
卡住原因恐怕是你的程序没有返回,在那里死循环了被强制退出

C语言用keil编程,关于while
如果没有这个死循环,那么程序在执行完一次后就结束运行退出了。你给出的代码有个中断处理函数,如果main里有while(1),大概的意思是中断函数执行一次,cnt++,在cnt达到1000等数的时候,就会设置相应的P1、P0等。如果没有while(1),程序执行进去什么都不会做,应为cnt变量没有增加到超过1000。

怎样正确退出Keil的调试状态
如果程序正在调试运行,需要先Stop。然后再点击退出调试按钮就行了。

请教单片机高人:怎么用C编写中断,汇编中可以有ORG 000BH来确定是T0中...
在中断函数中调用的函数所使用的寄存器组必须与中断函数相同。当没有使用using指令 时,编译器会选择一个寄存器组作为绝对寄存器访问。程序员必须保证按要求使用相应寄存 器组,C编译器不会对此检查。·如果在中断函数中执行浮点运算,必须保存浮点寄存器状态,当没有其他程序执行浮点运 算时,可以不保存。

单片机c语言如何返回主函数
中断里面不能用形参和返回值!!!具体的做法是声明一个全局变量,在中断中改变变量的值或者说状态。主程序就负责判断这个变量的状态,根据状态做出选择,如果状态比较多就用SWITCH,否则if就可以了。对于你补充的问题可以这样 在函数里,需要退出的地方写上,return;if(有推出键按下) retrun;...

请教用MDK编译出现dfa.axf: Error: L6218E: Undefined symbol_百...
出现Target not created,原因主要有:编译时出错,语法错误,变量未定义。连接时出错,调用外部函数,而由缺少相应的OBJ文件。其他原因,用Demo版,限制是程序不能大于4K,结果你超过了4k。Target not created:意思就是编译没有成功。这是因为程序中有错误。编译语言:是一种以编译器来实现的编程语言。

编译没有错误,但是KEIL有个红色的叉叉.不知为什么
;this.setTitle("停车场管理系统");this.setResizable(false);\/\/窗体大小不可改变 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\/\/当窗体为退出和关闭状态的时候,程序也退出 this.setLocationRelativeTo( null);\/\/窗体位置相对于屏幕居中对齐 this.setVisible(true);\/\/ 设置窗体可观 ...

当处理器开始处理异常时,异常的挂起状态如何处理
中断的挂起状态可以通过访问NVIC寄存器来读写,所以用户可以清除一个挂起的中断标志位或者用软件设置挂起寄存器以挂起一个新的中断。3、当处理器开始执行一个中断时,该中断的状态变为active,且挂起的位将被自动清除。同一个中断处理函数在处理的过程中不能嵌套,只有当异常退出(exception exit)将其active状态被清除后,...

对于switch语句在keil里的问题,向keil大神c大神求解
哥们儿,你程序里连主循环都没有?你这程序执行完switch后,一直跑空指令直到复位……

相似回答