基于ARM9的多行列键盘设计及其驱动实现

发布者:和谐相处最新更新时间:2012-03-24 来源: 微计算机信息 关键字:AT91RM9200  ARM-Linux  驱动程序 手机看文章 扫描二维码
随时随地手机看文章

1  引  言

许多嵌入式系统,尤其是一些人机交互(HMI)较频繁的嵌入式系统,键盘是一种应用最为广泛的输入设备。由于嵌入式设备的功能互异性,为其提供一种通用性键盘是不可行的,一般都需要根据嵌入式系统的实际功能来设计所需的特殊键盘,并实现相应的驱动程序。www.51kaifa.com

在嵌入式设备上扩展键盘的常用方式是通过使用CPU的GPIO端口扫描实现的,显然,这种方式会占用系统的GPIO资源,特别是在GPIO资源比较紧张而按键又较多的系统,这个问题就特别突出。当然,也可以通过外扩GPIO(如8255等)或外扩专用的键盘接口(如8279等)方式实现,但这种方式显然增加了系统的复杂度,在实际系统设计中颇感不便。

本文以在ARM9(AT91RM9200)嵌入式微处理器上实现一个POS机键盘(8×8)为例,呈现了一种在嵌入式设备上扩展多行列键盘的新设计思路,并在ARM-Linux系统实现了键盘的驱动程序。

2、接口电路的硬件设计

本文通过一个设计实例,说明如何使用一种比较简单的方式,来实现一个8×8的POS机矩阵键盘,POS机所采用的微处理器是AT91RM9200芯片。AT91RM9200是ATMEL公司生产的一款高性能的32位ARM9处理器,它是一款通用工业级ARM芯片,在工业控制、智能仪器仪表等领域内得到了大量的应用[3,4],其详细芯片特性可参见文献[2]。

在AT91RM9200上扩展键盘,一般都是通过其GPIO端口来实现。AT91RM9200虽提供了4×32个可编程的GPIO端口。但为减小芯片体积和功耗,其许多GPIO端口都是与系统的外围设备控制器端口或地址线、数据线进行复用的,所以实际可用于扩展的GPIO端口是很少的。而对于一个 8×8键盘,若采用传统的GPIO端口扩展方式,则需要16个GPIO,这在一个比较复杂的POS系统中是很难满足的,因此需要采用其他方式来解决这个问题。

图1  键盘接口原理图

本文通过数据锁存的方式,充分利用32位处理器的数据宽度优势,使用数据线来替代键盘扩展所需的GPIO端口,从而减少对系统GPIO资源的占用。键盘接口的实现原理如图1所示。在图1所示的电路中,U1301(74LVCC4245)为三态缓冲器,U1302(74HC574)为锁存器,系统工作原理描述如下:

U1301的nOE端连接系统的译码输出nKey_CS,部件地址由系统译码电路决定,当向该地址写数据时,nKey_CS信号为低电平,数据可以通过U1301,同时,nKey_CS信号经两级反相器延时后作为锁存信号将数据锁存到U1302的输出端,作为键盘的行扫描信号,而键盘的列扫描信号则仍然使用系统的GPIO。依次向每行送出低电平信号,同时检测连接在GPIO的列信号,即可实现对键盘的扫描。在本系统中,只使用了系统32位数据的低8 位作为行扫描信号,在实现8×8矩阵键盘扫描的情况下,仅需要占用8个GPIO口,如果采用同样的方式,分别使用16位数据或32位数据作为行扫描信号,则只需要占用4个或2个GPIO,显然,与传统的方式相比较,该方式可以大大节省系统的GPIO资源。[page]

3、键盘的驱动模块设计

完成接口电路的设计之后,还需要编写相应的键盘驱动模块。本文采用AT91RM9200芯片中已经运行了ARM-Linux操作系统,因此给键盘的驱动程序开发提供了很大的方便。键盘的驱动模块可分为硬件初始化、文件操作函数的实现以及键盘扫描程序三个部分。

3.1  硬件初始化

键盘驱动程序的开发模式与Linux系统中一般字符设备的驱动开发步骤相似,关于Linux设备驱动开发的详细分析可参考文献[1]。首先需完成的是驱动程序模块的初始化函数和清除函数。在初始化函数中,除完成模块注册外,还应进行硬件初始化,下面是本文根据AT91RM9200芯片的GPIO控制器的特性[2],在模块的初始化函数中的硬件初始化的伪代码。

……

