【蓝桥杯单片机入门记录】独立按键

目录

一、键盘、微动开关概述

二、按键工作原理

(1)按键构成

(2)(蓝桥杯开发板)独立按键电路图(非实际,参考理解)

(3)独立按键工作原理

三、单片机I/O口-输入

四、按键例程

(0)开发板设置

(1)例程1:按键控制LED点亮或熄灭(本例以按下S7按键打开L1灯,按下S6按键打开L2灯)

(2)例程2:按键控制LED点亮或者熄灭。本例以按下S7按键打开L1灯,按下S6按键打开L2灯按下s5按键打开L5灯,按下S6按键关闭L5灯为例。

(3)例程3:按键控制流水灯移位(一)。本例以S7按键每按下一次LED向右移动1位。 注:多次检测此程序,观察此程序存在的问题

(4)例程4:按键控制流水灯移位(二)。本例以S7按键每按下一次LED向右移动1位 注:此程序已加入按键消抖、LED效果为按键按下执行,

(5)例程5:按键控制流水灯移位(三)。本例以S7按键每按下一次LED向右移动1位 注:此程序已加入按键消抖、LED效果为按键松开执行,


一、键盘、微动开关概述

  • 键盘分编码键盘和非编码键盘。键盘上闭合键的识别由专用的硬件编码器实现,并产生键编码号或键值的称为编码键盘,如计算机键盘;
  • 而靠软件编程来识别的称为非编码键盘;
  • 在单片机组成的各种系统中,用的最多的是非编码键盘。也有用到编码键盘的。
  • 非编码键盘有分为:独立键盘和行列式(又称为矩阵式)键盘。

二、按键工作原理

(1)按键构成

微动开关是具有微小接点间隔和快动机构,用规定的行程和规定的力进行开关动作的接点机构用外壳覆盖,其外部有驱动杆的一种开关,因为其开关的触点间距比较小,故名微动开关,又叫灵敏开关、触动开关、轻触开关。

(2)(蓝桥杯开发板)独立按键电路图(非实际,参考理解)



(3)独立按键工作原理

按键在闭合和断开时,触点回存在抖动现象;涉及后续(软件)消抖

三、单片机I/O口-输入

四、按键例程

(0)开发板设置

  • J13跳线帽:IO模式
  • J5跳线帽:BIN模式(独立按键)

(1)例程1:按键控制LED点亮或熄灭(本例以按下S7按键打开L1灯,按下S6按键打开L2灯)

//头文件声明区域
#include <STC15F2K60S2.H>

//变量声明区域


//函数定义区域


//程序主体
void main()
{
	P2 = 0XA0;
	P0 = 0X00;
	P2 = 0X80;
	P0 = 0XFF;
	
	while(1)
	{
		if(P30 == 0) P00 = 0;
		if(P31 == 0) P01 = 0;
		
		
		
	}
	
	
}

(2)例程2:按键控制LED点亮或者熄灭。本例以按下S7按键打开L1灯,按下S6按键打开L2灯按下s5按键打开L5灯,按下S6按键关闭L5灯为例。

//头文件声明区域
#include <STC15F2K60S2.H>

//变量声明区域
sbit S4 = P3^3;
sbit S5 = P3^2;
sbit L5 = P0^4;

//函数定义区域


//程序主体
void main()
{
	P2 = 0XA0;
	P0 = 0X00;
	P2 = 0X80;
	P0 = 0XFF;
	
	while(1)
	{
		if(P30 == 0) P00 = 0;
		if(P31 == 0) P01 = 0;
		if(S5 == 0) L5 = 0;
		if(S4 == 0) L5 = 1;
		
		
		
	}
	
	
}

(3)例程3:按键控制流水灯移位(一)。本例以S7按键每按下一次LED向右移动1位。 注:多次检测此程序,观察此程序存在的问题

//头文件声明区域
#include <STC15F2K60S2.H>

//变量声明区域
unsigned char LED = 0;
//函数定义区域



//程序主体
void main()
{
	P2 = 0XA0;
	P0 = 0X00;
	P2 = 0X80;
	P0 = 0XFF;
	
	while(1)
	{
		if(P30 == 0)
		{
			P0 = ~(0x01<<LED);
		  LED++;
		  if(LED == 8) LED = 0;
		
			
		}
					

		
		
	}
	
	
}
//存在的问题:按下按键后,由于程序执行的太快,现象不明显

(4)例程4:按键控制流水灯移位(二)。本例以S7按键每按下一次LED向右移动1位 注:此程序已加入按键消抖、LED效果为按键按下执行

//头文件声明区域
#include <STC15F2K60S2.H>

#include<intrins.h>
//变量声明区域
unsigned char LED = 0;
//函数定义区域
void Delay(unsigned int time)		//@11.0592MHz
{
	unsigned char i, j;
 while(time--)
 {
	 	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
 }

}



