单片机流水灯问题

题目:在P1口接8个发光二极管(高电平或低电平亮都可以),完成流水灯功能。设计一个按键(随便哪个口),开始中间朝二边开花,按一次键松开后由上到下亮,再按松开后由下到上亮,再按松开后朝二边开花,又再按键松开后朝二边开花,如此循环。形成三种状态,如R1开始为0,按以下键松开后R1加一,加到3又回到零,形成0、1、2三种状态,判别零的值程序到不同的分支)。

我编写的程序:#include<at89x52.h>
#define uchar unsigned char
#define uint unsigned int
sbit key=P3^0;
uint data count;

void delay(){
uint i;
for(i=0;i<32000;i++);
}

void led0(void){
uchar temp=0x18,a,b;
uint i;
P1=temp;
delay();
for(i=0;i<4;i++){
a=(temp&0xf0)<<i;
b=(temp&0x0f)>>i;
P1=a|b; delay();
}
}

void led1(void){
uchar cmd=0x01;
while(1){
P1=cmd;
delay();
if((cmd&0x80)==0x80) cmd=(cmd<<1)+1;
else cmd=cmd<<1;
}
}

void led2(void){
uchar cmd=0x80;
while(1){
P1=cmd;
delay();
if((cmd&0x01)==0x01) cmd=(cmd>>1)+0x80;
else cmd=cmd>>1;
}
}

void main(void){
count=0;
led0();
while(1){
if(key==0){
delay();
if(key==0){
count=count+1;
if(count==3) count=0;
}
while(key==0);
}
switch(count){
case 0: led0();break;
case 1: led1();break;
case 2: led2();break;
default:;
}
}
}

问题:仿真按键转换状态时,第一次按,转为第二种状态,再次按键后,就没反应了,不能转为下一状态,请大侠们指点一下,谢谢!!

第1个回答  推荐于2016-02-07
你的问题在与led1()和led2()中有while(1)死循环,程序是不会出来了,可以根据实际要求设定循环次数,但是如果这样 按下的时间会长,因为要执行完for 才能检测到按键。
键盘最好不用P0口,如果要使用必须接上拉电阻
#include<at89x52.h>
#define uchar unsigned char
#define uint unsigned int
sbit key=P3^0;
uint data count;

void delay(){
uint i;
for(i=0;i<32000;i++);
}

void led0(void){
uchar temp=0x18,a,b;
uint i;
P1=temp;
delay();
for(i=0;i<4;i++){
a=(temp&0xf0)<<i;
b=(temp&0x0f)>>i;
P1=a|b; delay();
}
}

void led1(void){
uchar cmd=0x01;
for( )//这里不能用死循环;就像led0()一样,用FOR控制次数,你自己填写吧,不过这样按按键的时间要长。
{
P1=cmd;
delay();
if((cmd&0x80)==0x80) cmd=(cmd<<1)+1;
else cmd=cmd<<1;
}
}
}
void led2(void){
uchar cmd=0x80;
for( )//这里不能用死循环;就像led0()一样,用FOR控制次数,你自己填写吧,不过这样按按键的时间要长。
{

P1=cmd;
delay();
if((cmd&0x01)==0x01) cmd=(cmd>>1)+0x80;
else cmd=cmd>>1;
}
}
}
void main(void){
count=0;
led0();
while(1){
if(key==0){
delay();
if(key==0){
count=count+1;
if(count==3) count=0;
}
while(key==0);
}
switch(count){
case 0: led0();break;
case 1: led1();break;
case 2: led2();break;
default:;
}
}
}本回答被提问者采纳
第2个回答  2010-11-09
按键是否接有上啦电阻?松开后不能自动上拉吧。另外你的led1、2函数里面都有while(1){},按理说按键根本就不会有作用,但是你的led0()里面又没有while(1){}所以能从第一状态跳出来,第一次按键后进入led1()后,就无法扫描你的按键程序咯。
呵呵!

给分吧!
第3个回答  2010-11-09
把松手检测放到判断函数内部改成如下程序试一下:
void main(void){
count=0;
led0();
while(1){
if(key==0){
delay();
if(key==0){
while(key==0);
count=count+1;
if(count==3) count=0;
}

}
switch(count){
case 0: led0();break;
case 1: led1();break;
case 2: led2();break;
default:;
}
}
}
第4个回答  2021-04-05

