蓝桥杯备战——2.矩阵键盘

1.分析原理图

在这里插入图片描述
由上图可以看到若J5跳线帽接地,就S4~S7就可以当做四路独立按键,若接到P44,则就是4*4的矩阵键盘。

2.独立按键处理

相对传统的按键延时消抖方案,这里我采用更高效,更经典,更偏向产品级应用的状态机方案:

u8 Trg=0,Cont=0;
//独立按键
void Key_Scan()
{
	//状态机
	u8 ReadData = P3^0XFF;
	Trg = ReadData&(ReadData^Cont);	//记录短按键值
	Cont = ReadData;	//记录长按键值
	Key_Read();	//判断哪个按键按下
}
void Key_Read()
{
	if(Trg == 0x08){ //S4短按
		//按键任务区
		Set_Leds(1,1);//打开LED1
	}
	else if(Trg == 0x04){ //S5短按
		Set_Leds(2,1);	//打开LED2
	}
	else if(Trg == 0x02){	//S6短按
		Set_Leds(3,1);
	}
	else if(Trg == 0x01){ //S7短按
		Set_Leds(4,1);
	}
	else;
}

在应用的时候我们只需要知道三个状态对应的按键情况就行:
1.按键未按下或者松手时:Trg=0,Cont=0
2.按键刚按下,且Key_Scan只运行一遍时:Trg=键值,Cont=键值
3.按键持续按下状态时:Trg=0,Cont=键值
然后我们就能根据这三个状态来判断长按,短按,未按下,以及后续扩展双击等功能

扩展长按功能:由于按键持续按下状态Cont=键值,且Trg=0;因此我们可以在此条件基础上增加一个计时变量,当变量大于一定值则判定为长按。

u8 Trg=0,Cont=0,Num=0;
bit LONG_CLICKED=0;
//独立按键
void Key_Scan()	//20ms扫描一次
{
	//状态机
	u8 ReadData = P3^0XFF;
	Trg = ReadData&(ReadData^Cont);	//记录短按键值
	Cont = ReadData;	//记录长按键值
	
	if((Trg==0)&&(Cont!=0))	//记录按下时长
  	{
		if(++Num==100) //满足长按2S
    	{
			LONG_CLICKED=1;
			Num++;
    	}
  	}
	if((Trg==0)&&(Cont==0)) //松手或者未按下
	{
		//此处可扩展双击
		Num=0;
	}
	
	Key_Read();	//判断哪个按键按下
}

void Key_Read()
{
	if(Trg == 0x08){ //S4短按
		//按键任务区
		Set_Leds(1,1);
	}
	else if(Trg == 0x04){ //S5短按
		Set_Leds(2,1);
	}
	else if(Trg == 0x02){	//S6短按
		Set_Leds(3,1);
	}
	else if(Trg == 0x01){ //S7短按
		Set_Leds(4,1);
	}
	else;
	
	if(!LONG_CLICKED) return;
	if(Cont==0x08){ //S4长按
		Set_Leds(1,0);
	}
	else if(Cont==0x04){ //S5长按
		Set_Leds(2,0);
	}
	else if(Cont==0x02){	//S6长按
		Set_Leds(3,0);
	}
	else if(Cont==0x01){ //S7长按
		Set_Leds(4,0);
	}
	else;
	LONG_CLICKED=0;
}

扩展双击功能:双击功能则是在松手状态下去判断长按功能的计时变量,小于一定值则可认为按键短按一次,此时再创建一个计时变量,当此计时变量大于一定值而小于一定值时按键再次按下则可判定为双击。好像往年都未曾考查过此功能,所以我就不写了,有兴趣的同学可以试试。

3.矩阵键盘

矩阵键盘的处理方案同独立按键,我就不细讲了,理解记忆即可

u8 Trg=0,Cont=0,Num=0;
bit LONG_CLICKED=0;
//矩阵键盘
void Keys_Scan()
{
	//状态机
	u8 ReadData,ColumnData;
	P3 = 0XF0;  //行低列高
	P42 = 1;
	P44 = 1;
	P36 = P42;	//IO映射,便于数据操作
	P37 = P44;
	ColumnData = P3; //暂存列数据
	P3 = 0X0F;	//行高列低
	P42 = 0;
	P44 = 0;
	ReadData=(P3 | ColumnData)^0XFF;
	Trg = ReadData&(ReadData^Cont);	//记录短按键值
	Cont = ReadData;	//记录长按键值
	
	if((Trg==0)&&(Cont!=0))	//记录按下时长
  	{
		if(++Num==100) //满足长按2S
    	{
			LONG_CLICKED=1;
			Num++;
    	}
  	}
	if((Trg==0)&&(Cont==0)) //松手或者未按下
	{
		//此处可扩展双击
		Num=0;
	}
	
	Keys_Read();	//判断哪个按键按下
}

/****************矩阵键码表******************
S7-0X81  	S11-0X41 	S15-0X21 	S19-0X11   
S6-0X82		S10-0X42 	S14-0X22 	S18-0X12
S5-0X84		S9-0X44 	S13-0X24 	S17-0X14
S4-0X88		S8-0X48 	S12-0X28 	S16-0X18 
*******************************************/
void Keys_Read()
{	
	//用到再加,一一列举程序运行慢
	if(Trg == 0x81){ //S7按下
		Set_Leds(1,1);
	}
	else if(Trg == 0x48){	//S8按下
		Set_Leds(2,1);
	}
	else;
	
	if(!LONG_CLICKED) return;
	if(Cont == 0x81){ //S7长按
		Set_Leds(1,0);
	}
	else if(Cont == 0X48){ //S8按下
		Set_Leds(2,0);
	}
	else;
	LONG_CLICKED=0;
}

4.使用示例

#include "main.h"

void System_Init(void);

void Delay20ms()		//@12.000MHz
{
	unsigned char data i, j;

	i = 234;
	j = 115;
	do
	{
		while (--j);
	} while (--i);
}


void main()
{
	System_Init();
	while(1)
	{
		
		Delay20ms();
		//Key_Scan();
		Keys_Scan();
	}
}

void System_Init()//系统上电初始化
{
	//先锁存蜂鸣器,继电器所在573输出低电平,防止上电乱叫
	P25=1;P26=0;P27=1; //74HC138-->Y5=0,else=1-->Y5C=1,else=0
	P0=0X00;	//ULN2003输入经过非门送入达林顿管,低电平有效
	P25=0;P26=0;P27=0;//锁存数据
	
	//关闭所有LED灯
	P25=0;P26=0;P27=1; //74HC138-->Y4=0,else=1-->Y4C=1,else=0
	P0=0XFF;
	P25=0;P26=0;P27=0;//锁存数据
	
}

如果有用到长按功能,20ms运行一次最好是通过定时器去扫描实现,后续笔记中我会提供示例。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/348784.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript DOM之Cookie详解

cookie有的地方习惯使用复数形式的cookies,指的是网站为了识别用户的身份或者进行一些必要数据的缓存而使用的技术,它的数据是存在用户的终端上,也就是在浏览器上的。 一、什么是cookie 随着互联网的不断发展各种基于互联网的服务系统逐渐多…

第139期 做大还是做小-Oracle名称哪些事(20240125)

数据库管理139期 2024-01-25 第139期 做大还是做小-Oracle名称哪些事(20240125)1 问题2 排查3 扩展总结 第139期 做大还是做小-Oracle名称哪些事(20240125) 作者:胖头鱼的鱼缸(尹海文) Oracle A…

【C#】基础巩固

最近写代码的时候各种灵感勃发,有了灵感,就该实现了,可是,实现起来有些不流畅,总是有这样,那样的卡壳,总结下来发现了几个问题。 1、C#基础内容不是特别牢靠,理解的不到位&#xff…

2016年认证杯SPSSPRO杯数学建模B题(第一阶段)低分辨率下看世界全过程文档及程序

2016年认证杯SPSSPRO杯数学建模 B题 低分辨率下看世界 原题再现: 数码摄像技术被广泛使用于多种场合中。有时由于客观条件的限制,拍摄设备只能在较低的分辨率下成像。为简单起见,我们只考虑单色成像。假设成像的分辨率为 32 64&#xff0c…

架构师之路(十四)计算机网络(网络层)

前置知识(了解):计算机基础。 作为架构师,我们所设计的系统很少为单机系统,因此有必要了解计算机和计算机之间是怎么联系的。局域网的集群和混合云的网络有啥区别。系统交互的时候网络会存在什么瓶颈。 网络层提供主机…

Dlearning

Deep Learning Basic 神经网络: #mermaid-svg-rR22a8Udy5SxGOoP {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-rR22a8Udy5SxGOoP .error-icon{fill:#552222;}#mermaid-svg-rR22a8Udy5SxGOoP .error-t…

线扫相机使用教程

一.线扫相机的采集原理 在现有的工业 2D 相机中,主要有两种类型的相机,面阵相机和线扫相机。这两种相机有其 各自的特点。 面阵相机:主要用于采集较小尺寸的产品,特别是长度方向较小的产品。其采集原理是通过 单次或多次曝光&…

Atlassian 停服 Bitbucket?三步快速迁移至极狐GitLab

之前的文章Jira 母公司全面停服 Server 产品,用户如何迁移至极狐GitLab提到了 Atlassian 将在 2 月 15 日以后停止对 Server 端产品的服务支持,此后用户将无法像之前一样继续使用 Jira、Bitbucket、Bamboo、Confluence 这些产品了。如果用户想要继续使用…

蓝牙----蓝牙消息传输_GATT服务发现

蓝牙消息传输_GATT服务发现 1.主机和从机GATT服务的发现2.通知的使用 1.主机和从机GATT服务的发现 GATT服务的发现由主机执行,一共三个阶段  1.处理交换 MTU 请求和响应,启动对 Simple Service 服务的发现。 if (discState BLE_DISC_STATE_MTU){// MT…

四川思维跳动商务信息咨询有限公司专注抖音电商服务

在当今这个数字化时代,电商服务已经成为企业发展的重要驱动力。四川思维跳动商务信息咨询有限公司作为一家专注于抖音电商服务的公司,以其卓越的服务质量和创新能力,成为了行业的领航者。 四川思维跳动商务信息咨询有限公司自成立以来&#x…

pyqt5+vscode 配置坑笔记

1.conda activate XX 时失败 这样出来的python版本也是错的(总是全局版本) 无法加载文件 D:\Documents\WindowsPowerShell\profile.ps1,因为在此系统上禁止运行脚本 系统设置允许执行脚本解决 无法加载文件WindowsPowerShell\profile.ps1…

leetcode hot100组合

在本题中,是要求返回[1,n]这个数组的长度为k的组合。涉及到排列、组合、棋盘、分割等问题的时候,要考虑利用回溯来进行解决。 回溯和递归类似,也分为三步进行分析 确定递归函数的返回值和参数:一般来说返回值都是void&#xff0c…

互斥锁/读写锁(Linux)

一、互斥锁 临界资源概念: 不能同时访问的资源,比如写文件,只能由一个线程写,同时写会写乱。 比如外设打印机,打印的时候只能由一个程序使用。 外设基本上都是不能共享的资源。 生活中比如卫生间,同一…

微软人工智能办公AI工具 Copilot Pro 11项 Copilot 功能

Copilot(曾用名 Bing Chat 和 Bing Chat Enterprise)在此期间成为了许多用户的日常AI伴侣,并在正式发布后将继续为用户提供AI驱动的网络聊天体验。 微软Copilot官方网址链接:Microsoft Copilot: 你的日常 AI 助手 Copilot详情&am…

香港web3盛会:Unisat确认参加Big Demo Day项目路演

本次“Big Demo Day”将于1月31日举办第十期,是由Zeepr 总冠名,Central Research、Techub News联合主办、数码港、852web3支持举行的大型线下活动。Big Demo Day集结了Web2和Web3行业精英聚焦香港市场。 Unisat确认参加 Big Demo Day 线下活动&#xff0…

14.java集合

文章目录 概念Collection 接口概念示例 Iterator 迭代器基本操作:并发修改异常增强循环遍历数组:遍历集合:遍历字符串:限制 list接口ListIteratorArrayList创建 ArrayList:添加元素:获取元素:修…

Java JVM类加载阶段 双亲委派模式

类加载阶段 加载 将类的字节码载入方法区中,内部采用 C 的 instanceKlass 描述 java 类,它的重要 field 有: _java_mirror 即 java 的类镜像,例如对 String 来说,就是 String.class,作用是把 klass 暴露…

WWDG喂狗

3F 是0111111 40 是1000000 0X7F 127 0X5F 95 127-9532 注意:中断是在0x40,在0x40喂狗则程序不会复位 在0x5F之前喂狗会复位,减小到63以下也会复位 在0x5F与0x3F之间喂狗会继续执行,不会复位 WWDG_HandleTypeDef WWDG_Handler; //窗口看门狗句柄//初始化窗口看门狗…

2024 高级前端面试题之 HTML 「精选篇」

该内容主要整理关于 HTML 的相关面试题,其他内容面试题请移步至 「最新最全的前端面试题集锦」 查看。 HTML模块精选篇 1. 如何理解HTML语义化2. H5的新特性有哪些3. 说一下 HTML5 Drag API4. iframe有那些缺点5. 如何实现浏览器内多个标签页之间的通信6. 简述一下s…

EF core连接数据库的前期完整配置流程-开发环境搭建

EF core连接数据库完整流程-开发环境搭建 前置:.net6 core webapi不勾选任何配置 声明:这里是以两个配置类来做的,一个T_Books表,一个T_Person表 Book:创建属性及类型 BookConfig:对创建的进行属性数据表…