标题:
51单片机的外部中断函数里可以有if语句吗
[打印本页]
作者:
佳佳0227洋洋
时间:
2015-4-8 20:20
标题:
51单片机的外部中断函数里可以有if语句吗
/* 通过中断来控制流水灯 */
#include <reg52.h>
#include <intrins.h>
#define LED P0
#define uchar unsigned char
//uchar count;
void delay_100ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 5;
j = 52;
k = 195;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void liushuideng1()
{
uchar i,led;
led = 0xfe;
// while(1)
// {
for(i=0;i<8;i++)
{
LED = _crol_(led,i);
delay_100ms();
if(i==8)
i = 0;
EX0 = 1;
}
// }
}
void liushuideng2()
{
uchar led,i;
led = 0xff;
// while(1)
// {
for(i=0;i<8;i++)
{
led >>= 1;
LED = led;
delay_100ms();
if(i==8)
{ i = 0;
led = 0x7f;}
}
// }
}
void liushuideng3()
{
uchar led;
led = 0xaa;
// while(1)
// {
LED = led;
delay_100ms();
LED = ~led;
delay_100ms();
// }
}
void ZD_init()
{
EA = 1;
EX0 = 1;
IT0 = 1;
}
void main()
{
// uchar i;
ZD_init();
while(1)
{
LED = 0xff;
delay_100ms();
LED = 0x00;
delay_100ms();
}
}
void waibuZD0() interrupt 0
{
static count = 0;
count++;
if(count == 1)
{
liushuideng1();
// delay_100ms();
}
else if(count == 2)
{
liushuideng2();
// delay_100ms();
}
else if(count == 3)
{
liushuideng3();
// delay_100ms();
}
else
{ count = 0;
}
}
复制代码
上面是代码,现象是,中断一次会产生两个流水灯现象。而我要的是中断一次只产生一个流水灯现象。并且只用一个中断。
作者:
dingmingzhou
时间:
2015-4-9 09:00
好像没人说不可以
作者:
dingmingzhou
时间:
2015-4-9 09:01
好像没人说不可以在中断服务程序里用IF
作者:
maxplus
时间:
2015-4-9 10:56
估计是中断源的问题,如果中断源是按键,就可能是按键抖动的问题,实际上产生了多次中断。可以加个消抖电路,不如加个电容之类
作者:
克林
时间:
2019-11-12 16:23
如果中断源是按钮的话,可以通过代码延时来进行按钮的消抖操作
作者:
别问我呀
时间:
2019-11-12 17:21
当然可以呀
作者:
噗噗噗p
时间:
2019-11-12 17:53
按键按下存在抖动,必须要采取硬件或者软件延时来消除抖动
作者:
liuyongjun000a
时间:
2019-11-12 17:54
你这代码没问题,主要是外引脚触发方式没有定义吧,上升沿和下降沿都解发了中断,所以就出现两次了。
作者:
faiwong
时间:
2019-11-12 21:17
IT0默认为0,上升沿中断,下降沿也中断,你所说的中断一次实际上是触发了两次中断,产生两个流水灯现象没毛病。
作者:
Dfadti
时间:
2019-11-12 21:54
可以的,实在不知道,就试试嘛
作者:
qwertyuio543
时间:
2019-11-12 22:46
可以的
作者:
bh2030693
时间:
2019-11-12 22:46
根据你的代码原文稍作精简和修饰,你可以试一下(while里面注释掉的代码也可以取消注释):
/* 通过中断来控制流水灯 */
#include <intrins.h>
#include <reg52.h>
#define LED P0
#define uchar unsigned char
void Delay_100ms(void) {
unsigned char i, j, k;
_nop_();
_nop_();
i = 5;
j = 52;
k = 195;
do {
do {
while (--k)
;
} while (--j);
} while (--i);
}
void LiuShuiDeng1(void) {
uchar i;
for (i = 0; i < 8; i++) {
LED = ~(0x01 << i);
Delay_100ms();
}
}
void LiuShuiDeng2(void) {
uchar i;
uchar temp = ~0x80;
for (i = 0; i < 8; i++) {
LED = temp >> i;
Delay_100ms();
}
}
void LiuShuiDeng3(void) {
LED = 0xaa;
Delay_100ms();
LED = ~0xaa;
Delay_100ms();
}
void ExInt0_init(void) {
IT0 = 1;
EX0 = 1;
EA = 1;
}
void main(void) {
ExInt0_init();
while (1) {
// LED = 0xff;
// Delay_100ms();
// LED = 0x00;
// Delay_100ms();
}
}
void ExInt0(void) interrupt 0 {
static uchar count;
count++;
switch (count) {
case 1:
LiuShuiDeng1();
break;
case 2:
LiuShuiDeng2();
break;
case 3:
LiuShuiDeng3();
count = 0;
break;
default:
count = 0;
break;
}
}
作者:
bh2030693
时间:
2019-11-12 23:14
当第一次外部中断0执行的时候,外部中断请求位IE0会自动被清零,中断之所以执行两遍,很显然是当执行第一次中断的过程中再次有信号触发了中断,所以第一遍执行完依然存在中断标志,继而执行第二次中断并清除已存在的请求标志。为什么没有第三次?因为这个触发信号显然在第一次触发的时候发生的,正如楼上几位朋友分析的,是因为抖动重复触发。
在中断函数最后一个大括号前加一句:“IE0 = 0;”人为清除中断请求标志。
void ExInt0(void) interrupt 0 {
...
...
...
IE0 = 0;
}
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1