打印

【菜鸟】写了一个稍复杂点的流水灯程序,欢迎批评指正

[复制链接]
2708|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
红色钢铁|  楼主 | 2012-2-7 16:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 红色钢铁 于 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--);
}


应该还有地方可以改进,我觉得。欢迎大家指正。

相关帖子

沙发
红色钢铁|  楼主 | 2012-2-7 16:21 | 只看该作者
reg52cus.h 是我按照自己的习惯修改过的头文件,把一些常用的宏定义写了进去。

比如

#define uint unsigned int

使用特权

评论回复
板凳
hengdabinlv123| | 2012-2-7 16:54 | 只看该作者
学习了 。

使用特权

评论回复
地板
forgot| | 2012-2-7 17:49 | 只看该作者
首先,p=1;改为p=0x01;更好
“q=P1;                        //赋值给P1,点灯”  你感觉这句注释对吗?

而且你这个程序有个大问题你调试没发现?这个程序应该每次循环的开始都是只有P1^0亮,并不是几个灯一起亮。

你感觉用_crol_左移函数来做不要简单很多吗?

使用特权

评论回复
5
T120130241| | 2012-2-8 17:11 | 只看该作者
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
unsigned i,n,temp;
void delay(uint Z);

void main()
{
        temp=0xfe;
        while(1)
        {
                for(i=0;i<8-n;i++)
                {
                        P1=temp;
                        delay(500);
                        temp=_crol_(temp,1);
                }
                temp=temp<<n+1;
                n=n+1;//记录次数
                if(n==8)
                {
                        n=0;
                        temp=0xfe;
                }
        }
}

void delay(uint Z)
{
        uint X,Y;
        for(X=Z;X>0;X--);
                for(Y=114;Y>0;Y--);
}

使用特权

评论回复
6
红色钢铁|  楼主 | 2012-2-10 13:50 | 只看该作者
首先,p=1;改为p=0x01;更好
“q=P1;                        //赋值给P1,点灯”  你感觉这句注释对吗?
而且你这个程序有个大问题你调试没发现?这个程序应该每次循环的开始都是只有P1^0亮,并不是几个灯一起亮。 ...
forgot 发表于 2012-2-7 17:49

1、菜菜得问一句,为什么“p=0x01”比“p=1”更好?
2、那个注释确实写错了……很明显那句话是想把P1的值传递给q,让q保留先前P1口的值以实现对P1^7的0—>1跳转检测;
3、没有几个灯一起亮啊。我自己编译完下到单片机上试过的,实现了动画所示的功能。不信的话你可以自己试试。用Keil的调试功能就能验证;
4、对,循环左移应该能让程序更简单一下。写的时候没有转过这个弯来。

使用特权

评论回复
7
红色钢铁|  楼主 | 2012-2-10 14:09 | 只看该作者
本帖最后由 红色钢铁 于 2012-2-10 14:19 编辑

T120130241 发表于 2012-2-8 17:11

1、这个程序你编译通过了吗?有两个小错误:
(1)unsigned char i,n,temp; //你漏写了char
(2)
void delay(uint Z)
{
        uint X,Y;
        for(X=Z;X>0;X--) //你多写了一个分号,构不成两层循环嵌套
                for(Y=114;Y>0;Y--);
}
2、修改调试通过后,下载到单片机上,现象明显与我给的动画不同。不是多个灯一起点亮,而是一个一个以“流入”的方式逐次点亮。你和我对功能要求的理解存在不同,我想要实现的功能——如动画所示——比你写的要稍复杂一些。

使用特权

评论回复
8
红色钢铁|  楼主 | 2012-2-10 14:45 | 只看该作者
不。我想了一下,用循环左移实现我所提供的动画中的功能,其实也还是挺麻烦的。不见得比我的方法简洁多少。

使用特权

评论回复
9
sbrgw1130| | 2012-2-10 17:19 | 只看该作者
:lol

使用特权

评论回复
10
拿起书本| | 2012-2-12 00:25 | 只看该作者
利用数组做找过更好

使用特权

评论回复
11
T120130241| | 2012-2-13 17:03 | 只看该作者
兄弟,你提的那个语法错误是存在的,不过我对于本题的意思的理解应该是没有问题的。**最初的意思就是想让一个管循环亮一组,然后是两个管亮循环一组,一直到八个管都亮,有空你可以联系他,呵呵。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

20

主题

105

帖子

0

粉丝