历史上的今天
返回首页

历史上的今天

今天是:2024年10月19日(星期六)

正在发生

2020年10月19日 | 基于ARM的矩阵键盘设计及其linux驱动实现

2020-10-19 来源:elecfans

  1.引言

  ARM微处理器已广泛应用于工业控制、消费类电子产品、通信系统等领域。矩阵键盘是一种常用的键盘形式,它将按键设计成M行N列,这样共需M+N根信号线,却可驱动M&TImes;N个按键,大大节约了I/O资源。本文介绍了一种利用TQ2440开发板的GPIO口扩展5&TImes;4矩阵键盘的方法,并将所有按键重新布局成手持终端的键盘形式,方便操作。


  2.硬件设计

  本设计扩展5行4列的矩阵键盘,如图1所示。其中行线ROW1-ROW5连接S3C2440的中断引脚EINT8,EINT9,EINT11,EINT13,EINT14[1]。这些中断引脚本身连有10kΩ的上拉电阻,把中断引脚电平拉高,确保按键空闲时不会触发中断。列线COL1-COL4连接S3C2440的普通I/O口GPF3,GPF4,GPG7,GPG10.这里需要注意的问题是:确保行线所用的中断在Linux的其他设备中均未使用到,否则会引起该驱动程序或其他驱动程序初始化失败。

  5行4列的矩阵键盘电路原理图

  考虑到手持终端设备按键的常用性与操作的方便性,只取矩阵键盘的前18键,并将它们重新布局为图2的形式。其中Ent键具有二重功能,即确认功能(短按)和开关机功能(长按),此功能将在驱动程序中实现。

  键盘布局

  3.矩阵键盘的Linux驱动程序设计

  3.1 键盘驱动总体概述

  驱动程序是操作系统内核和硬件设备之间的接口。设备驱动程序为应用程序屏蔽了硬件的细节,使应用程序可以像操作普通文件一样操作硬件设备[2]。驱动程序没有main函数,它以一个模块初始化函数作为入口,并且它完成初始化之后不再运行,等待系统调用。


  驱动程序是linux内核的一部分,所以在程序编写上要采用linux的表达方式。首先将列I/O端口定义为数组:col_table [] ={ S3C2410_GPF3,S3C2410_GPF4, …},行I/O端口定义为结构型:

  button_irqs [] ={ {IRQ_EINT8,S3C2410_GPG0,S3C2410_GPG0_EINT8, 0,“R1″},

  {IRQ_EINT9,S3C2410_GPG1,S3C2410_GPG1_EINT9, 1,”R2″},

  …}。//中断号(irq),引脚(pin),引脚设置,序号,名称

  矩阵键盘是作为Linux的一个字符设备注册到系统中的。我们首先向系统注册矩阵键盘设备,包括设备号,设备名及file_operaTIons结构体;file_operaTIons结构体的成员函数是字符设备驱动程序设计的主体内容,这些函数实际会在应用程序进行Linux的open()、write()、read()、close()等系统调用时最终被调用[3]。用户对键盘没有写操作,其file_operations结构体的成员函数为open()、read()、close()、poll()。


  中断的注册和行列初始化在打开键盘时(即open()函数中)实现。注册中断包括:中断号,中断入口程序,中断方式,中断名和代号。关键语句为:request_irq(button_irqs[i].irq,buttons_interrupt,IRQ_TYPE_EDGE_FALLING,button_irqs[i].name,(void*)&button_irqs[i])。IRQ_TYPE_EDGE_FALLING意思为下降沿触发。然后再进行行列初始化:设置行线为中断,使能上拉,在linux中其表达方式为:

  s3c2410_gpio_cfgpin(button_irqs[i]。

  pin,S3C2410_GPIO_SFN2); //设置第i行引脚为中断

  s3c2410_gpio_pullup(button_irqs[i]。

  pin,1); //第i行引脚上拉

  设置列线为输出,置低电平。语句表达同理,由于篇幅所限,这里不再一一列出。

  read()函数实现从设备中读取数据。该函数实现无按键按下时程序进入休眠,关键代码:

  static DECLARE_WAIT_QUEUE_HEAD(button_waitq); //生成一个等待队列头队列,名为button_waitq

  static volatile int ev_press = 0;//置1,表示有键按下

  ev_press为0时执行语句:wait_event_interruptible(button_waitq,ev_press),程序即进入休眠。ev_press为1时把数据从内核空间复制到用户空间,关键语句:

  copy_to_user(buff,(const void *)key_values,min(sizeof(key_values),count));//buff为用户空间的指针,key_values为内核空间指针,最后一个参数为从内核空间向用户空间拷贝数据的字节数,我们取实际大小与用户指定大小中的最小值。数据复制成功时返回零;出错时返回没有复制成功的数据字节数。

  close()函数实现关闭矩阵键盘设备,释放已注册的中断,关键语句:free_irq(button_irqs[i].irq,(void *)&button_irqs[i])。

  Poll()函数实现轮询,如果没有按键数据,调用linux的poll_wait函数等待;如果有按键数据,则select函数会立刻返回。


  3.2 中断处理及键盘扫描程序

  中断处理函数的名称为上面注册的buttons_interrupt.具体程序流程如图3所示。当有按键按下时,该键所在行列导通。列的低电平将该行电平拉低,进而触发中断。然后,进入中断处理函数。由于按键存在抖动的问题,单靠一次中断的触发就判定有按键按下是不可靠的,所以采用定时器延时10ms后再进入键盘扫描函数。

  键盘扫描程序流程图

  本设计的键盘扫描程序采用先确定行再确定列的方法,最后对行列进行一定的运算即得键值。首先确定行:逐行扫描,判断是否有行引脚为低电平。若有,保存该行值(row)。继续确定列:逐列置低电平,当该列为按下所在列时,才会使该行再次为低电平,从而确定列(column)。再对行列进行运算:k=row*4+column,则将矩阵键盘的每一键对应为键号0-19.键盘布局为图2所示形式后,我们只取矩阵键盘的前18键(键号0-17),键值保存为k+1.对于Ent键,通过按下的时间长短区分是确定功能还是开关机功能,按下时间小于0.5秒为确认功能,按下时间大于1.6秒为开关机功能,时间在0.5秒-1.6秒的视为无效操作。计时方法为:

  若该行仍为低电平且整数cnt小于1700:延时1ms,cnt++;根据cnt值即得按下时间。

  开关机功能保存为第18键号,键值19.


  4.驱动程序的测试

  测试程序属于上层应用程序,直接调用键盘驱动程序提供的接口即可实现度键盘的操作。我们调用open()函数实现矩阵键盘设备的打开,再调用read()函数即可将键盘数据读取出来并保存到自己定义的数组中,最后使用printf()函数将测试结果显示出来。

  功运用到笔者的项目中,键盘输入的正确率和反应时间均符合设计要求。


  5.总结

  本文介绍了一种直接从ARM的I/O口扩展矩阵键盘的方法,它无需增加其它接口元器件,设计快速实用,并实现了在Linux系统下的驱动,为ARM嵌入式设备扩展手持终端式键盘提供了一种解决方案。

