按键板的原理与实现 扩展GPIO
在系统可用的GPIO口数量有限的情况下实现按键板的另一个选择就是:扩展GPIO口。扩展GPIO的方法有很多,市场上已经有很多种类的GPIO口扩展器件,但是从成本上考虑,但它们总是显得昂贵。对于按键板的实现,使用基于一个移位寄存器的方法,因其低成本、方便稳定性而被广泛使用,这里我们将讨论一个基于74LS164的典型扩展IO实现按键板的方法。
1:硬件原理
嵌入式开发工程师必须要能看懂HW,要看懂电路,只有懂了电路是如何工作的,才可能编写出正确的控制程序。所以,我们首先看一下74LS164(8bit移位锁存寄存器)的工作原理。我们先给出使用74LS164实现按键板的原理图,并针对这个原理图做必要的分析解释。

对于74LS164,除了供电之外,有两个单向输入端口A、B,一个CLK,一个CLR和8个单向输出口Q0-Q7。我们关心的只是:特定的输入会得到怎样的输出,就是我们应该给GPIO_1 & GPIO_2什么样的信号,可以得到我们想要的输出。74LS164的输入输出状态见下表

也就是说:实际输入时“A&B”,假定某一时刻A&B=1(高电平)Q0=0,在CLK的上升沿后Q0=1(原A&B的状态) Q1=0(原Q0的状态),就是向后移了一位。实际上可以认为:A&B->Q0->Q1->…->Q7,在CLK的每个上升沿,都会顺序的向后移动一位。如果CLK信号一直为低电平,那么Q0-Q7就会之一保持其当前的状态。这也就是所谓的移位锁存寄存器。
根据74LS164的原理,分析一下我们的原理图:
1:给GPIO_1(Input A & B)高电平,再给GPIO_2(CLK)送上8个脉冲信号,那么Q0-Q7均为高电平状态。
2:给GPIO_1低电平,接着给GPIO_2一个脉冲信号,则Q0为低电平,Q1-Q7为高电平;此时读取GPIO_3(KS_DET0),若为低电平,则表明KEY_0被按下,若为高电平,则表示KEY_0没有动作。同理,读取GPIO_4(KS_DET1)的状态,可以判断KEY_8的状态。
3:给GPIO_1高电平,然后给GPIO_2一个脉冲信号,则Q0为高,Q1为低,Q2-Q7为高,可以判定KEY_1 & KEY_9的状态
4:此后只需要每次给GPIO_2一个脉冲信号,就可以依次判断其他按键了。
2:软件实现
基于上面的分析,我们已经很清楚按键判定的原理,知道该如何控制74LS164来实现按键侦测。在开始软件编程之前,一定要搞清楚我们这种实现的每一个步骤,才能确保写出正确的代码。下面是我的一个实现:

上述代码提供了一个判断与74LS164输出端相连的开关量信号状态的标准函数,对侦测按键的函数就显得很简短了。注意到Key_Scan()函数的实现,优先判断无按键动作的情况,因为现实中的按键板在99%的情况下是无按键动作的,这样就显著提高了代码效率。优秀的程序员在写代码的时候,不仅仅会单独从语言特性方面来提高代码执行效率,还很懂得根据项目的特性来提升性能。
3:讨论与总结
1:使用74LS164的扩展,从严格意义上讲,它并不能称作扩展GPIO,但在我们的实现中,它替代了GPIO的作用。例子中的实现使用4个GPIO实现了16个按键。理论上推理下去,N个GPIO可以实现(N-2)*8个按键。
2:按键动作,其实就是一个开关量。只要是涉及对开关量的侦测,我们的实现都可以应用。而编程上只需要简单的封装,就可以想其他IO一样,对其进行侦测