设置所使用GPIO端口为GPIO控制器控制

设置所使用GPIO端口的类型为输入

使能所使用GPIO端口的输入毛刺滤波功能

使能相应的GPIO控制器时钟

取指定地址的虚拟地址并向地址写入数据0x0

……

3.2  文件操作函数的实现

因为键盘在系统中一般只起输入作用,因此在键盘驱动程序的file_operations结构中,必须实现的文件操作函数只有文件读函数。

另外在实际应用中,为防止键盘按键的丢失,被按下键的扫描代码通常都放置在一个缓冲区内,直到应用程序准备处理一个按键为止。缓冲区大小一般视应用系统的需求而定,本例中缓冲区大小取为20个按键代码。而缓冲区的实现是以一个环形队列的形式实现。当按键按下后,扫描代码将被放置在队列的下一个空位置,若缓冲区已满,则下一按键将会被丢弃。应用程序则通过键盘的读函数read()从缓冲区的位置指针处起,读取所需个数的键码;完成读取操作后,还需将已被读取的键码从缓冲队列中删除,并更新缓冲区的位置指针。下面给出了本例中,实现的键盘读函数key_read()的伪代码:

ssize_t key_read(……)

{

定义并初始化变量;

if 缓冲区中可被读取的键码数大于0;

    取得键码放置缓冲区的自旋锁;

    计算此次读操作可读取的代码个数M(缓冲区中可读取的代码个数与程序要求个数之间的较小者);

    从缓冲区位置指针开始,从缓冲区中拷贝M个的键码到用户空间缓冲区内;

    更新缓冲区的位置指针和缓冲区中还剩余的键码个数;

    释放自旋锁

    返回此次读操作成功读取的代码个数。

  Else

返回-1

}[page]

3.3  键盘扫描程序

键盘的工作原理是通过键盘的行线和列线的状态来判断键盘中有无按键被按下。键盘扫描程序的功能就是用来判断处于按下状态的按键的具体位置及取得相应的键码值,因此扫描程序的设计是键盘驱动模块实现的核心。

键盘扫描程序的实现主要有两种,即轮询方式和中断方式[5]。在本例中,利用操作系统定时器队列与轮询扫描方式结合的方法对键盘的驱动程序进行了设计,主要是基于以下两个方面的原因。其一是AT91RM9200芯片的中断信号线是非常宝贵的硬件资源,每一组GPIO端口只配置了一根中断信号线,即32个GPIO端口共享一条信号线。这样若采用中断方式,则至少需要占用一条芯片中断信号线,对多行列的键盘,如果其所采用的 GPIO端口不是来自于同一组时,就需要占用多条中断信号线。而且若其他设备使用的GPIO端口与键盘使用的GPIO口属于同一组,那么在两种设备的驱动程序设计中,必须进行中断共享,这样不仅使系统的软件设计更为复杂,且易产生中断丢失和中断竟态等问题,使设备性能受到影响。其二键盘是系统中属于一种相对低速的设备,采用轮询方式完全可以满足键盘的输入要求。

ARM-Linux操作系统提供了良好的定时器机制,因此通过简单定时器操作,就可以实现以固定间隔对键盘的状态进行扫描并对按键事件进程处理,固定间隔的大小可根据系统需求进行配置,定义器的详细操作可参见文献[1]。如前所述,键盘扫描程序的功能就是对键盘的状态进行判断和处理。若无按键按下,则扫描直接返回;若有按键按下,则对被按下键的位置进行判断,并将相应的键码值写入缓冲区中。因为本例中的键盘是为POS机配置,因此按键的准确性是至关重要,因此在扫描代码中对按键值进行了多次验证,下面是本例中使用的键盘扫描程序的伪代码:

int Scan_Keyboard()

   {

定义并初始化变量;

取得键码放置缓冲区的自旋锁;

if   缓冲区中还有空;

① 依次判断各GPIO口的状态,若无低电平,则无键按下,直接退出if语句;否则,有键按下,且当前检验的GPIO口连接的行线即为按键所在的行;

② 给键盘列线连接的数据线依次送入高电平,再通过判断按键行线所在的GPIO端口的电平状态,得到按键所在的列;

延时一小段时间,以消除键盘抖动;

③ 再向给键盘列线连接的数据线全送低电平,使用代码段①再次判断是否有键按下,若有,则取得按键所在的行;

④ 同样使用代码段②重新判断按键所在的列;

⑤ 判断第一次得到的按键的行与列是否与第二次完全一样,若完全相同,则可进入下一步,否则退出if语句;

⑥ 重新向给键盘列线连接的数据线全送低电平,并判断按键是否弹起,若仍处于按下状态,则继续等待,否则根据行与列,转化为相应键值,并写入缓冲区;

if语句结束;

释放自旋锁;

函数返回 0;

}

