找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9729|回复: 0
打印 上一主题 下一主题
收起左侧

五种方法实现流水灯

[复制链接]
跳转到指定楼层
楼主
ID:51090 发表于 2014-9-24 22:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
嗨,大家好,我是宝哥,很高兴您能关注我的文章,作为一名职业的IT男,把自己的所学记录下来并与大家分享是我由来已久的一个想法,于是开通了这个博客,希望对还在迷茫和困惑中的朋友有所帮助。
今天怀着无比激动的心情,我完成了单片机C语言板块第一篇博客的撰写,写的不好希望大家见谅,欢迎大家拍砖,给我提宝贵意见,我一定尽力改进,写的不对的地方也请大家指出,以免误人子弟,总之本人能力有限,希望大家不吝赐教!
本系列博客的撰写我打算采用这样的一个思路:以例子为路线,讲解单片机C程序设计的方法,侧重知识的活学活用,适合于有一定单片机和C语言基础的朋友。
好了,废话少说,开始我今天的主题,今天的主题是五种方法实现流水灯,讲这个的目的不是为了让你会五种方法而可以在小伙伴中炫耀,而是想告诉大家一个理念,学习要善于思考,活学活用,解决问题的办法不只有一个。
好了,先上一个电路图:


P0口为例,我连接了8个共阳的led灯,电路很简单,当IO口给低电平时,led点亮。那么实现流水灯的原理是:先点亮第一个led,保持一会,然后熄灭,点亮下一个led,保持,再熄灭,直到第8led点亮,之后熄灭,循环执行这个过程。
其实这个功能的实现很简单,就是循环执行点亮、熄灭的过程。根据上面的电路图,我想到了5个我认为还比较简单的方法(也许是我太自恋了,哈哈),那些位操作和单独的总线操作的方法这里就不提了,实在是很笨的方法。
第一种方法:运用总线操作的方法,但使用了循环操作的方式,大大减少了代码的编写。首先定义一个数组将8个总线数据存到数组中,用循环的方法给IO口赋值,之后延时保持led点亮,然后重新给IO口赋值,实现了led的流水显示,具体请看代码,不再解释:
u_char table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
void main(void)
{
u_char i;
while(1)
{
   for(i=0;i<8;i++)
   {
     P0=table[ i];
     delay();
   }
}
}
第二种方法:运用了“移位”和“按位或”两个操作,还不清楚这两个操作的朋友该回去恶补C语言了。这是实现流水灯最常用的方法之一了,原理是先给IO口赋值(代码中的temp),点亮第一个led,然后将数值左移一位,此时数值低两位变成0,需要将最低位置1,所以又将数值与0x01按位或,循环8次执行这个过程,实现了led的流水显示,具体实现请看代码:
void main(void)
{
u_char i;
while(1)
{
   u_char temp=0xfe;
   for(i=0;i<8;i++)
   {
     P0=temp;
     delay();
     temp=temp<<1;
     temp |= 0x01;
   }
}
}
第三种方法:相对于第二种方法在代码上能简单一点,但是原理同出一辙,原理其一是二进制数左移一位相当于数值乘以2,右移一位相当于数值除以2,原理其二是01按位或相当于01。掌握了这两个原理,那好的,方法二的程序顺理成章的可以改成下面的这个程序,代码如下:
void main(void)
{
u_char i;
while(1)
{
   u_char temp=0xfe;
   for(i=0;i<8;i++)
   {
     P0=temp;
     delay();
     temp=temp*2+1;
   }
}
}
第四种方法:也是运用了移位的方法,但反其道而行之,使得代码得到了一定简化。这种方法数值temp给的是0x01,对它进行移位操作,如果直接将其赋值给IO口,那么实现的效果是流水熄灭,这个效果很好,想想如果我对temp这个值取了一下反,再赋值给IO口,实现的是什么效果呢?请看代码:
void main(void)
{
u_char i;
while(1)
{
   u_char temp=0x01;
   for(i=0;i<8;i++)
   {
    P0=~temp;
    delay();
    temp=temp<<1;
   }
}
}
第五种方法:我认为很简单,调用系统库函数的循环移位函数实现,需要注意的是在预编译时需要包含头文件。循环移位的好处是可以保持各位数值间的关系不变,因此整个过程只需要一个操作即可。这种方法虽然简单,但是使用面不是很广,因为我们常常记不住系统都有哪些库函数可以用,所以对这种方法做以了解即可,程序代码如下:
#include<reg52.h>
#include"intrins.h"
#define u_char unsigned char
#define u_int unsigned int
void delay(void);
void main(void)
{
u_char temp=0xfe;
while(1)
{
   P0=temp;
   delay();
   temp=_crol_(temp,1);
}
}
讲到这里,五种方法实现流水灯已经给大家介绍完了,相信大家已经可以轻松自如的运用上面的某一种方法实现流水灯了。其实单片机学起来,就是这么简单,只要你喜欢,肯努力,一切so easy
最后提一句,学习很重要的一点是举一反三,举个例子,现在你可以实现一个往返的流水灯了吗?如果可以,很好,恭喜你已经理解了!那么我们继续加油!好了今天就到这里吧,再次欢迎大家拍砖,多提宝贵意见,感谢您的支持。
欢迎转载,转载请保留以下信息:
文章出自:宝哥的博客
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表