//程序主体
void main()
{
	P2 = 0XA0;
	P0 = 0X00;
	P2 = 0X80;
	P0 = 0XFF;
	
	while(1)
	{
		if(P30 == 0 )
		{
			Delay(10);//消抖
			
			if(P30 == 0)
			{
				P0 = ~(0x01<<LED);
				LED++;
				if(LED == 8) LED = 0;
				
			}
		while(!P30);//一直在读取P30的状态,程序不会往下进行,知道松开手
		Delay(10);//消抖
		while(!P30);
		
		}
		
		
	}
	
	
}

(5)例程5:按键控制流水灯移位(三)。本例以S7按键每按下一次LED向右移动1位 注:此程序已加入按键消抖、LED效果为按键松开执行

//头文件声明区域
#include <STC15F2K60S2.H>
#include<intrins.h>
//变量声明区域
unsigned char LED = 0;
unsigned char S7_Flag = 0;
//函数定义区域
void Delay(unsigned int time)		//@11.0592MHz
{
	unsigned char i, j;
 while(time--)
 {
	 	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
 }

}



//程序主体
void main()
{
	P2 = 0XA0;
	P0 = 0X00;
	P2 = 0X80;
	P0 = 0XFF;
	
	while(1)
	{
		if(P30 == 0)
		{
			Delay(10);//消抖
			if(P30 == 0)
			{
			S7_Flag = 1;
			}
			while(!P30);
			
		}
		

		
		if(S7_Flag == 1)
		{
			S7_Flag = 0;
			P0 = ~(0x01<<LED);
			LED++;
			if(LED == 8) LED = 0;
			
		}
			
		
	}
	
	
}

(6)例程6:按键控制流水灯移位。本例以S7、S6、s5.、S4按键每按下一次LED向右移动1位。 注:LED移位程序使用第四章例程10。 注:此程序按键采用独立子函数方式编程。

//头文件声明区域
#include <STC15F2K60S2.H>
#include<intrins.h>
//变量声明区域
unsigned char LED = 0;
unsigned char S7_Flag = 0;
//函数定义区域
void Delay(unsigned int time)		//@11.0592MHz
{
	unsigned char i, j;
 while(time--)
 {
	 	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
 }

}
//独立键盘扫描函数
void KeyScan(void)
{
		if(P30 == 0)
		{
			Delay(10);//消抖
			if(P30 == 0)
			{
			S7_Flag = 1;
			}
			while(!P30);
			
		}
			
		else if(P31 == 0)
		{
			Delay(10);//消抖
			if(P31 == 0)
			{
			S7_Flag = 1;
			}
			while(!P31);
			
		}		
		
		else if(P32 == 0)
		{
			Delay(10);//消抖
			if(P32 == 0)
			{
			S7_Flag = 1;
			}
			while(!P32);
			
		}		
		else if(P33 == 0)
		{
			Delay(10);//消抖
			if(P33 == 0)
			{
			S7_Flag = 1;
			}
			while(!P33);
			
		}
	
	
}

//程序主体
void main()
{
	P2 = 0XA0;
	P0 = 0X00;
	P2 = 0X80;
	P0 = 0XFF;
	
	while(1)
	{

		

		KeyScan();
		
		if(S7_Flag == 1)
		{
			S7_Flag = 0;
			P0 = ~(0x01<<LED);
			LED++;
			if(LED == 8) LED = 0;
			
		}
			
		
	}
	
	
}

(7)例程7:按键控制流水灯移位。本例以S7、S6、S5、S4按键分别控制L1,L7亮灭

//头文件声明区域
#include <STC15F2K60S2.H>
#include<intrins.h>
//变量声明区域
unsigned char LED = 0;
unsigned char S7_Flag = 0,S6_Flag = 0,S5_Flag = 0,S4_Flag = 0;
//函数定义区域
void Delay(unsigned int time)		//@11.0592MHz
{
	unsigned char i, j;
 while(time--)
 {
	 	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
 }

}
//独立键盘扫描函数
void KeyScan(void)
{
		if(P30 == 0)
		{
			Delay(10);//消抖
			if(P30 == 0)
			{
			S7_Flag = 1;
			}
			while(!P30);
			
		}
			
		else if(P31 == 0)
		{
			Delay(10);//消抖
			if(P31 == 0)
			{
			S6_Flag = 0;
			}
			while(!P31);
			
		}		
		
		else if(P32 == 0)
		{
			Delay(10);//消抖
			if(P32 == 0)
			{
			S5_Flag = 1;
			}
			while(!P32);
			
		}		
		else if(P33 == 0)
		{
			Delay(10);//消抖
			if(P33 == 0)
			{
			S4_Flag = 1;
			}
			while(!P33);
			
		}
	
	
}


//程序主体
void main()
{
	P2 = 0XA0;
	P0 = 0X00;
	P2 = 0X80;
	P0 = 0XFF;
	
	while(1)
	{

		

		KeyScan();
		
		if(S7_Flag == 1)
		{
			S7_Flag = 0;
			 P00 = 0;
			
		}
		
		if(S6_Flag == 0)
		{
			S6_Flag = 0;
			P00 = 1;
		}
		
		if(S5_Flag == 0)
		{
			S5_Flag = 0;
			P06 = 0;
		}
		
		if(S4_Flag == 1)
		{
			S4_Flag = 0;
			
			P06 = 1;
		}
		
	}
	
	
}