完成驱动程序代码编写后,就可以将键盘的驱动程序加载到ARM-Linux内核中了,既可以采用静态加载方式,也可以采用动态方式进行加载。加载后,在应用程序中键盘的编程使用方式与其他字符设备一样。采用本文所述方式设计的键盘,目前已配置在笔者参与开发的POS机中交用户使用,据用户测试,键盘的输入准确率和反应时间都达到了设计要求。

4、结束语

本文以运行ARM-Linux的AT91RM9200系统为基础,提出了一种在ARM9上扩展特殊键盘的新设计方法,并对键盘扩展的硬件设计和驱动软件开发都作了详细说明。本设计方法利用数据锁存方式替代了常规的GPIO扩展,提高了系统硬件的资源利用率,这一思想也为在其他嵌入式设备扩展多行列键盘提供了一种新的设计思路。

 

参考文献

[1] 魏永明,骆刚,姜君(译).Linux设备驱动程序(第二版)[M].中国电力出版社.2002.4

[2] ATMEL.AT91RM9200 User Manual.2005

[3] 张秀松.基于AT91RM9200的嵌入式工业控制系统设计[J].微计算机信息,2006,1-2:45-47

[4] 王建忠,田力,武凌.基于ARM920T核的AT91RM9200微控制器及其在嵌入式家庭网关中的应用[J].微计算机信息, 2004,20(5):49-51

[5] 马忠梅.ARM&Linux嵌入式系统教程[M].北京航空航天大学出版社.2004.9

关键字:AT91RM9200  ARM-Linux  驱动程序 引用地址:基于ARM9的多行列键盘设计及其驱动实现

上一篇:一种基于S3C2410A的液晶屏接口设计
下一篇:基于ARM-Linux的SQLite嵌入式数据库的研究

推荐阅读最新更新时间:2024-03-16 12:56

