今天开始刷题的时候,发现总是出现这个矩阵键盘的问题,然后我也没有耐下心来仔细看,随便抄了答案,但是总感觉不爽,不说把它搞得多透彻吧,但是最起码要知道咋算,于是在网上查找了相关资料,稍微理解了一点,所以我在这把我理解的稍微总结一下,可能里面会有理解有误的地方,欢迎各位大佬指出来
参考网址:
https://wenku.baidu.com/view/3f517aa6561252d381eb6e80.html

先贴上按键原理图

然后再把题库中的源代码贴出来,里面的空我都已经填上去了,我们主要是看一下整个代码的大概意思以及相关计算

//KEYOUTPUT是键盘扫描时的输出地址,KEYINPUT是键盘读入时的地址
#define KEYOUTPUT(*(volatile INT8U *)0x56000044)
#define KEYINPUT(*(volatile INT8U *)0x56000044)
INT16U ScanKey()
{INT16U key=0xFFFF;INT16U i;INT8U temp=0xFF,output;//rGPECON是端口E的控制寄存器rGPECON=((rGPECON & 0xFFFFFF00) | 0x00000055);//初始化GPE0~GPE3为输出rGPECON=rGPECON & 0xFFFF00FF;//初始化GPE4~GPE7为输入//下面判断键盘中是否有键按下for(i=1;((i<=8)&&(i>0));i<<=1){output|=0xFF;output&=(~i);KEYOUTPUT=output;temp=KEYINPUT;if((temp&=0xF0)!=0xF0)//判断列信号是否全为1{key=(~i);key<<=8;key|=((temp&0xF0)|0x0F);//求得按键的返回值return (key);}}return 0xFFFF;
}

然后我们一点一点的来看整个代码

//KEYOUTPUT是键盘扫描时的输出地址,KEYINPUT是键盘读入时的地址
#define KEYOUTPUT(*(volatile INT8U *)0x56000044)
#define KEYINPUT(*(volatile INT8U *)0x56000044)

开头这两句就是定义了两个宏定义,用KEYOUTPUT代替了行扫描输出信号的相关IO口,用KEYINPUT来代替了列扫描的读入信号的相关IO口,就相当于我们用LED0来代替一个IO口时一样的,所以这里不做过多说明

INT16U key=0xFFFF;
INT16U i;
INT8U temp=0xFF,output;

这三句话就是定义了一些相关的变量以及给部分变量赋予了初值,我们需要注意的就是各个变量是8位的还是16位的,其中key和i是16位的,而temp和output是8位的

 //rGPECON是端口E的控制寄存器rGPECON=((rGPECON & 0xFFFFFF00) | 0x00000055);//初始化GPE0~GPE3为输出rGPECON=rGPECON & 0xFFFF00FF;//初始化GPE4~GPE7为输入

这两行代码就是配置与按键相关的IO口,其中GPE0~GPE3是作为行扫描信号的,我们需要让这四个IO口循环的输出低电平,所以我们要把GPE0~GPE3初始化为输出模式,而GPE4~GPE7是作为列扫描的读入信号,如果有按键按下,相对应列所对应的IO口就会被输入低电平(对照着上面那个原理图来说,假如现在按下了确认键,那么GPE7这个IO口就会被输入低电平),我们需要不断地循环读取GPE4~GPE7这四个IO口的电平状态,从而判断是哪一列有按键按下,然后后面再得到当检测到有按键按下那一时刻的 i 的值,就可以知道是哪一行的按键按下了,从而我们就知道具体是哪一行哪一列的按键被按下了

for(i=1;((i<=8)&&(i>0));i<<=1)

这是一个for循环,首先我们注意下for循环的循环条件,它让i从1开始循环,然后一直循环到i=8,关键的问题就是在于i的自增条件,它不是我们常用的i++或者i–,它是i<<=1,也就是说,每循环一次,i 就要左移一次,它的变化过程就是0001、0010、0100、1000,当 i 变化到1000的时候,它已经变成8了,此时这个for循环循环了4次,再往后面我们就会发现,其实这个循环4次就是让GPE0~GPE3这四个IO口循环输出低电平

output|=0xFF;
output&=(~i);
KEYOUTPUT=output;

