栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

按键是个心态,按不起来时候都想把地球都按爆(单片机蓝桥杯学习历程3)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

按键是个心态,按不起来时候都想把地球都按爆(单片机蓝桥杯学习历程3)

单片机的学习只是个心态。底层的东西,难起来那确实不是人学的,所以我们学他干什么,了解最基本的易懂的,知道代码怎么敲,硬件怎么排出来,把一个东西学到百分之八十需要精力,但是总共东西的百分之八十的学会,你就是行业大佬了。

按键只是个内容,单片机也只是个心态。底层是个迷宫,像女人的心,何必把自己陷的那么深?

今天一起学按键。 按键可以分成三种:短按,长按,还有混合到一起的(比如手机截图时候音量键和锁屏键一起按)。第三种不说,单片机也暂时用不到,前两种从硬件画图到软件一行一行细分,听我给您叙述。

按键的硬件:

这个是按键的原理图,左下角的玩意叫跳线帽,可以理解成三个引脚,用法就是12连一起,或者23连一起。12连一起时组成了矩阵按键,23连一起时只是单个按键有效。

硬件原理:
我们要知道计算机就是傻不拉几的速度超快的变态,他没什么超能力,就是计算速度非常快。就是右边p30到P44的引脚,cpu可以非常快速的判断从导线里传输的信号是0还是1。根据判断出来的结果进行和其他引脚信号对比,就能判断出来相应的代表的信息。这就是所谓的按键扫描。
我开始听到扫描还以为什么高科技玩意,结果就是个这????

判断独立按键哪个被按下
当组成简单的独立按键时(23连一起),左边3接地,cpu疯狂判断右边的P30到P33是不是0,因为当比如S7按下时,因为左边接地可以看成0,所以按下时接通,P30也为0,这时候就可以判断出S7是否被按下啦。
接着我们看代码,
if(P30 == 0) Key_Value = 7;
这个就是判断S7有没有被按下的代码了,就这很简单哥们,别把这玩意想的那抹高大上,毕竟现在科技那么发达,这都是快被淘汰的玩意了。

独立按键代码整合到一起就是

```c
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;
}

判断矩阵按键判断哪个被按下
当12连在一起时就是矩阵按键。我们让CPU给P44一个值0吧,其余P42,P35,p34(这四个判断出了那一列)都给1吧,当判断出P30也为0时候,我们就可以确定这两个端口连载到了一起,就是S7被按下。(P30到P33这四个端口决定了哪一列)
所以矩阵按键代码就是

unsigned char Key_Read(void)
{
	unsigned int Key_New;
	unsigned char Key_Value;
	//产生数据
	P44 = 0;P42 = 1;P35 = 1;P34 = 1;
	Key_New = P3 & 0x0F;  // 0f:1111 0000
	
	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);
	//key_new只是一个中间体,用来存放数据的
	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_Value = Key_Read();
	Key_Down = Key_Value & (Key_Old ^ Key_Value);//下降沿,按得哪个按键,这个值就是几
	Key_Old = Key_Value;//检测电平,一直按着一直等于一个数

三行代码看出来短按还是长按,这个看不懂的话可以背下来,因为我们要记住的是前边怎么判断,这个不是重点,但也更好理解记忆


总体代码

你可以拿去用,适合懒人,因为我也是


#include "stc15f2k60s2.h"

void Key_proc(void);

unsigned char Key_value;
unsigned char Key_old,Key_down;



//--矩阵键盘   判断按下的哪个键
unsigned char Key_Read(void)
{
	unsigned int Key_New;
	unsigned char Key_Value;
	
	P44 = 0;P42 = 1;P35 = 1;P34 = 1;
	Key_New = P3 & 0x0F;  // 0f:1111 0000
	
	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;
	
}

void Led_Disp(unsigned char ucLed)//led部分函数
{

	P0 = (~ucLed);
	P2 = P2 & 0x1F | 0x80;//  Y4C为1
	P2 &= 0x1F;  //关闭P2端口就是Y4C关闭为0  

}




void Cls_Peripheral(void)//关闭外设
{
	
	P0 = 0xFF;
	P2 = P2 & 0x1F | 0x80;//led 1F:1000 0000
	P2 &= 0x1F;
	
	P0 = 0x00;
	P2 = P2 & 0x1F | 0xA0;//beep  A0:1010 0000  1f: 1111 1000
	P2 &= 0x1F; //后三位清0

}
void main (void)
{
	Cls_Peripheral();
	
	while(1)
	{ 
		Key_proc();
	}
}

void Key_proc(void)
{
	Key_value=Key_Read();
	Key_down=Key_value & (Key_old ^Key_value);
	Key_old = Key_value;
	
 switch(Key_down)
 {
	 case 15:Led_Disp(0x0f);break;//如果按下S15,那末前四个灯亮
	 
 }
	
}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/767242.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号