一、流水灯控制
1、点亮流水灯
首先看一段点亮流水灯的代码:
#include <reg52.h>
void main()
{
while(1)
P1= 0xFE;
}
这就是点亮流水灯中最后一个灯的代码,超技简单。就在main函数中写个循环(甚至while循环都可以省略,单片机会自动循环main函数),再给P1赋值。
其实P1就是控制流水灯的端口,在头文件<reg52.h>中已经包括了这个端口变量,因此可以直接给它赋值。
而0xFE代表的就是十六进制,转化成二级制就是1111 1110,而此代码表示的是亮最后一个灯,因此0也就是代表亮的那个灯,想让哪个灯亮,就给哪个灯赋值。(注意:0是低电平有效的单片机,若单片机的流水灯模块是高电平有效,那想让它亮就是给个1)
甚至可以将0xFE改成:P1=1111 1110;
2、循环显示流水灯
#include <reg52.h>
#define uchar unsigned char //8位数据,0~255
#define uint unsigned int //16位数据,0~65535
//流水灯是低电平有效
//一个table数组存放需要给p1赋值的数据
unsigned char table[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
//延时函数,用于控制灯亮灭的快慢
void delay(uint x){
uint i, j; //定义用于遍历的变量
for(i=x; j>0; i--)
for(j=125; j>0; j--) ;
}
int main()
{
while(1)
{ //无限循环流水灯
uint m;
for(m=0; m<8; m++)
{
P1=table[m];
delay(2000);
}
}
}
以上,就是将需要点亮的流水灯装在一个数组里,然后通过for语句循环遍历,再将每个值赋值给P1端口变量,这样流水灯就按照数组里的信号来显示了。
因为数组里装的就是顺序显示的流水灯信号十六进制,因此在单片机上就会顺序显示了。
二、按键控制流水灯
1、独立按键
//定义端口变量
sbit key1= P3^0;
sbit key2= P3^1;
sbit key3= P3^2;
sbit key4= P3^3;
当给这些端口为0时,就表示按键被按下了,因此我们可以通过if(key1==0){ 操作 }
来监测键盘是否被按下。
2、按键消抖
当我们监测键盘是否被按下时,需要判断一下键盘是否被持续按下,或者只轻轻按了一下,这时候我们就需要使用到按键消抖了。当然是通过程序来实现,硬件是已经固话了的,我们无法改变。
if(key1 == 0)
{
delay(Q); //消抖处理
if(key1 == 0)
{
操作
}
}
原理就是延时一下,再进行判断按键是否被按下,也就是两个 if 语句。
3、按键控制流水灯【基础版】
结合前文学习的流水灯控制,就可以做出按某个按键,然后流水灯执行某种花样变化。
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define Q 35000 //间断时长控制
//定义端口变量
sbit key1= P3^0;
sbit key2= P3^1;
sbit key3= P3^2;
sbit key4= P3^3;
//延时函数
void delay(uint t)
{
while(t)
t--;
}
//1、一个按键控制两个灯,不灭
void Two_on()
{
if(key1 == 0)
P1= 0x7e;
else if(key2 == 0)
P1= 0xbd;
else if(key3 == 0)
P1= 0xdb;
else if(key4 == 0)
P1= 0xe7;
}
//2、一个按键控制两个灯,松开就灭
void Two_off()
{
if(key1 == 0)
P1= 0x7e;
else if(key2 == 0)
P1= 0xbd;
else if(key3 == 0)
P1= 0xdb;
else if(key4 == 0)
P1= 0xe7;
else
P1= 0xff;
}
//3、向左依次滑动
void Left()
{
uchar led[]= {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
uint i;
for(i=0; i<=sizeof(led); i++)
{
if(key1 == 0)
{
delay(Q); //消抖处理
if(key1 == 0)
P1= led[i];
else
P1= 0xff;
}
}
}
//4、向右依次滑动
void Right()
{
uchar led[]= {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe};
uint i;
for(i=0; i<=sizeof(led); i++)
{
if(key4 == 0)
{
delay(Q); //消抖处理
if(key4 == 0)
P1= led[i];
else
P1= 0xff;
}
}
}
int main()
{
//Two_on();
//Two_off();
Left();
Right();
}
4、按键控制流水灯【实时版】
该版可以实现按一下按键,流水灯动一下,多按几下,就多动几下。
#include <reg52.h>
#define uint unsigned int
#define Q 15000
//定义端口变量
sbit key1= P3^0;
sbit key2= P3^1;
sbit key3= P3^2;
sbit key4= P3^3;
//延时函数
void delay(uint t)
{
while(t)
t--;
}
//S2向左堆积
void Left_add()
{
if(P1 == 0x00)
P1= 0x7f;
else
P1 >>= 1;
}
//S3向左减少堆积
void Left_reduce()
{
if(P1 == 0x00)
P1= 0xff;
else
P1 |= (P1<<1);
//右移之后再左移无法还原,因此移位之后需要再和原来的P1进行“或运算”一下
}
//S4向右减少堆积
void Right_reduce()
{
if(P1 == 0x00)
P1= 0xff;
else
P1 |= (P1>>1);
//左移之后再右移无法还原,因此移位之后要和P1进行“或运算”
}
//S5向右堆积
void Right_add()
{
if(P1 == 0x00)
P1= 0xfe;
else
P1 <<= 1;
}
int main()
{
P1= 0xff;
while(1)
{
if(key1 == 0)
{
delay(Q); //消抖处理
if(key1 == 0)
Left_add();
}
if(key2 == 0)
{
delay(Q);
if(key2 == 0)
{
Left_reduce();
}
}
if(key3 == 0)
{
delay(Q);
if(key3 == 0)
{
Right_reduce();
}
}
if(key4 == 0)
{
delay(Q);
if(key4 == 0)
{
Right_add();
}
}
}
}
以上,就是独立按键与流水灯的控制,已经它俩相互结合的使用方法。