本帖最后由 红色钢铁 于 2012-2-7 16:11 编辑
我现在正在跟着郭天祥的那个视频教程学51,刚开始。
第二课的课后练习题的第6道让我颇费周章:
间隔300ms第一次一个管亮流动一次,第二次两个管亮流动,依次到8个管亮,然后重复整个过程。
比较笨但也肯定有效的办法就是把所有的状态一个一个排列好,顺序出现即可。但我觉得这太没有技术含量,非要搞成循环的——练手嘛,应该故意给自己出点难题。
作为菜鸟,于是乎就搞了好久……
不过总算是搞出来了,很得意、很有成就感啊!!
我理解的功能应该是这样的,最后做出来的也是这种效果(P1口,低电平灯亮,打钩的是高电平。自己做的动画,够蛋疼吧……):
代码如下:
#include<reg52cus.h>
void delay(uint);
sbit p0=P1^0; //因为需要在P1口末尾添0(加点一盏灯),需要单独对这一位进行操作
void main()
{
while(1)
{
uchar cont,temp,p,q;
P1=0xfe; //对P1口进行初始化
for(cont=0;cont<8;cont++) //从0循环到7,共8个循环,分别对应点亮1盏灯到点亮8盏灯
{
temp=cont; //temp是控制键值,控制要不要在P1口的D0位再添一盏灯
p=1; //p初始化。p是一个用于移位操作的中间变量。的作用是:利用左移位+取反赋值给P1实现流水灯动作。
P1=0xfe; //P1"八次循环"内初始化
q=0; //q的作用是保存P1口先前的值,与P1口当前的值作比较,实现对P1^7由0到1跳转的判断
while(!((q==0x7f)&&(P1==0xff))) //当上面所说的跳转发生,一个循环结束。开始进行加一盏灯的流水灯循环。
{
delay(301); //延时300毫秒
q=P1; //赋值给P1,点灯
p=p<<1; //p左移一位
P1=~p; //p取反然后把赋值给P1实现指定位的点亮
if(temp){p0=0;p=~P1;temp--;}//当cont等于1~7时需要在D0位加灯再流水;当cont==1加1盏,当cont==2连续加2盏,以此类推
}
}
}
}
void delay(uint t)//延时子程序
{
uint x,y;
for(x=t;x>0;x--)
for(y=113;y>0;y--);
}
应该还有地方可以改进,我觉得。欢迎大家指正。 |