51单片机流水灯 单片机 流水灯的问题 C51程序

本人在单片机学习的过程中遇到一个问题 ,源程序如下,但是确不能完全理解下面三条语句的作用;
a=_crol_(a,j);
P1=0xff;
a=a<<1;

另请帮忙分析 ,外层循环和内层循环的作用;
其实我主要是不明白如果实现P0 = a;的循环次数,如何达到题目那种效果的,这个问题困扰了我差不多一周了。不知如何解决,麻烦知道的帮忙解释下,非常感谢;逻辑应该很清晰,就是这个语句实现有些看不明白;最好把for中的语句详细说明下~

题目:间隔300ms第一次一个管亮流动一次,第二次两个管亮流动,依次到8个管亮,然后重复整个过程。

#include<reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void main()
{
uchar a,i,j;
while(1)
{
a=0xfe;
for(j=0;j<8;j++)
{
for(i=0;i<8-j;i++)
{
P1=a;
delay(200);
a=_crol_(a,1);
}
a=_crol_(a,j);
P1=0xff;
a=a<<1;
}
}
}
楼下说的都非常精彩 我自己编写的程序只和源程序差一行 a = _crol_(a, j); 这条语句~ 结果在执行前两次的时候没问题,到执行第三次的时候程序开始差一位程序跑飞了。我一直理解不了这点,别的应该没问题,麻烦帮忙继续解答下。

---------------------------------------------------------------------------------------------

针对楼下问题本人想继续说明 本人在调试的时候
a=_crol_(a,j); //这是我一直想不明白的指令 原因是不加这条指令循环不正常。但是这个怎么配合循环
P1=0xff; //这条指令有无无妨大碍 至少对于我的ME300B开发板是这样
a=a<<1; //这条指令 如果没有上边的a=_crol_(a,j); 执行前两次是正常的 就是 i = 0 和 i=1的时候是正常 ,但是当i= 2往上就不能正常循环了。

对于整个程序的指令 单条拿出来我是明白的 指令执行的逻辑我也很清晰 不明白的就是如何实现当 i > 2也就是从3个LED开始亮 是如何循环上去的
就是不明白a=_crol_(a,j); 这条指令时怎么配合程序执行的~ 为什么把这个a=_crol_(a,j); 删除就出错
我自己编写的程序就是少了a=_crol_(a,j); 这条指令 而直接a = a << 1; 谢谢大家悉心指教~

while(1)
{
a = 0xfe;
for(j=0;j<8;j++) //外循环8次
{
//--------------------------------------------
for(i=0;i<8-j;i++) //内循环8、7、6...0次
{
P1=a; //第一次,只有右边1个发光
delay(200);
a=_crol_(a,1); //左移一位
}
//以上单个LED发光,移位8、7、6...次
//----------------------------------------
a = _crol_(a, j); //左移,第一次,移动0位,以后渐多
//前面的内循环,移位次数逐减,这里逐增,合到一起,仍然是移动8位

P1 = 0xff; //关闭显示
a = a << 1; //左移一位,右边添0,这样,就会有两个发光

} //到前边去循环,显示两个发光;
//再循环,有三个发光;
//……
}
温馨提示:答案为网友推荐,仅供参考
第1个回答  2009-12-07
我想说~程序加一行和不加一行是很大差别的
首先你要明白a = _crol_(a, j); 这条指令时什么意思
a = _crol_(a, j); 只能在头文件intrins.h里调用
意思是向左移j位 例如:a = _crol_(a, 1);就是向左移一位,a = _crol_(a, 2);就是向左移两位,如此类推
如果你需要向右移则需要用a = _cror_(a, j);指令,原理是一样的
首先我看你的程序
a=_crol_(a,j); 你加了这个指令 即代表j随for(j=0;j<8;j++)这个函数控制,里面的j变化a=_crol_(a,j); 这里的j就会变化j是0是,向左移0位,j是1是向左移1位,j是2时向左移动2位
为什么能实现数码管的循环亮?因为a=0xfe; 这指令,a=1111 1110,运用a = _crol_(a, 1);一次a=1111 1101;再用a = _crol_(a, 1); 一次a=1111 1011,这你应该能理解了吧

我在次回答你的问题~
我想说a=_crol_(a,j);是相当于复位的效果
第2个回答  2009-12-06
a=_crol_(a,j);
P1=0xff;
a=a<<1;
第一句是一个定义
第二句是给P1端口送初值8个高电平也就是让你接的灯全亮(或全灭)看你怎么接的
第三句是实现左移一次的功能
你修改初值可以实现不同的效果
差一位就你只用修改初值就行