51单片机流水灯程序

#include <reg51.h>
void delay(int z)
{
int i,j;
for(i=z;i>0;i--)
for(j=148;j>0;j--);
}
void main()
{
char a=0xfe;
while(1)
{
P0=a;
delay(200);
a=a<<1;
a=a|0x01;
if(a==0xff)
a=0xfe;
}

}不知道为什么这个程序只流水一遍,随后P0全部置1了,keil4不是可以自动循环吗?去掉while(1)只有P00对应的LED亮,费解…求大神解答~~

第1个回答  2014-08-10
程序错误
#include <reg51.h>
#define uchar unsigned char;
#define uint unsigned int;
void delay(uint x)
{
uchar i;
while(x--)
{
for(i=0;i<120;i++);
}
}
void main()
{
uchar a=0xfe;
while(1)
{
P0=0xfe;
for(i=0;i<7;i++)
{
P0=_crol_(P0,1);
delay(150) ;
}
if(a==0xff)
a=0xfe;
}追问

_crol_这个函数是循环左移吧…当P0=0x7f继续左移后P0变为0xfe……
我程序哪错了啊?麻烦指出来让我明白一下好吗?我也很费解看不出哪错了…

追答

_crol_这个函数的确是循环左移。

当你去掉while(1)时,程序只运行一次,所以肯定就只会流动一次。while(1)是在不掉电的情况下,一直循环while(1)函数里面的程序。
你程序错误出现在主程序:
a=a|0x01;
if(a==0xff)
这两个式子。

追问

Kiel4不是可以自动循环?不是没有while(1)烧写以后也可以循环执行程序?
还是不明白错哪了,要是按位左移的话当P0=0x7f时,再左移后a成为0xfe按位或之后成为0xff,不是应该领a继续等于0xfe吗?所以加if语句判断一下a是否是0xff
不知道错在哪?望指点~!

追答

你没用Proteus做仿真么?
那我继续说几句,你可以参考一下。

在第7次执行到a=a<<1后,

P7-P0口的状态是
01111111
然后再执行a=a|0x01运算后的结果还是
0111111
而你if语句是if(a==0xff)

即P7-P0口的状态是
11111111
所以就不会执行
a=0xfe;

然后再次返回到while(1)时,
P0口全部置为1 也就是全部为高电瓶,
你的程序只要改一点就行了;
即在运行到第七次的时候
if(a==0xff)
改为
if(a==0x7f)。

你这程序还可以改另外一处程序,也可以实现你需要的动作。你知道怎么改么?

追问

哥们,你说的不对啊…当P0=0x7f时先左移才或的啊…肯定会出现0xff的…
假设a现在是0x7f吧,将a赋给P0,然后a左移成为0xf7,然后a或0x01,a成为0xff,所以要判断a是否是0xff,如果a是0xff,再将a变为0xfe,继续执行程序
我的程序是先执行左移再或的

追答

我刚才也说错了。
在第4次执行完a=a<<1后
这时P0口会出现这种状况;

P7---P0
11101111
再执行a=a|0x01时,P0口的状态会是这样的
P7---P0
11101111
因为a=a|0x01是或运算,而你P0口的高4为1110和0x01的高4位全为0000;
所以在往下执行下去,P0口的状态将会是00001111

还有你说:【哥们,你说的不对啊…当P0=0x7f时先左移才或的啊 】 当第7次还没执行到a=a<<1,时P0口的状态是10001111,(按照我刚才错误的说的话 P0口的状态是10111111,当执行a=a<<1
后,P0口的状态为01111111,然后执行a=a|0x01,然后就会出现a=0x7f,就会执行if语句。)

本回答被提问者采纳
第2个回答  2018-01-07
答案错误,题主不要采纳