这是for循环里面的前3条语句,首先第一条output|=0xFF;,其实就是对output的初始化,然后第二条output&=(~i);,这条语句的意思就是先让 i 取反,然后再让output与取反后的 i 进行相与,相与的结果再赋给output,然后第三条KEYOUTPUT=output;,这条语句的意思就是把output的值给KEYOUTPUT,也就是把output的值给了行扫描信号对应的IO口了。如果这三条语句是第一次循环,那么这三条语句执行完之后,i=0x0001,output的值就是0xFE(注意,i 是16位数据,而output是8位数据,当8位数据与16位数据相与时,结果只能保留8位数据),把output的值化成二进制表示就是1111 1110,其实这个output就对应着上面那个原理图中的GPE7~GPE0,(我们只需要重点关注output的值就行,至于KEYOUTPUT的值,它只不过是就是把output给复制走了,output起到了中间桥梁的作用)即这个时候是就对应着是让GPE0为0,我们先不管后续的程序,假如现在进入到了第二次循环,那么对应的 i 就应该左移一位,即 i=0x0002,此时经过 output&=(~i);语句之后,output=0xFD,化为二进制表示就是1111 1101,即这个时候就对应着GPE1为0,继续往下循环下去,我们通过 i 的左移和相与的操作,就实现了矩阵按键的行扫描,即让四个行扫描信号循环的为低电平。
我们接着往下看源程序

temp=KEYINPUT;
if((temp&=0xF0)!=0xF0)//判断列信号是否全为1{key=(~i);key<<=8;key|=((temp&0xF0)|0x0F);//求得按键的返回值return (key);}

这段代码的作用就是判断有没有按键按下去,同时如果有按键按下去,则返回相应的码值
首先temp=KEYINPUT; ,就是把对应的IO口的值给读到变量temp上,以便用于后期的操作。

if(`(temp&=0xF0)!=0xF0`)//判断列信号是否全为1

这个if语句就是先让temp与上0xF0,即把temp的低四位给屏蔽掉,我们只关注高四位,因为高四位就分别对应着GPE7~GPE4。然后我们又有一个判断(temp&=0xF0)!=0xF0,这个就是用来判断temp的高四位是不是全部都为高电平,如果是,则代表着哪一列都没有按键按下去,如果temp的高四位有一个是低电平,那么就表示着低电平所对应的列有按键按下去,然后就进入到if语句里面进行处理。
首先就是key=(~i);,即把 i 取反,然后送给变量key,然后下一句key<<=8;,这条语句就是让key左移8位,假如key是0xFFFE,左移8位就相当于十六进制的左移2位,即左移8位后,key=0xFE00。然后下一句key|=((temp&0xF0)|0x0F);,这条语句的作用就是求得按键的返回值,假如现在temp=0x7*(此时我们先只看temp的高四位,低四位的值在这里意义不大,我用 * 号代替),然后temp与上0xF0后,temp=0x70,然后再和0x0F相或,结果是temp=0x7F,然后原来key的值再与此时的temp相或,相或的结果再赋给key,则计算完之后,key=0xFE7F,到这里,这个ScanKey()函数就说完了。(因为我们刚才假设的key=0xFFFE,temp=0x7*,也就是说这个时候是第一行、第四列的按键被按下,也就是我们上面原理图中的确认键被按下了,即如果我们得到这个ScanKey函数的返回值是0xFE7F的话,我们就可以知道,此时是确认键被按下了)
以上就是我们矩阵按键的工作原理,我说的也比较多,可能也比较乱,希望大家可以仔细地揣摩一下其中的原理,其实它也没那么复杂,只要一步步推导就可以了。其中关键点就是 i 的左移,它每左移一次,就代表着对应的行扫描信号就要是低电平,然后我们就去读取所有的列扫描信号,如果所有的列都是高电平,就代表着没有按键按下去,如果有一列是低电平,那么就是那一列有按键按下了。

矩阵按键扫描整体思路:
矩阵按键分为四行四列,起初初始化的时候所有的行和列所对应的引脚都是高电平,然后我们让那四行中的各行循环为低电平,假如说现在我们让第一行为低电平,其余三行还是高电平,然后我们就开始去读取那四列的信号状态,如果四列全为高电平,就代表没有按键按下,如果我们发现第2列对应的引脚是低电平的时候,那么就代表着第二列的四个按键中肯定有一个按键被按下,而我们现在是让第一行为低电平,那也就是说第一行、第二列的按键被按下了,然后我们再进行一些相关的数据运算,最终通过函数返回一个数值就完成了按键的扫描,每一个按键都对应着不一样的返回值,(如果没有按键按下,则返回值为0xFFFF)由此我们就可以通过返回值来判断是哪一个按键被按下了。

参考网址:
https://wenku.baidu.com/view/3f517aa6561252d381eb6e80.html