(8)例程8:按键控制流水灯以200ms为间隔自动移位方向。本例以S7按键控制LED自动向左”移位,S6按键控制LED自动向右移位,S5按键控制LED停止循环移位,S4按键关闭所有LED。(注意:此程序存在的问题(按键不灵敏),并思考为什么会存在这样的问题。尽可能解决)

//头文件声明区域
#include <STC15F2K60S2.H>
#include<intrins.h>
//变量声明区域
unsigned char LED = 0;
unsigned char S7_Flag = 0,S6_Flag = 0,S5_Flag = 0,S4_Flag = 0;
unsigned int i = 0;
//函数定义区域
void Delay(unsigned int time)		//@11.0592MHz
{
	unsigned char i, j;
 while(time--)
 {
	 	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
 }

}
//独立键盘扫描函数
void KeyScan(void)
{
		if(P30 == 0)
		{
			Delay(10);//消抖
			if(P30 == 0)
			{
			S7_Flag = 1;
			}
			while(!P30);
			
		}
			
		else if(P31 == 0)
		{
			Delay(10);//消抖
			if(P31 == 0)
			{
			S6_Flag = 0;
			}
			while(!P31);
			
		}		
		
		else if(P32 == 0)
		{
			Delay(10);//消抖
			if(P32 == 0)
			{
			S5_Flag = 1;
			}
			while(!P32);
			
		}		
		else if(P33 == 0)
		{
			Delay(10);//消抖
			if(P33 == 0)
			{
			S4_Flag = 1;
			}
			while(!P33);
			
		}
	
	
}
void Flash_Left(void)
{
	for(i = 0;i < 8;i++)
	{
		
		P0 = ~(0x01<<i);
		Delay(200);
	}
	
}

void Flash_Right(void)
{
	for(i = 0;i < 8;i++)
	{
		
		P0 = ~(0x80>>i);
		Delay(200);
	}
	
}


//程序主体
void main()
{
	P2 = 0XA0;
	P0 = 0X00;
	P2 = 0X80;
	P0 = 0XFF;
	
	while(1)
	{

		

		KeyScan();
		
		if(S7_Flag == 1)
		{
			S7_Flag = 0;
			 Flash_Left();
			
		}
		
		if(S6_Flag == 0)
		{
			S6_Flag = 0;
			Flash_Right();
		}
		
		if(S5_Flag == 0)
		{
			S5_Flag = 0;
		}
		
		if(S4_Flag == 1)
		{
			S4_Flag = 0;
			
			P0 = 0xff;
		}
		
	}
	
	
}
//问题,按键后只亮一个灯,并不是流水灯效果
//解决
//头文件声明区域
#include <STC15F2K60S2.H>
#include<intrins.h>
//变量声明区域
unsigned char LED = 0;
unsigned char S7_Flag = 0,S6_Flag = 0,S5_Flag = 0,S4_Flag = 0;
unsigned char LED_Flag = 0;
unsigned int i = 0;
//函数定义区域
void Delay(unsigned int time)		//@11.0592MHz
{
	unsigned char i, j;
 while(time--)
 {
	 	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
 }

}
//独立键盘扫描函数
void KeyScan(void)
{
		if(P30 == 0)
		{
			Delay(10);//消抖
			if(P30 == 0)
			{
			S7_Flag = 1;
			}
			while(!P30);
			
		}
			
		else if(P31 == 0)
		{
			Delay(10);//消抖
			if(P31 == 0)
			{
			S6_Flag = 0;
			}
			while(!P31);
			
		}		
		
		else if(P32 == 0)
		{
			Delay(10);//消抖
			if(P32 == 0)
			{
			S5_Flag = 1;
			}
			while(!P32);
			
		}		
		else if(P33 == 0)
		{
			Delay(10);//消抖
			if(P33 == 0)
			{
			S4_Flag = 1;
			}
			while(!P33);
			
		}
	
	
}
void Flash_Left(void)
{
	for(i = 0;i < 8;i++)
	{
		
		P0 = ~(0x01<<i);
		Delay(200);
	}
	
}

void Flash_Right(void)
{
	for(i = 0;i < 8;i++)
	{
		
		P0 = ~(0x80>>i);
		Delay(200);
	}
	
}


//程序主体
void main()
{
	P2 = 0XA0;
	P0 = 0X00;
	P2 = 0X80;
	P0 = 0XFF;
	
	while(1)
	{

		

		KeyScan();
		
		if(S7_Flag == 1)
		{
			S7_Flag = 0;
			LED_Flag = 1;
			
		}
		
		if(S6_Flag == 0)
		{
			S6_Flag = 0;
			LED_Flag = 2;
		}
		
		if(S5_Flag == 0)
		{
			S5_Flag = 0;
			LED_Flag = 0;
		}
		
		if(S4_Flag == 1)
		{
			S4_Flag = 0;
			
			P0 = 0xff;
		}
		
		//保证不停地亮
		if(LED_Flag == 1) Flash_Left();
		if(LED_Flag == 2) Flash_Right();
			
		
	}
	
	
}

  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值