单片机流水灯的三种实现方式(由上至下,再重下到上)
原理图
一般使用单片机的P1口 输出,不需要加上拉电阻:
由原理图可以看出这里采用低电平输出。
一、采用数组方式进行字节定义,最好理解的方式
#include<reg51.h>
#define uchar unsigned char
uchar tab[] ={
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//预设好每个灯亮时的代码
void delay() //延时
{
uchar a,b,c;
for(c=5;c>0;c--)
for(b=116;b>0;b--)
for(a=214;a>0;a--);
}
void main()
{
uchar i;
while(1){
for(i = 0;i<7;i++)
{
P1 = tab[i];
delay();
}
for(i = 7;i>0;i--)
{
P1 = tab[i];
delay();
}
}
}
二,用移位运算符号“<<”“>>”来实现,注意移位运算的特点,左移时高位丢弃,低位补0,反之;
#include<reg51.h>
#define uchar unsigned char
void delay() //延时
{
uchar a,b,c;
for(c=5;c>0;c--)
for(b=116;b>0;b--)
for(a=214;a>0;a--);
}
void main()
{
uchar i,temp;
while(1)
{
temp = 0x01; //0000 0001
for(i =0;i<8;i++)
{
P1=~temp;
delay();
temp=temp<<1;
}
temp = 0x80; //1000 0000
for(i =0;i<8;i++)
{
P1=~temp;
delay();
temp=temp>>1;
}
}
}
三、还有一种使用循环位移函数(最简单的方式),需要添加库函数<intrins.h> _crol_
循环左移,_cror_
循环右移
#include<reg51.h>
#include<intrins.h>
delay()
{
unsigned char a,b,c;
for(c=167;c>0;c--)
for(b=171;b>0;b--)
for(a=16;a>0;a--);
return 0;
}
void main()
{
unsigned char temp;
unsigned i =6;
temp=0xFE;
P1 = temp;
delay();
while(1){
for(i=7;i--;i>0)
{
temp =_crol_(temp,1);
P1= temp;
delay();
}
for(i=7;i--;i>0)
{
temp =_cror_(temp,1);
P1= temp;
delay();
}
}
}
水平有限 欢迎指正