蓝桥杯单片机按键模块化编程

蓝桥杯单片机按键模块化编程,第1张

按键 一.按键电路

1.矩阵按键

将J5的KBD接在一起,使用矩阵按键。就是1.2接在一起。

现在8个I/O口控制16个按键。P34,P35,P42,P44控制四列,单片机通过这四个I/O输出高低电平。P30,P31,P32,P33控制四行,单片机通过这四个I/O接收高低电平。通过这种方式,单片机进行按键扫描。

具体来说,就是先给P44一个低电平,P34,P35,P42一个高电平,这个时候看P30,P31,P32,P33,如果P30给单片机一个低电平,那么表示S7按下,以此类推。

总结来说,按键扫描就是给a列低电平,其实三列高电平,如果b行是低电平,就是a列b行的按键被按下。

2.独立按键

将J5的BTN接在一起,使用独立按键,就是2.3接在一起。

独立按键由四个一列的按键组成。

独立按键由于2.3接在一起,默认这列是低电平,然后看那行低电平,就是对应的按键。

总结来说,独立按键扫描就是那行低电平,就是那行对应的按键被按下。

二.按键模块化编程 1.按键模块化编程原理

由于矩阵按键和独立按键扫描原理差不多,就不分开编程了。

蓝桥杯单片机开发板中,按键是一个特殊的外设,一般通过它将其他的外设连接起来。例如:按下S7,LED全亮。

所以说,在按键编程时,不仅要编写按键的模块化代码,还要有一个模板来方便各种外设调用。

2.按键模块化编程代码 (1)按键扫描部分
//key.c头文件代码部分
#include "key.h"

//根据考题决定是编写独立按键还是矩阵键盘

//--独立按键
unsigned char Key_Read_BTN(void)//这个独立按键结构简单,代码方便。
{
	unsigned char Key_Value;
	
	if(P30 == 0) Key_Value = 7;
	else 	if(P31 == 0) Key_Value = 6;
	else 	if(P32 == 0) Key_Value = 5;
	else 	if(P33 == 0) Key_Value = 4;
	else Key_Value = 0;

	return Key_Value;
}

//--矩阵键盘
unsigned char Key_Read(void)/*这个思路是先扫描一列,然后接收P3的低四位,
P3 & 0X0F就是将P3的高四位清空,低四位保持不变。然后让这个低四位左移,而低
四位可以代表那一行的按键按下。在keil中,unsigned int是16位变量,通过不断
的左移,这个变量前四位是扫描第1列时P3的后四位,以此类推。这个变量就储存着
按下的按键位置。*/
    
{
	unsigned int Key_New;
	unsigned char Key_Value;
	
	P44 = 0;P42 = 1;P35 = 1;P34 = 1;
	Key_New = P3 & 0X0F;
	
	P44 = 1;P42 = 0;P35 = 1;P34 = 1;
	Key_New = (Key_New<<4)|(P3 & 0X0F);
	
	P44 = 1;P42 = 1;P35 = 0;P34 = 1;
	Key_New = (Key_New<<4)|(P3 & 0X0F);
	
	P44 = 1;P42 = 1;P35 = 1;P34 = 0;
	Key_New = (Key_New<<4)|(P3 & 0X0F);
	
	switch(~Key_New)
	{
		case 0x8000: Key_Value = 4; break;
		case 0x4000: Key_Value = 5; break;	
		case 0x2000: Key_Value = 6; break;	
		case 0x1000: Key_Value = 7; break;	
	
		case 0x0800: Key_Value = 8; break;
		case 0x0400: Key_Value = 9; break;	
		case 0x0200: Key_Value = 10; break;	
		case 0x0100: Key_Value = 11; break;	

		case 0x0080: Key_Value = 12; break;
		case 0x0040: Key_Value = 13; break;	
		case 0x0020: Key_Value = 14; break;	
		case 0x0010: Key_Value = 15; break;			
	
		case 0x0008: Key_Value = 16; break;
		case 0x0004: Key_Value = 17; break;	
		case 0x0002: Key_Value = 18; break;	
		case 0x0001: Key_Value = 19; break;			
		default :  Key_Value = 0;
	}
	
	return Key_Value;
	
}
//key.h头文件代码部分
#include "STC15F2K60S2.H"

unsigned char Key_Read_BTN(void);//独立按键
unsigned char Key_Read(void);//矩阵键盘

(2)按键消抖

通过上面的代码以及注释,我们编写了一个只要按下s几按键,key—down就是多少的代码,但是实际上并非如此。通常的按键所用开关为机械d性开关,当按键按下、抬起时,电平短时间内会发生几次跳变,按键在闭合及断开的瞬间均伴随有一连串的抖动。

抖动很有可能带来一次按键按下,结果单片机执行多次指令,所以我们要做消抖的工作。常用的是通过延时函数进行消抖,不过效果不太好,还会造成性能浪费。蓝桥杯官方采用”三行代码“进行按键消抖。

	//三行代码
	Key_Value = Key_Read();
	Key_Down = Key_Value & (Key_Old ^ Key_Value);//下降沿,按得哪个按键,这个值就是几 ^是异或符号,当两个数异或时,会把这两个数按位异或,例如 7^8 = 00000111 ^ 00001000 = 00001111 = 15
	Key_Old = Key_Value;//检测电平,一直按着一直等于一个数
  1. 正常情况下按键没有按下,Key_Value = 0,Key_Old = 0 。
  2. 当有按键按下,例如S7,Key_Value = 7,Key_Down = 00000111 & (00000111 ^ 00000000)= 00000111 = 7 Key_Old = 7 。
  3. 当按住按键不动时,Key_Value = 7,Key_Down = 00000111 & (00000111 ^ 00000111)= 00000000 = 0 Key_Old = 7 。
  4. 在按键抬起时,Key_Value = 0,Key_Down = 00000000 & (00000111 ^ 00000000)= 00000000 = 0 Key_Old = 7 。

也就是说,Key_Down 是一个判断下降沿的变量,只有按键处于按下的过程Key_Down 才会被赋值,其他情况下Key_Down 是0 。

三行代码提供消抖的作用,同时三行代码具有很高的灵活性,通过一些变化,就可以实现单击,双击,长按等功能。

同时,在按键扫描的部分,我们需要搭配定时器来进行扫描,可以保证按键响应及时,这一部分在定时器部分在仔细讲解。
wn 才会被赋值,其他情况下Key_Down 是0 。==

三行代码提供消抖的作用,同时三行代码具有很高的灵活性,通过一些变化,就可以实现单击,双击,长按等功能。

同时,在按键扫描的部分,我们需要搭配定时器来进行扫描,可以保证按键响应及时,这一部分在定时器部分在仔细讲解。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1323479.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-12
下一篇 2022-06-12

发表评论

登录后才能评论

评论列表(0条)

保存