122x32液晶1520控制器驱动程序(C51)
简介:本文主要介绍了122x32液晶1520控制器驱动程序(C51)。 #include reg51.h #include intrins.h #include absacc.h #include .incASCII816.h //标准ASCII码库 #include .incHZTable.h //自制的汉字库 #include .incmenu.h //自制的菜单库 sbit LCD12232_A0=P3^3; sbit LCD12232_RW=P3^1; //读写 sbit LCD12232_E1=P3^5; //片选1(Master) sbit LCD12232_E2=P3^4; /
[单片机]
arm-linux交叉编译ACE
ACE应用于主站数据采集核心的开发已告一段落了。现在打算涉足嵌入式linux应用程序的设计。俗话说“工欲善其事,必先利其器”,ACE支持arm系列的嵌入式系统,当然首先折腾他了,后期还打算整整apache的运行时库apr。嵌入式系统的仿真平台采用skyeye,在这样一个平台里我已经实现了nfs mount 宿主机目录。测试交叉编译后的程序十分方便。 网上搜到一篇《机电之家 嵌入式Linux系统攻略--ACE程序移植过程详细解析》交叉编译工具是Moxa tool chain for DA66x,写的满详细,主要参照它就完成了arm-linux的交叉编译。详细过程如下: 1.解压ace源代码到/root 2.设置环境变量ACE_
[单片机]
<font color='red'>arm-linux</font>交叉编译ACE
1_5.5.1_字符设备驱动程序之概念介绍_P
之前讲了uboot,它的任务是启动内核; 内核的任务是启动应用程序; 应用程序,里面肯定会涉及很多文件操作,比如读写文件,还有很多硬件操作,比如点灯,获取按键值等。 对于写应用程序的人,他们通常不会去查看芯片手册看这些硬件要怎么操作,而是直接调用open,read,write这些接口来调用底层驱动。 最简单的一种对应方法就是,open函数,read函数,write函数分别会来调用底层驱动的led_open函数,led_read函数,led_write函数。 现在我们来看一下,应用程序的open,read这些函数,是怎么最终调用我们底层驱动的led_open,led_read这些函数的,中间有哪些东西。 假如
[单片机]
1_5.5.1_字符设备<font color='red'>驱动程序</font>之概念介绍_P
STM32 TM1640芯片驱动程序
以下为.h文件: #ifndef __TM1640_H__ #define __TM1640_H__ #include stm32f10x.h #define ADDR_START1640 0XC0 #define DSP1640_DIS 0 #define DSP1640_ENB 1 /* 控制显示 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f 分别对应 1/16, 2/16, 4/16, 10/16, 11/16, 12/16, 13/16, 14/16 设置数据,0x40,0x44分别对应地址自动加一和固定地址模式 */
[单片机]
STM32 TM1640芯片<font color='red'>驱动程序</font>
STM32开发笔记7: ST-LINK/V2-1驱动程序的安装
单片机型号:ST-LINK 插入ST-LINK/V2-1仿真器后,会提示驱动硬件的安装,除了大容量存储器外,虚拟串口和调试端口都需要安装驱动程序。 这个驱动程序存在于相应的IDE开发环境中,例如Keil软件,我们只需要将驱动程序的路径指定到相应的目录,即可进行正确的安装。 安装后的设备管理器如下图所示。 这样就完成了驱动程序的安装,我使用的开发板是STM32F030R8,与计算机正确连接后,LD1常亮,LD3常亮,LD2闪亮。
[单片机]
STM32开发笔记7: ST-LINK/V2-1<font color='red'>驱动程序</font>的安装
STM8L的LCD接口详解及驱动程序
STM8L部分型号集成了段式液晶驱动器,可以驱动4*28=112个液晶段.段式液晶屏为低功耗显示器件,功耗根据屏的大小和显示段数会有所不同,通常功耗在10ua左右.生活中,数字电子表,数字万用表,数显温度计等,使用的都是段式液晶屏,通常一颗纽扣电池可以保证设备间隔不断显示数字两年或更久. 大家比较熟悉的液晶屏1602模块其实也是段式液晶,是一个有很多段的点组成的,由于点比较多,所以1602模块集成了驱动芯片,我们只需给1602送数据,就可以控制1602进行显示了.液晶本身不会发光,1602之所以会发光是因为使用了LED背光板. 段式液晶驱动器,通常会含有一个电压泵,一个频率分频器.电压泵用来提供驱动液晶段的电压,电压的高低决定
[单片机]
STM8L的LCD接口详解及<font color='red'>驱动程序</font>
mini2440LED驱动程序开发
/*********************************************************实验源代码 ********************************************************************/ 一、源代码: /***********************mini2440_leds.c*********************** *******************************************************************/ #include linux/miscdevice.h #include
[单片机]
基于WinCE的II2C驱动程序设计
引言   随着以计算机技术、通信技术和软件技术为核心的信息技术的迅速发展,嵌入式系统在各行业得到了广泛的应用,极大地推动了行业的渗透性应用。嵌入式系统是“以应用为中心、以计算机技术为基础、软硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统”,由嵌入式硬件和嵌入式软件两部分组成。嵌入式软件包括嵌入式操作系统和嵌入式应用软件。Microsoft的桌面操作系统已经为人们熟悉和使用,嵌入式的操作系统 Windows CE.net也日益风行。Windows CE.net是Microsoft推出的功能强大的紧凑、高效、可伸缩的32位嵌入式操作系统,主要面对各种各样的嵌入式系统和产品。该系统所具有的多线程、多
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
  • ARM裸机篇--按键中断
    先看看GPOI的输入实验:按键电路图:GPF1管教的功能:EINT1要使用GPF1作为EINT1的功能时,只要将GPFCON的3:2位配置成10就可以了!GPF1先配 ...
  • 网上下的--ARM入门笔记
    简单的介绍打今天起菜鸟的ARM笔记算是开张了,也算给我的这些笔记找个存的地方。为什么要发布出来?也许是大家感兴趣的,其实这些笔记之所 ...
  • 学习ARM开发(23)
    三个任务准备与运行结果下来看看创建任务和任运的栈空间怎么样的,以及运行输出。Made in china by UCSDN(caijunsheng)Lichee 1 0 0 ...
  • 学习ARM开发(22)
    关闭中断与打开中断中断是一种高效的对话机制,但有时并不想程序运行的过程中中断运行,比如正在打印东西,但程序突然中断了,又让另外一个 ...
  • 学习ARM开发(21)
    先要声明任务指针,因为后面需要使用。 任务指针 volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • 学习ARM开发(20)
  • 学习ARM开发(19)
  • 学习ARM开发(14)
  • 学习ARM开发(15)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved