1.导言
ARM微处理器已广泛应用于工业操控、消费类电子产品、通讯体系等范畴。矩阵键盘是一种常用的键盘办法,它将按键规划成M行N列,这样共需M+N根信号线,却可驱动M×N个按键,大大节省了I/O资源。本文介绍了一种运用TQ2440开发板的GPIO口扩展5×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的其他设备中均未运用到,不然会引起该驱动程序或其他驱动程序初始化失利。
考虑到手持终端设备按键的常用性与操作的便利性,只取矩阵键盘的前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嵌入式设备扩展手持终端式键盘供给了一种解决方案。