蓝桥杯51单片机花样流水灯与独立按键实例分析【单片机开发初学者通俗易懂】

文章目录

    • 一、流水灯控制
        • 1、点亮流水灯
        • 2、循环显示流水灯
    • 二、按键控制流水灯
        • 1、独立按键
        • 2、按键消抖
        • 3、按键控制流水灯【基础版】
        • 4、按键控制流水灯【实时版】

一、流水灯控制

1、点亮流水灯

首先看一段点亮流水灯的代码:

#include 
void main()
{
	while(1)
		P1= 0xFE;
}

这就是点亮流水灯中最后一个灯的代码,超技简单。就在main函数中写个循环(甚至while循环都可以省略,单片机会自动循环main函数),再给P1赋值。

其实P1就是控制流水灯的端口,在头文件中已经包括了这个端口变量,因此可以直接给它赋值。

而0xFE代表的就是十六进制,转化成二级制就是1111 1110,而此代码表示的是亮最后一个灯,因此0也就是代表亮的那个灯,想让哪个灯亮,就给哪个灯赋值。(注意:0是低电平有效的单片机,若单片机的流水灯模块是高电平有效,那想让它亮就是给个1)

甚至可以将0xFE改成:P1=1111 1110;

2、循环显示流水灯

#include 
#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 
#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 
#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();
			}
		}
	}
	
}

以上,就是独立按键与流水灯的控制,已经它俩相互结合的使用方法。

你可能感兴趣的:(嵌入式开发技术,单片机,编程语言,嵌入式,程序人生,c语言)