原文链接:https://blog.csdn.net/NutriYang/article/details/4374706
按键板的原理与实现 扩展GPIO的更多相关文章
- 按键板的原理和实现--基于GPIO的按键板
上篇介绍简单的ADC实现,需要IC提供一个额外的ADC.但出于IC成本的考虑,无法提供这个的ADC时,但提供了多个额外的GPIO(General Purpose Input Output:双向的:可以 ...
- 按键板的原理与实现----ADC
在嵌入式系统产品开发中,按键板的设计是最基本的,也是项目评估阶段必须要考虑的问题.其实现方式又很多种,具体使用那一种就需要结合特定IC的可用IO数量,并综合考虑成本,做出最终选择.本系列文章将介绍多种 ...
- Django admin 组件 原理分析与扩展使用 之 sites.py (一)
一 . 前言 Django 提供了admin 组件 为项目提供基本的管理后台功能(对数据表的增删改查). 本篇文章通过 admin源码 简单分析admin 内部原理 ,扩展使用方式,为以后进行定制和自 ...
- 学习笔记: 反射应用、原理,完成扩展,emit动态代码
using Ruanmou.DB.Interface; using Ruanmou.DB.MySql; using Ruanmou.DB.SqlServer; using Ruanmou.Model; ...
- 在.NET下学习Extjs(第四个案例 Extjs扩展的原理)
1.构建如下代码 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head& ...
- 【细语】C#之扩展方法原理及其使用
1.写在前面 今天群里一个小伙伴问了这样一个问题,扩展方法与实例方法的执行顺序是什么样子的,谁先谁后(这个问题会在文章结尾回答).所以写了这边文章,力图从原理角度解释扩展方法及其使用. 以下为主要内容 ...
- JQ的核心原理以及扩展等
jQuery核心原理 定义原型扩展和工具包扩展的方法 JQ的API中文速查: http://jquery.cuishifeng.cn/ JQ的原理:http://www.cnblogs.com/Sca ...
- 重新学习Spring注解——扩展原理
39.扩展原理-BeanFactoryPostProcessor 40.扩展原理-BeanDefinitionRegistryPostProcessor 41.扩展原理-ApplicationList ...
- 【spring 注解驱动开发】扩展原理
尚学堂spring 注解驱动开发学习笔记之 - 扩展原理 扩展原理 1.扩展原理-BeanFactoryPostProcessor BeanFactoryPostProcessor * 扩展原理: * ...
随机推荐
- biiset用法
C++ bitset--高端压位卡常题必备STL 以下内容翻译自cplusplus.com,极大地锻炼了我的英语能力. bitset存储二进制数位. bitset就像一个bool类型的数组一样,但是有 ...
- python 之 列表常用 操作
- lixuxmint系统定制与配置(1)-系统初始配置
小书匠Linux 经常安装新的系统,每次安装完都得去搜索一边如何将系统部署为之前的环境,不仅耗费时间,还不一定能弄回之前的环境,现在把从裸机->到工作环境的系统定制及配置过程记录下来,期间的配置 ...
- webstorm 和 vscode 的纠结
自从知道了 vscode 之后,尝试了一下后,就开始纠结是否要更换到vscode. 特别是在 webstorm 卡的时候. 也研究了几日 vscode,安装了许多插件. 我是安装插件后, 就开始学习快 ...
- 《挑战30天C++入门极限》新手入门:关于C++中的内联函数(inline)
新手入门:关于C++中的内联函数(inline) 在c++中,为了解决一些频繁调用的小函数大量消耗栈空间或者是叫栈内存的问题,特别的引入了inline修饰符,表示为内联函数. 可能说到这里,很 ...
- 在Maven项目中使用lombok
事前准备:如果是eclipse的话,需要在官网下载jar文件,放到eclipse根目录下,eclipse.ini的最后追加 -Xbootclasspath/a:lombok.jar -javaagen ...
- Android中为何使用Log而不用System.out
Android中为何使用Log而不用System.out System.out除了使用方便一点以外有以下缺点:日志不可控制,打印时间无法确定,不能添加过滤器,日志没有级别之分. 使用Log比如想打印一 ...
- 解决tecplot中壁面速度不为0的问题
当直接将fluent的.cas文件和.dat文件导入tecplot中进行后处理的时候,我们会发现,壁面速度不为0的情况(见上图). 出现这样问题的原因为:fluent的计算数据是存储在每个单元的中心位 ...
- 纯JavaScript开发飞机大战项目
开发工具: HBuilder 编程语言:JavaScript 其他技术:Html + Css 项目截图: 视频: 源代码: 在线观看地址: (暂无) 百度网盘下载地址: 请加QQ群:915 ...
- C语言--二维数组
一.PTA实验作业 题目1:7-2 求整数序列中出现次数最多的数 1. 本题PTA提交列表 2. 设计思路 定义变量n表示输入整数个数,count表示每个数出现次数,i.j表示循环变量,k表示次数最多 ...