单片机外部中断0的疑问 为什么第一按int1,调用定时器1,执行了继电器的工作。当再次按int1就没有反应了?

void main()
{
EX1=1;
IT1=1;
EA=1;
while(1);
}
void int1() interrupt 2
{
TMOD=0x10;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
ET1=1;
TR1=1;
}
void t1() interrupt 3
{
count++;
if(count==20)
{
count=0;
second++;
}
switch (second)
{
case 1:P1=0xfe;break;//继电器1工作
case 4:P1=0xfd;break;//继电器2工作
case 7:P1=0xfb;break;//继电器3工作
case 13:P1=0xfe;break;//继电器1工作
case 17:P1=0xf7;break;//继电器4工作刹车
case 20:P1=0xff,TF1=0,IE1=0;break;//所有继电器停止工作

}
}
void int1() interrupt 2
{
TR1=1;
}
void t1() interrupt 3
{
TMOD=0x10;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
ET1=1;
count++;
if(count==20)
{
count=0;
second++;
}
switch (second)
{
case 1:P1=0xfe;break;//继电器1工作
case 4:P1=0xfd;break;//继电器2工作
case 7:P1=0xfb;break;//继电器3工作
case 13:P1=0xfe;break;//继电器1工作
case 17:P1=0xf7;break;//继电器4工作刹车
case 20:P1=0xff,TF1=0,IE1=0;break;//所有继电器停止工作

}
}
这样对吗?

首先,你用的不是外部中断0,你用的是外部中断1进行的外部中断中断;其次,你的定时器开启之后就没有关闭,所以second会一直加下去,同时,你再按下外部中断1也不会再执行从零开始加了。第三点TF1=0,IE1=0会硬件自动清零的,不用单独写程序设置它。基于以上这些,我给你改了一下程序,希望对你有用。如果你能把电路是怎么连接的发给我的话,我可以给你仿真一下。那样就知道结果是怎么样的了!
void main()
{
EX1=1;//允许外部中断1中断
IT1=1;//选择外部中断为跳变沿触发方式
EA=1;//开总中断
while(1);
}
void int1() interrupt 2//外部中断1
{
TMOD=0x10;//定时计数器1模式1(16位计数器)
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;//装初值
ET1=1;//允许定时器1中断
TR1=1;//为定时器1的运行控制位
second=0;
}
void t1() interrupt 3///定时器1中断
{
count++;
if(count==20)
{
count=0;
second++;
}
switch (second)
{
case 1:P1=0xfe;break;//继电器1工作
case 4:P1=0xfd;break;//继电器2工作
case 7:P1=0xfb;break;//继电器3工作
case 13:P1=0xfe;break;//继电器1工作
case 17:P1=0xf7;break;//继电器4工作刹车
case 20:P1=0xff;break;//所有继电器停止工作

}
if(second==20)
{
TR1=0;
}
}
我认为你的switch case没有问题,因为在没有符合条件的时候语句就什么也不执行,P1口还是原来的数据,所以可以完成你的继电器工作时间要求。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2010-09-13
你这个程序用中断来完成对外部设备的操作不可取,应该在中断中设置标志位,在主程序中完成外部设备操作!还有你的case用错了吧
我帮你改一下吧:

void main()
{
TMOD=0x10;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
EX1=1;
IT1=1;
EA=1;
count=0;
second=0;
while(1)
{
if(flag_1scnd)
{
second=second++;
}
switch (second)
{

case 0:P1=0xff;break;//加一个case0吧
case 1:
case 2:
case 3:P1=0xfe;break;//继电器1工作
case 4:
case 5:
case 6:P1=0xfd;break;//继电器2工作
case 7 8 9 10 11 12:P1=0xfb;break;//继电器3工作
case 13 14 15 16:P1=0xfe;break;//继电器1工作
case 17 18 19:P1=0xf7;break;//继电器4工作刹车

//最后一个case很关键
case 20:
{
P1=0xff;
TR1=0;
ET1=0; //关定时器1中断
}break;//所有继电器停止工作
}

}
}
void int1() interrupt 2
{
ET1=1;
TR1=1;
}
void t1() interrupt 3
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
count++;
if(count==20)
{
count=0;
flag_1scnd=1;//定时1秒标志
}本回答被提问者采纳
第2个回答  2010-09-13
你这样写不对吧!int1() 这里面你做的是什么事???你在这边给T1重新傅值是什么意思?要也要在t1()里面。再有一个就是你中断里不要那么做,设个标志位。功能的执行在外头执行。
相似回答