51单片机,按键控制流水灯程序,懂的进!

八个LED灯与单片机P1口连,按键key1与单片机P32连。该程序是完成以下工作:单片机上电,流水灯每一秒移一位,当按键key1按下后,流水灯停止在该灯处;当再次按下key1时,流水灯在停止处继续移位。

问题是:
在有些时候(注意:只是有些时候)在流水灯运行的时候,按下按键,流水灯停止,而当再一次按下的时候,流水灯却一直停在那里,而不重新开始运行了。
请各位高手帮我看看该程序是否哪里有缺陷!谢谢……
/****************************************/

#include<reg52.h>
#include<intrins.h>

#define uchar unsigned char
#define uint unsigned int

sbit key1=P3^2;
uchar num=0,temp;

void delay_ms(uchar N)
{
uchar i,j;
for(i=N;i>0;i--)
for(j=220;j>0;j--);
}

void init()
{
P0=0xfe;
TMOD=0x01;
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
EA=1;
ET0=1;
TR0=1;
}

void display(void)
{
P0=_crol_(P0,1);
temp=P0;
}

void key_scan(void)
{
if(key1==0)
{
delay_ms(10);
if(key1==0)
{
P0=temp;
TR0=~TR0;
}
}
while(!key1);
}

void main()
{
init();
while(1)
{
if(num==20)
{
num=0;
display();
}
key_scan();
}
}

void timer0() interrupt 1
{
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
num++;
}
不好意思,8个LED是与单片机P0口连,写错了。程序中写的P0是没错的!

假如,你的程序在执行key_scan();是触发了两次中断导致num>20,你的显示函数将永远被跳过,你应该写成
if(num>20)
{
num=0;
display();
}
这是一个比较直观的错误,其他的没细看,你在试试
温馨提示:内容为网友见解,仅供参考
第1个回答  2011-10-29
呵呵,找你的程序看,应该是当你按下键后,TR0=0;而又刚好定时器再执行中断void timer0();这样定时器不起作用了,它只能一直停在时间中断程序里面,无法进入主函数,自然无法你的按键扫描了,所以此时你不管怎么按也没有反应。。

找出了问题,相信以你的能力,你想办法尽量避免这种情况就行了。具体怎么操作我就不说了。。哈哈
第2个回答  2011-10-29
问题出在键盘扫描,有可能按键时根本没有执行到扫描程序处,因此可能漏掉按键,可以考虑将键盘扫描程序安在定时中断里,发现有按键就置一个按键标志,在主循环中判断键盘标志来决定显示或停止
第3个回答  2011-11-01
你把键盘扫描程序里的延时改小些 并试一下再TR0=~TR0后加一句init();
第4个回答  2011-10-29
将程序if(num==20)
{
num=0;
display();
}
放到定时器0中断子程序中 就0k了。
相似回答