花样流水灯的玩法,一个51单片机8位端口轮流输出16颗灯珠,

怎样用单片机实现一个流水灯的效果呢?
单片机流水灯1到8依次亮,是通过编程控制单片机的I\/O端口实现的。通常使用循环结构和延时函数,依次将每个LED灯对应的I\/O端口置为高电平,使其亮起,然后延时一段时间,再将其置为低电平,使其熄灭。通过不断循环这个过程,就可以实现流水灯的效果。单片机流水灯是一种常见的电子制作项目,它通过单片机...

单片机流水灯怎么实现的?
在这个单片机流水灯代码中,假设使用的是8051单片机。需要定义8个LED灯,分别连接到P1端口的不同引脚上。然后使用一个循环结构来控制这8个LED灯按照一定的顺序逐个亮起,形成流水灯的效果。具体来说,使用for循环来控制LED灯的亮灭顺序。在每次循环中,通过给P1端口赋值来控制LED灯的亮灭状态。例如,给P...

用51单片机写了一个流水灯程序,有一点问题,请高手解惑
单片机的流水灯程序,因为程序就这么写的,决定了流水灯左移7次,再右移7次,结束两个循环后,才能执行下面的while(!key),按键才有效,而在循环过程中,不执行while(!key),所以按键无效。下图画红框内的两个循环。要想按键随时有效,应该把两个移位函数_cror_,_crol_ 放在主程中,检测key也放在...

关于单片机流水灯的问题
12MHz为时钟周期,如果不分频,定时器周期也为12MHz,51单片机为12分频。以下计算均为不分频。Fc = 12MHz, Time = 1s ,计数次数为12_000_000,如果有16bit定时器,计数上限65535,不可以满足,因此要配合软件计数。12000000 = 60_000 X 200.硬件连接为:发光二极管的压降为1~3V,额定电流:20mA ...

单片机流水灯全亮,我亦有同样问题在看见最佳回答后仍不知如何解决,附网...
单片机默认复位后或者上电后的所有引脚输出都为高电平,这是为了方便读取数据。所以,你的单片机在上电之后就是全亮,因为你的LED灯是正极接在了单片机的输出口上了,LED的负级接的地。这样芯片上电后,灯就全亮了。有可能你的芯片没有设置上电复位电路,就是说程序并没有在芯片上电之后就运行。所...

单片机流水灯不能循环
这是由于定时器设置的1ms,间隔很短,在i归零时,counter很难落到0-100之间,而是落在100-800间,这时counter=time[0]*100显然无法成立,移位操作没有执行,导致流水灯停止,只有等到counter溢出后回环,才会重新恢复正常(你可以观察一下,卡住以后等一会会自动恢复)为了验证这个问题,你可以将time[]=...

怎样用单片机控制流水灯的闪烁?
可以用for循环试试unsingned char i;for(i=0;i<5;i++)\/\/流水灯闪烁程序。若干个灯泡依次点亮就叫流水灯,它用在夜间建筑物装饰方面。例如在建筑物的棱角上装上流水灯,可起到变换闪烁美不胜收的效果。单片机(Single-Chip Microcomputer)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据...

51单片机C程序实验LED灯:[2]左到右的流水灯
说明:实现一排灯从左到右依次一个一个点亮熄灭,实现流水灯 proteus电路图 元件清单:(分别是) 51单片机 电容 瓷片电容(也可用普通电容) 晶振 红色二极管 电阻 电路图的连接方法 程序清单 说明:本例有两种程序写法 第一种是入门级别比较基础的写法 先是依旧延时子程序,然后主程序利用直接赋值,与...

请问51单片机数码管0到1000的同时流水灯从左到右循环点亮,数码管到1000...
这需要四位数码管显示加8个流水灯,而数码管显示和流水灯都需要延时,如果处理不好两个延时方式,就会造成数码管显示闪烁和流水灯停顿。可以用数码管显示一遍作为流水灯的延时。

51单片机流水灯怎么循环3次停止?
设置3次循环,每次引用流水灯,循环3次后就会停止。

相似回答