51单片机流水灯程序解析,求大神指导,本人是初学者。

这是我从教程书上复制的流水灯代码:
#include<reg51.h>
#include<stdio.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
//延时
void DelayMS(uint x)
{
uchar i;
while(x--)
{
for(i=0;i<120;i++);
}
}
//主程序
void main()
{
P0=0xfe;
while(1)
{
P0=_crol_(P0,1);
DelayMS(150);
}
}
代码正确,但我想弄清楚P0=0xfe;的作用,0xfe转化为十进制为254,为什么P0要赋值一个254呢,我试了将P0=0xfe变为P0=0x01.效果就完全相反了,之前就是流水灯(一个亮,七个暗,逐个发亮),改变后还是流水灯(一个暗,七个暗,逐个熄灭),为什么会这样呢,随后我又将P0=0xfe变为P0=0x00,之后就一直发亮,没有流水灯效果了,希望大神帮我解释一下;还有我还想了解一下P0端的作用,一开始是高电平还是低电平,还是将P0.0赋值为0后是低电平,赋值非0后为高电平?
电路图补充

你认真分析原理图啊,上面明显接成共阳的了。

1、51单片机上电时,端口都是高电平的,只有运行程序,电平才可能产生变化。复位时,端口也是高电平。

2、你这仿真图中,LED正端都接到电源了,负端接单片机IO,根据二极管正向导通原理,此时负端肯定要为低电平,二极管才导通,才会亮。

所以,你要点亮哪个LED,你就要让那个IO口输出0。
0xfe,二进制为1111 1110,正好是P0.0输出0,其它都为高,所以P0.0那个灯就亮。

你要是输出0x01,二进制为0000 0001,可以看到,除了P0.0高电平,其它都是低电平。那么,P0.0那个灯肯定是不会亮的,而其它几个灯肯定都会亮。

你要是想输出1,灯亮,你就要把二极管换一种接法。

这样说,你明白嘛?追问

真的好谢谢你,终于有所明白了,0xfe就是一个灯亮,0xfc就是两个灯亮呀,试了一下果然这样。不过你之前所说的原理图接成了共阳,那怎样结成共阴呢?是这样吗?

不过这样接了之后就所有的灯都不亮了?究竟什么回事?

追答

1、接个上拉电阻试试吧,不接上拉,你就接到其它端口,如P1,P2等 ……
2、高电平点亮,别搞错了。

温馨提示:答案为网友推荐,仅供参考
第1个回答  2014-03-26
首先,楼主要搞清楚P口的值与P口每一个输出端的关系,也即楼上所说的,要转换成二进制来看,数据0xfe = 1111 1110中的每一个1或0对应一个端口的高或低电平;其次楼主要结合电路图LED的接法与单片机端口的属性,搞清楚是1使得灯亮还是0使得灯亮;最后楼主要知道函数_crol_(P0,1)的作用,它是将P0的值循环左移后,即比如原来P0为1111 1110,循环左移后为1111 1101,再赋值给P0,你如果给P0一开始设置的初值为0x00,那当然不论怎么循环都是0x00,没有流水灯的效果。
第2个回答  2014-03-26
要看二进制的数据0xfe = 1111 1110,对应到P0口的每个引脚,就是0亮,其他灭,0x01= 0000 0001