计算机三级嵌入式系统考试之矩阵键盘相关推荐

  1. 计算机三级嵌入式试题讲解,计算机三级嵌入式系统操作题及解析.docx

    PAGE PAGE # 计算机三级嵌入式系统操作题及解析 操作题(一) 1地铁进出站闸机的控制器以 S3C2410芯片为核心,并外加其他功能电 路来进行设计,其基本功能描述如下: a闸机能够识别本地铁 ...

  2. 计算机三级嵌入式系统易错题总结

    1.IP是中文 知识产权的英文缩写 2.有线电视的视频编码:MPEG-2,互联网视频编码:MPEG-4 AVC 3.ARM处理器异常中断处理中用于软中断的指令助记符是:SWI,用于断点中断指令助记符是 ...

  3. 计算机三级嵌入式系统开发 知识点笔记

    目录为搜索词,详情看每一节后图片 思维导图已上传,点击这里下载 嵌入式系统开发 全部章节图片 第一章 嵌入式系统概论 1.1 SoC IP核 1.2 1.2.1 ASCII GB2312 GB1803 ...

  4. 计算机三级嵌入式系统之常考指令

    指令的条件码总结 EQ - 相等 NE - 不等 MI - minus负数 PL - plus正数或0 vs - overflow set溢出 vc - overflow clear未溢出 GT - ...

  5. 全国计算机三级嵌入式 - 题库 - 真题(含答案) - 未来教育 - 视频讲解 - 资料获取

    全国全国计算机三级嵌入式等级考试 1. 考题大纲 历年不一样. 但是换汤不换药. 2. 考试真题 历年全部考题.真题. 包含全部答案. 3. 未来教育 考点.知识点.历年真题视频讲解. 4. 资料获取 ...

  6. 计算机三级嵌入式上传学习资源介绍

    计算机三级嵌入式上传学习资源介绍 一."计算机三级嵌入式学习笔记(onenote版)"(一)~(五) 下载地址: (一).(二).(三).(四).(五) 资源介绍: 这是我之前在备 ...

  7. 计算机三级嵌入式知识点总结

    知识总结: 1.嵌入式系统的CPU具有4个特点: 支持实时处理 低功耗 结构可扩展 集成了测试电路 注:高主频非其特点 2.USB的特点     (1) 在具有OTG(On-The-Go)的USB总线 ...

  8. 计算机四级嵌入式工程考试试题和理解总结记录

    #计算机四级嵌入式工程师考试试题和理解总结记录 ##结合了社区几位大神笔记的,整理了一些计算机四级嵌入式工程师备考试题等.写了下面的理解和必备.如果有不对和疏漏的地方请指正 计算机操作系统 一.绪论: ...

  9. 计算机数据库技术应用了什么,2018年全国计算机三级数据库技术考试考什么内容...

    根据<全国计算机等级考试三级数据库技术考试大纲(2018年版)>,全国计算机三级数据库技术考试内容主要包括:数据库应用系统分析及规划.数据库设计及实现.数据库存储技术.数据库编程技术等7项 ...

最新文章

  1. mysql 5.7 1055_mysql 5.7报1055错误的解决方法
  2. Semtech与Lacuna从太空接收信息
  3. [poj] 2318 TOYS || 判断点在多边形内
  4. μCUnit,微控制器的单元测试框架
  5. python电子章_Python语言程序设计(电子)答案
  6. 常见排序算法之冒泡排序
  7. SQL文档阅读笔记-对水平分区和垂直分区理解
  8. XCode 单独debug area窗口
  9. 如何备份数据库的某张表_详解mysql数据库如何用mysqldump实现单表备份
  10. 洛谷——P1426 小鱼会有危险吗
  11. 完成一个Vue3项目的过程
  12. 5.5使用Cucumber来测试
  13. excel工作簿合并怎么处理?
  14. 四川300家旅游企业上“云端”转型信息化
  15. 抖音如何接入在线客服系统?
  16. 深入浅出Apache DolphinScheduler
  17. 【SCIR笔记】多模态摘要简述
  18. gem 安装oxidized-web报错:checking for -licui18n... no处理
  19. vue 上次登录时间_Vue设置长时间未操作登录自动到期返回登录页
  20. 屏幕小于6英寸的手机_6寸以上屏幕手机有哪些?

热门文章

  1. Lumines! to exploit
  2. 关于用户自定义控件与引用该控件的页面之间的javascript脚本冲突
  3. 【报告分享】中科院-地球大数据支撑可持续发展目标报告.pdf
  4. 研究生必备自学课程!打好科研的数学基础与机器学习基础!
  5. ajax无法发送json串,如何使用$ .ajax发送JSON而不是查询字符串?
  6. Leetcode每日一题:1024.video-stitching(视频拼接)
  7. Leetcode每日一题:904.fruit-into-baskets(水果成篮)
  8. Representation Flow for Action Recognition论文解读
  9. Webpack4 学习笔记 - 02:loader 打包静态资源(图片)
  10. Nginx内置模块简介