按键板的原理与实现 扩展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 * 扩展原理: * ...
随机推荐
- Problem 5 素数筛法+并查集
$des$ 给定一个长度为 $n$ 的正整数序列 ${a_i }$.将 ${1,2,...,n}$ 划分成两个非空集合 $S.T$,使得 $gcd(\prod_{i \in S} a_i, \prod ...
- AtCoder Grand Contest 020 题解
传送门 怎么又是\(tourist\)神仙的题-- \(A\) 咕咕 int n,a,b; int main(){ scanf("%d%d%d",&n,&a,&am ...
- elasticsearch routing
当索引一个文档的时候,文档会被存储到一个主分片中. Elasticsearch 如何知道一个文档应该存放到哪个分片中呢?当我们创建文档时,它如何决定这个文档应当被存储在分片 1 还是分片 2 中呢?首 ...
- DDD应对运营活动系统腐化实践
前言 任何人类的设计都会腐化,软件系统也不例外 腐化之谜 随着系统的规模增长和复杂度膨胀,系统会慢慢腐化. 于是改一个很简单的下单地址,就会牵动整个交易系统十几处的改动. 如何解决这种腐化之谜呢? 参 ...
- winform如何不卡界面
快速阅读 如何在winform程序中,让界面不再卡死. 关于委托和AsyncCallback的使用. 界面卡死的原因是因为耗时任务的计算占用了主线程,导致主界面没有办法进行其它操作,比如拖动.造成界面 ...
- 元素在当前窗口可视的区域---Element.scrollIntoView()
element.scrollIntoView(); // 等同于element.scrollIntoView(true) element.scrollIntoView(alignToTop); // ...
- (转)AutoML 与轻量模型大列表: awesome-AutoML-and-Lightweight-Models
Awesome-AutoML-and-Lightweight-Models 原文:http://bbs.cvmart.net/articles/414/zi-yuan-automl-yu-qing-l ...
- 2019年ArcGIS规划专业专项培训(四天)
2019年ArcGIS规划专业专项培训(四天) 商务合作,科技咨询,版权转让:向日葵,135-4855__4328,xiexiaokui#qq.com 第一天:GIS入门 第一章 GIS概述及其应 ...
- Python 设计模式之建造者模式 Builder Pattern
#引入建造者模式 肯德基的菜单上有 薯条, 鸡腿,鸡翅,鸡米花,可乐,橙汁,火腿汉堡,至尊虾汉堡,牛肉汉堡 , 鸡肉卷等这些单品,也有很多套餐. 比如 套餐1:鸡翅,至尊虾汉堡,可乐,薯条 套餐2:鸡 ...
- docker批量操作容器
author:headsen chen date: 2019-08-07 15:26:46 列出所有的容器 ID docker ps -aq 停止所有的容器 docker stop $(docker ...