推荐阅读

史海拾趣

Decawave公司的发展小趣事

2020年,美国RF解决方案的领先供应商Qorvo宣布收购Decawave。这一收购对于Decawave来说是一个重要的里程碑。Qorvo看中了Decawave在UWB技术领域的创新能力和市场潜力,通过收购整合,Qorvo能够更好地将Decawave的技术应用于其移动、汽车、消费类和工业物联网市场的产品中。同时,Decawave也借助Qorvo的全球资源和市场渠道,进一步扩大了其市场份额和影响力。

Aplus Flash Technology Inc公司的发展小趣事

随着全球环保意识的提高,电子行业对环保的要求也越来越高。Aplus Flash Technology Inc公司积极响应环保号召,将环保理念融入产品设计和生产过程中。公司研发出了一款低能耗、环保型的闪存芯片,不仅降低了产品的能耗和碳排放,还提高了产品的可回收利用率。这一创新举措得到了消费者的广泛认可和支持,也为公司在市场上树立了良好的环保形象。

EXCELTA公司的发展小趣事

Excelta公司创立于20世纪90年代初,当时电子元器件市场正处于快速发展阶段。创始人李明看到连接器市场的巨大潜力,决定投身其中。然而,初创时期资金紧张,技术储备薄弱,公司面临巨大挑战。李明带领团队日夜兼程,通过技术创新和成本控制,成功开发出第一款具有竞争力的连接器产品,并迅速获得了市场的认可。此后,Excelta逐渐在连接器领域崭露头角。

