一个51单片机矩阵键盘的扫描,消抖和键号显示程序

2023-10-27

51单片机的按键判断是一项很重要的功能,在蓝桥杯的比赛中必不可少,下面介绍一个稳定性比较好的矩阵键盘程序。

首先介绍一下该矩阵键盘的基本原理:

1.扫描:四条列线(接单片机的P2.4-P2.7口),电平都为1. 四条行线(接P2.0-P2.3口),先使第一条行 线的电平为0,其他行线为高电平,判断是否有按键按下(本程序是通过比较当前状态值和上一时刻状态值进行判断的),如果当前状态值和上一时刻状态值不同,说明按键状态改变,如果状态是从1变为0,则判定为按键按下,于是 ’ 4*行线号+列线号 ’ 就为按下按键的键号。分别扫描四条行线。

2.消抖:采用定时器0中断,每1ms进一次中断,每次进中断都将按键的状态值更新给缓冲值,进一次中断,可以采集到4个按键的状态,每个按键扫描4次,因此共需4*4=16ms(相当于一个延时消抖的时间),之后对按键缓冲值进行判断,如果四次采集的状态量都为0,说明按键按下;四次采集值都为1,说明按键跳起;其他状态均视为按键抖动,不予处理。这样一来,可以很好的提高按键的稳定性。

3.键号显示:当有按键按下时,将数据传给数码管,显示键号。

下图为protues的仿真原理图:
在这里插入图片描述

部分代码不太好理解,建议深入分析一下。

#include <reg52.h>
sbit KEY_IN_1 = P1^3;          //定义四条列线
sbit KEY_IN_2 = P1^2;
sbit KEY_IN_3 = P1^1;
sbit KEY_IN_4 = P1^0;
sbit KEY_OUT_1 = P1^7;			//定义四条行线
sbit KEY_OUT_2 = P1^6;
sbit KEY_OUT_3 = P1^5;
sbit KEY_OUT_4 = P1^4;
unsigned char code ledchar[] = { 0x3f, 0x06, 0x5b, 0x4f, 
								0x66, 0x6d, 0x7d, 0x07, 
								0x7f, 0x6f, 0x77, 0x7c, 
								0x39, 0x5e, 0x79, 0x71 };  //数码管显示字模
unsigned char keysta[4][4] = {  {1, 1, 1, 1}, 
								{1, 1, 1, 1},
							    {1, 1, 1, 1}, 
 								{1, 1, 1, 1} };     //定义16个按键的当前状态量(初始值都设为1)
void main()
{
	unsigned char i, j;
  unsigned char backup[4][4] = { {1, 1, 1, 1}, 
  								 {1, 1, 1, 1}, 
  								 {1, 1, 1, 1},
  								 {1, 1, 1, 1} };   //定义16个按键上个时刻的状态量
     EA = 1;             //打开定时中断
     TMOD = 0x01; 
  	 TH0 = 0xFC;         //定时1ms
   	 TL0 = 0x67;
   	 ET0 = 1;     
  	 TR0 = 1;              //开始计时
     P2 = ledchar[0];      //数码管初始显示为'0'
	while(1)               //进行按键状态的检测,获取键号
	{
		for(i=0;i<4;i++)
		{
			for(j=0;j<4;j++)
			{
				if(backup[i][j]!=keysta[i][j])  //如果当前按键状态与上一时刻状态量不同,说明按键有动作
				{
					if(backup[i][j]==1)              //上一状态量为1,说明此时是按键按下,即: 1 -> 0
					{
						P2=ledchar[i*4+j];              //数码管显示按键键号
					}
					backup[i][j]=keysta[i][j];         //将当前按键状态赋给上一时刻状态量,进行更新
				}
			}
		}
	}
}
void InterruptTimer0() interrupt 1     //定时器0
{
		unsigned char i;
 static unsigned char keyout = 0;       //扫描的行号,起始第一行
 static unsigned char keybuf[4][4] = { {0xFF, 0xFF, 0xFF, 0xFF},
                                       {0xFF, 0xFF, 0xFF, 0xFF},
                                       {0xFF, 0xFF, 0xFF, 0xFF}, 
                                       {0xFF, 0xFF, 0xFF, 0xFF} };    //缓冲值
 TH0 = 0xfc; //定时器重装
 TL0 = 0x67;
 keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;      //第'keyout'行的列扫描
 keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;
 keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;
 keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;
		for(i=0;i<4;i++)
		{
			if((keybuf[keyout][i]&0x0f)==0x00)              //判定为按键按下
			{
				keysta[keyout][i]=0;						//改变对应按键的状态
			}
			else if((keybuf[keyout][i]&0x0f)==0x0f)         //判定为按键跳起
			{
				keysta[keyout][i]=1;                        //改变对应按键的状态
			}
		}
		keyout++;                  //扫描下一行
		keyout=keyout&0x03;        //第四行扫描完后,keyout清零,从第一行开始
		switch(keyout)             //当前扫描行电平置0,上一行置1
		{
			case 0:KEY_OUT_4=1,KEY_OUT_1=0;break;
			case 1:KEY_OUT_1=1,KEY_OUT_2=0;break;
			case 2:KEY_OUT_2=1,KEY_OUT_3=0;break;
			case 3:KEY_OUT_3=1,KEY_OUT_4=0;break;
			default: break;
		}
}

编程技巧: keyout = keyout & 0x03;这一行,在这里是要让keyout 在 0~3 之间变化,加到 4 就自动归零,因为 0、1、2、3 这四个数值正好占用 2 个二进制的位,所以我们把一个字节的高 6 位一直清零的话,这个字节的值就是一种到 4 归零的效果,这样一句代码比 if 语句更为简洁,而效果完全一样。

经过实物测试,使用该代码的矩阵键盘,稳定性较好。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一个51单片机矩阵键盘的扫描,消抖和键号显示程序 的相关文章

  • 刚体动力学

    文章目录 刚体状态 将某个物体从局部坐标系变化到全局坐标系 对时间求导 对矩阵求导 惯性 刚体属性 1 质心 计算方法 体素法 直接计算法 四面体体积 四面体的中心 2 惯性张量 世界坐标系中的惯性变量 刚体运动 力矩 刚体的固定属性 当前
  • C++数据结构 矩阵的转置、镜像及旋转

    C 数据结构 矩阵的转置 镜像及旋转 矩阵介绍 C 中的矩阵是一种二维数组 用于存储数值数据 矩阵可以用于存储图像数据 以及科学和工程计算中的数据 常用于以下场景 数学运算 矩阵乘法 行列式计算 特征值分解等 图像处理 图像缩放 旋转 颜色
  • STM32矩阵按键(定时器)

    由于采用延时函数会影响程序速度 所以采用定时器中断写的矩阵扫描按键 利用简单的状态机思想 1 定时器初始化 定时器初始化 void TIM2 Configuration void TIM TimeBaseInitTypeDef TIM Ti
  • 11-矩阵(matrix)_方阵_对称阵_单位阵_对角阵

    矩阵 向量是对数的拓展 一个向量表示一组数 矩阵是对向量的拓展 一个矩阵表示一组向量 1 2
  • #C++矩阵类的实现

    C 矩阵类的实现 环境 Win10 VS2017 最近老师布置一个简单的C 作业 实现一个矩阵类 并且实现矩阵运算 主要实现运算为矩阵的加 减 乘 除以及求行列式 伴随矩阵 代数余子式和逆矩阵等 在参考网上的一些前辈的代码后 写出了这些运算
  • 使用克拉默法则进行三点定圆(三维)

    目录 1 三维圆 2 python代码 3 计算结果 本文由CSDN点云侠原创 爬虫网站请自重 1 三维圆 已知不共线的三个点 设其坐标为 x 1 y 1
  • 2、基于51单片机智能交流电表抄表OLED屏

    毕设帮助 开题指导 技术解答 有偿 见文末 目录 摘要 一 硬件方案 二 设计功能 三 实物图 四 原理图 五 PCB图 六 程序源码 七 资料包括 摘要 电表表示着人们日常用电的多少 现在每家每户安装的根本上是带有转盘的那种电表 它只能显
  • 基于51单片机汽车胎压温度监测报警系统(程序+仿真+原理图+元件清单)

    功能介绍 采用51单片机作为主控单片机 通过采集传感器的胎压和DS18b20的温度 显示到LCD1602上面 并且可以通过按键设置温度和压力的阈值 超过此值蜂鸣器进行报警 可以及时的提醒驾驶员胎压或者温度异常 程序采用keil编写 并且有中
  • 图谱论学习—拉普拉斯矩阵背后的含义

    目录 一 为什么学习拉普拉斯矩阵 二 拉普拉斯矩阵的定义与性质 三 拉普拉斯矩阵的推导与意义 3 1 梯度 散度与拉普拉斯算子 3 2 从拉普拉斯算子到拉普拉斯矩阵 一 为什么学习拉普拉斯矩阵 早期 很多图神经网络的概念是基于图信号分析或图
  • MATLAB之LU分解法(十)

    LU分解 1 LU分解的基础知识 矩阵的LU分解又称为矩阵的三角分解 即将一个矩阵分解为一个下三角矩阵L和一个上三角矩阵U 即 A L U A LU A LU 其在方程组的求解和求矩阵的逆有许多应用 LU分解的求解命令是lu 基本使用格式如
  • 密码复习——AES

    AES 分组加密 明文的固定长度128位 密钥长度可以是128 192 256位 按明文与密钥长度都是128位来解释AES的加密过程 在AES中 明文是以字节的形式排列 一个字节8bit位 排列如下 AES的整体加密流程 其中最后一轮第十轮
  • GPU编程 CUDA C++ 线性代数求解器 cuSolver库

    cuSolver库较cuBLAS库更为高级 其能处理矩阵求逆 矩阵对角化 矩阵分解 特征值计算等问题 cuSolver库的实现是基于cuBLAS库和cuSPARSE库这两个基本库 cuSolver库的功能类似于Fortran中的LAPACK
  • TRMF 辅助论文:最小二乘法复现TRMF

    1 目标函数 总 论文笔记 Temporal Regularized Matrix Factorization forHigh dimensional Time Series Prediction UQI LIUWJ的博客 CSDN博客 1
  • OSQP二次规划求解库使用说明

    OSQP二次规划求解库使用说明 贺志国 2023 5 10 1 凸二次规划的一般表达式 m i n 1 2 x
  • Herriott池的建模

    摘要 在气体光谱学中 为了获得足够灵敏的吸收测量 通常要求具有较长的光程长度 充气体积包裹在反射镜之间的多通道单元是满足这一要求的一种方式 同时在途中控制光束发散 避免了对超大设备的需求 Herriott单元是这种系统的一个例子 其特点是使
  • 【Qt开发流程】之事件系统3:键盘事件

    序章 以下链接是拖放事件介绍和使用示例 Qt开发流程 之拖放操作1 介绍链接 https blog csdn net MrHHHHHH article details 134626484 Qt开发流程 之拖放操作2 使用链接 https b
  • LeetCode-数组-矩阵问题-中等难度

    toc 矩阵 矩阵是二维数组相关的应用题型 常见的有矩阵水平翻转 矩阵对角线翻转 矩阵遍历等 1 重塑矩阵 1 1 题目描述 leetcode跳转 566 重塑矩阵 1 2 方法一 简单模拟 借助一个一维数组用来保持按行列遍历的结果 然后再
  • 【二分查找】【z型搜索】LeetCode240:搜索二维矩阵

    LeetCoe240搜索矩阵 作者推荐 贪心算法 中位贪心 执行操作使频率分数最大 本文涉及的基础知识点 二分查找算法合集 题目 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 该矩阵具有以下特性 每
  • Linux值得学习吗?打工人利用业务时间学习Linux需要多长时间?

    nbsp Linux值得学习吗 打工人利用业务时间学习Linux需要多长时间 在开始前我有一些资料 是我根据自己从业十年经验 熬夜搞了几个通宵 精心整理了一份 Linux的资料从专业入门到高级教程 工具包 点个关注 全部无偿共享给大家 在评
  • 矩阵基本操作2

    题目描述 问题描述 将方阵 n 行n列 n lt 100 置成下三角矩阵 主对角线右上角数字全部清零 输入格式 第一行输入n 接下来的n行每行n列 表示矩阵的数值 用空格隔开 输出格式 n行n列下三角矩阵 每个数字3个占位符 左对齐 输入样

随机推荐

  • 代码审计总结

    目录 概述 一 代码审计 1 1什么是代码审计 1 2为什么要执行代码审核 1 3代码审计的好处 二 代码审计流程 2 1代码检查方法 2 2代码检查项目 2 3编码规范 2 4代码检查规范 2 5缺陷检查表 2 6代码审计复查 2 7代码
  • Linux工具 Ansible

    Linux工具 ansible Ansible是一个运维管理工具 可以减少一些重复的配置 比如有几百台主机需要进行相似的配置时或者对所有主机进行某些软件的版本升级时 如果是人工一台一台的配置是非常慢的 也容易出错 毕竟人精力有限 而这个An
  • PowerShell 美化(谁不想要一个好看的终端呢)

    PowerShell 美化 安装powershell Scoop 安装 Oh My Posh 安装 字体设置 应用主题 花里胡哨的折腾 bushi 多种主题任君挑选 安装powershell 地址 https github com Powe
  • neo4j官方示例数据库

    官方示例数据库 CREATE TheMatrix Movie title The Matrix released 1999 tagline Welcome to the Real World CREATE Keanu Person name
  • param.grad为 None或者TypeError: unsupported operand type(s) for *: ‘float‘ and ‘NoneType‘

    在学习李沐的动手学深度学习 从零开始实现softmax回归中 我跟着敲完代码 发现无法运行 报错入如下 TypeError Traceback most recent call last Cell In 72 line 3 1 num ep
  • 小程序蓝牙传输二维码

    有个需求 蓝牙要显示二维码 需要得到二维码的位图 点阵图 矩阵图 实现思路 1 获得canvas的二维码图片 要求为64px乘64px 2 获得二维码的图片 然后解析像素数组 获得像素的二进制状态码 3 将二进制状态码转化为byte数组 然
  • PCIE专题学习——1.0

    PCIE基础概念 一 1 PCIe的概念 PCIe是一种全双工 差分 端对端 串行告诉接口协议 PCI是并行处理的机制 差分可以提高传输的稳定性 全双工意味着发送端在发送的同时 也可以接收 问题在于串行会比并行处理快吗 当然不一定 这和系统
  • RuntimeError: The Session graph is empty. 和no Attribute““解决方法

    问题产生的原因 无法执行sess run 的原因是tensorflow版本不同导致的 tensorflow版本2 0无法兼容版本1 0 解决办法 添加行 tf compat v1 disable eager execution 无法执行se
  • JAVA 通过POI实现Excel从单元格选择下拉选项

    发生情景 最近使用到了模板导出功能 最开始使用的是hutool的POI工具 但是做下拉列表的时候 addSelect方法报错 问题 Excel在添加自定义下拉数据的时候 输入内容不能大于255个字符 这在做一些简单的下拉选项时没有问题 但是
  • 数论整理之算数基本定理de变形

    D Sigma Function 这道题一看到就和上一道题很像 以为也是算数基本定理的考查 做了一下 发现能过样例 tle tle的思路 经过多次验算 就是发现幂的规律吧 只要存在一个pi ei都为奇数的pi ei 就能使sum为偶数 素因
  • R语言中的quantile()函数

    在R语言中取百分位比用quantile 函数 下面举几个简单的示例 1 求某个百分位比 gt data lt c 1 2 3 4 5 6 7 8 9 10 gt quantile data 0 5 50 5 5 gt quantile da
  • 【ES】原生es的复杂查询

    原生es的复杂查询 相关依赖 复杂查询概述 外层查询 SearchSourceBuilder 类 外层查询概述 对查询结果进行分页 对查询结果进行排序 对查询结果字段进行过滤 对查询结果进行聚合 求年龄的最大值 根据年龄进行分组 内层查询
  • 关于两个页面用params传数据,刷新后数据消失的解决

    通常我们在两个页面传数据时 一般会采用params query 或者将数据用vuex localStorage sessionStorage存储起来 然后方便其他页面调用数据 但是params和vuex有一个不好的地方就是只要我们在接受数据
  • R6-1 给定两个均不超过9的正整数a和n,要求编写函数fn(a,n) 求a+aa+aaa++⋯+aa⋯aa(n个a)之和,fn须返回的是数列和函数接口定义:fn(a,n)其中 a 和 n 都是用户传

    给定两个均不超过9的正整数a和n 要求编写函数fn a n 求a aa aaa aa aa n个a 之和 fn须返回的是数列和 函数接口定义 fn a n 其中 a 和 n 都是用户传入的参数 a 的值在 1 9 范围 n 是 1 9 区间
  • python学习笔记---函数【廖雪峰】

    函数 调用函数 函数名其实就是指向一个函数对象的引用 完全可以把函数名赋给一个变量 相当于给这个函数起了一个 别名 gt gt gt a abs 变量a指向abs函数 gt gt gt a 1 所以也可以通过a调用abs函数 1 定义函数
  • UE4内置浏览器支持h264 mp4 视频 编译cef3 3071源码

    转载 原文链接 UE4内置浏览器支持h264 mp4 视频 编译cef3 3071源码 ue4 cef 鸿蒙老道的博客 CSDN博客首先ue4内置的CEF3 浏览器是不支持h264视频的 所以需要我们重新编译CEF内核 然后覆盖旧的版本一
  • 空闲时间不要接私活,要提升自己

    这个话题很纠结 现在社会 有很多人都在利用个人时间兼职赚钱 程序员俗称 接私活 其他行业称作兼职 比如下了班出去跑滴滴 周末兼职抢单送外卖等等 都是普通人很常见的兼职方式 甚至很多技术同行 我听说也有周末去跑滴滴和送外卖的 我觉得很不可思议
  • JVM-对象内存分配与回收细节问题

    对象内存分配与回收细节问题 1 禁用System gc System gc 会显示直接触发Full GC 同时触发老年代和新生代进行回收 而一般情况是我们认为 垃圾回收时自动进行的 无需手动触发 频繁的垃圾回收对系统性能造成较大影响 可以使
  • [数据分析与可视化] 基于matplotlib-scalebar库绘制比例尺

    matplotlib scalebar是一个Python库 用于在matplotlib图形中添加比例尺 它允许用户指定比例尺的大小 位置 字体和颜色 以及比例尺的单位 该库支持不同的比例尺单位 例如米 英尺 英寸等 matplotlib s
  • 一个51单片机矩阵键盘的扫描,消抖和键号显示程序

    51单片机的按键判断是一项很重要的功能 在蓝桥杯的比赛中必不可少 下面介绍一个稳定性比较好的矩阵键盘程序 首先介绍一下该矩阵键盘的基本原理 1 扫描 四条列线 接单片机的P2 4 P2 7口 电平都为1 四条行线 接P2 0 P2 3口 先