Diamond SA公司的发展小趣事

随着全球对环保和可持续发展的关注度不断提高,Diamond SA公司也积极响应这一趋势。他们致力于开发环保型电子产品和技术解决方案,减少对环境的影响。同时,公司还积极参与各种环保活动和公益事业,推动整个电子行业的绿色发展。这些努力不仅提升了公司的社会形象和声誉,也为公司的长期发展奠定了坚实的基础。

敦泰(FOCALTECH)公司的发展小趣事
电冰箱不制冷可能由多种电路问题引起,如电源线路故障(如插头未插紧、插座无电等)、压缩机启动电路故障(如启动器损坏、压缩机线圈断路等)、温控电路故障(如温控器失灵、温度传感器损坏等)或制冷系统电路故障(如制冷剂泄漏、毛细管堵塞等)。建议首先检查电源是否正常,然后逐步排查压缩机、温控器和制冷系统电路。
Global Navigation Systems公司的发展小趣事
减少远程无线防盗报警系统的误报率可以从以下几个方面入手:首先,选择合适的探测器和安装位置,避免将探测器安装在易受干扰或误触发的位置;其次,合理设置探测器的灵敏度和报警阈值,避免过度敏感导致误报;最后,定期对系统进行维护和检查,及时发现并排除潜在的故障和隐患。

问答坊 | AI 解惑

倒计时程序有问题

《无线电》2004年第9期(带光盘)有一个99分钟89C2051倒计时程序,2个数码管显示,我按其作了一个,并将其光盘上的程序拷入,实际运行结果出现这样一个问题:     就是十位和个位到0后并没有停止(停止时显示‘--’2个负号),而是继续显示‘ ...…

查看全部问答>

ARM与嵌入式linux入门的建议

本帖最后由 paulhyde 于 2014-9-15 08:56 编辑 ARM与嵌入式linux入门的建议  …

查看全部问答>

射频电路板设计技巧

成功的RF设计必须仔细注意整个设计过程中每个步骤及每个细节,这意味着必须在设计开始阶段就要进行彻底的、仔细的规划,并对每个设计步骤的进展进行全面持续的评估。而这种细致的设计技巧正是国内大多数电子企业文化所欠缺的。     近几 ...…

查看全部问答>

如何控制LED静电死灯?

replyreload += \',\' + 380148;Timson,如果您要查看本帖隐藏内容请回复…

查看全部问答>

供S5PC100开发板 ARMcortex A8 core

供S5PC100开发板 ARMcortex A8 core iPhone 3GS 采用Samsung S5PC100主控拥有720p高清视频engineering, 在iPhone中Apple特意降低了处理器运行频率为600MHz,以减少功耗。 显然S5PC100的拥有很强大的处理功能,包括3D engineering S5PC100集多 ...…

查看全部问答>

嵌入式软件开发工程师

汉王科技股份有限公司 嵌入式软件开发工程师-OCR软件部 电子邮箱:          yinsg@hanwang.com.cn 发布日期:         2007-03-21         工作地 ...…

查看全部问答>

iar442不能设置断点是怎么回事啊?

                                 rt…

查看全部问答>

有什么好办法解决STM32RTC不起振么

                                 最近焊了一批板子,那个RTC的晶振死活不起振,十个里面只有一个能起来,其他的怎么弄都起不来。原来在别的板子上好 ...…

查看全部问答>

PR788应用于LED路灯设计

简介:德州仪器电源管理产品经理Pietro Scalia为您简述一款LED路灯板。通过分析PR788参考设计电路图使你更清楚的了解到这个设计是如何实现更节能的目的的   $(\'swf_cT7\').innerHTML=AC_FL_RunContent(\'width\', \'550\', \'height\', \'4 ...…

查看全部问答>

三极管电路分析

请大虾们帮忙分析下,怎么理解?…

查看全部问答>