一个嵌入式Linux系统的键盘驱动实现 (1)(2)

2016-01-29 12:59 15 1 收藏

一个嵌入式Linux系统的键盘驱动实现 (1)(2),一个嵌入式Linux系统的键盘驱动实现 (1)(2)

【 tulaoshi.com - PHP 】

初始化部分。这部分包括硬件层和软件层上的初始化。在本例中,需要先对矩阵电路和SN74hc164芯片所使用到的GPIO端口作配置,以使CPU可以对它们进行控制和访问。为了要将某个GPIO端口配置成输入输出或者是中断源,需要在对应的GPIO控制寄存器中设置正确的值,具体的值可以通过查阅S3C2410开发板手册来获得。比如,为了将GPB1设置成SN74hc164的输入端,需要将GPBCON这个控制字中2,3两位设置成二进制的01,为了将GPG6设置成电压低跳变中断源,需要将GPGCON中12,13两位设置成二进制的10。在完成了硬件初始化操作以后,就是软件层上的初始化了。首先将键盘中断处理函数注册到系统,然后设置好一个定时器结构,以便在中断发生时将其挂到内核的定时器队列中去,该定时器将触发对键盘的扫描操作。最后通过SN74hc164将矩阵电路的16列置零。

中断处理部分。如前所述,这部分软件应该完成的工作就是扫描特殊键盘,确定哪个键被按下,并且拿到稳定的扫描码,然后调用内核导出函数handle_scancode。在这个应用中,该特殊键盘的布局与PC标准键盘的布局比较相似,所以我们直接将PC键盘上对应键的系统扫描码作为我们特殊键盘上各个键的扫描码,同时我们将PC键盘驱动程序中扫描码到键码的转换函数pckbd_translate作为我们的kbd_translate函数。

确定哪一个键被按下的算法如下。在中断到来时,我们已经可以根据中断号确定被按下的键在哪一行,我们还需要确定被按下的键在哪一列。为此,我们先给串联的两个SN74hc164芯片送一个CLR信号,清零,然后送16个1,使得特殊键盘的列均为高电位,此时我们在键盘的行端口读到的都是高电位。在16个时钟脉冲下,给SN74hc164芯片送入1个0和15个1,使得0在每一列上都唯一出现一次,于此同时在键盘行端口进行扫描。当被按下键所在列置0时,其所在行就会读到一个低电位。使用这种“走0法”,我们就可以确定出键盘上哪个键被按下了。但是这种简单的扫描算法还不够,因为在这种类型的矩阵扫描键盘中,键的每次按下和抬起都会有10~20ms(这段时间的长短由硬件特性决定)的毛刺抖动存在,如图2所示,所以为了获取稳定的按键信息,必须要想办法去掉这种抖动,才能避免将用户的一次按键误当作几次按键来处理。去毛刺的一种常见的方法是在有键盘中断到达时,并不立即去扫描键盘,而是先等待一段时间,等跳过毛刺抖动以后再去扫描键盘,其伪代码如下所示:

等待一段时间,跳过抖动;

扫描键盘;

if 键盘上没有键被按下

结束返回;

if 键盘上有键被按下

再次等待一段时间然后检查同样的键是否依然处于被按下状态;

if 同样的键任然是按下

将读到的扫描码返回;

else

直接返回;

这种解决方案固然可行,但是它使用了忙等的方法去毛刺,在忙等期间,系统做不了任何有用的工作。这对于计算资源本身就很有限的嵌入式Linux系统来说,是一种奢侈的浪费。本应用中,我们设计了一种适合嵌入式系统的去毛刺解决方案,使用效果良好。

由于Linux内核提供了定时器队列,所以我们可以使用这种机制来避免忙等,提高系统的性能。当键盘上有键被按下时,键盘中断处理程序首先关闭中断源,进入轮询模式,将一个timerlist对象挂入定时器队列以后就结束了。挂入内核的定时器按时地被触发,它所触发的函数完成以下一些工作:先对整个键盘上所有的键进行一次扫描,并且将扫描得到的结果保存到一个静态2维数组变量snap_shot_matrix[16][4]中。该变量描述的是在本次键盘扫描的这个时刻,键盘上所有键的按下情况。如果某个键没有被按下,即处于松开状态,那么将snap_shot_matrix中对应的值置为0,如果某个键处于按下状态,那么将snap_shot_matrix中对应的值作自增1操作,若该值在自增1以后大于某个预先指定的数,我们就可以认为这是一个稳定值,并且将另一个大小为16*4的2维数组变量current_matrix对应坐标中的值置1,否则置0。这个变量描述的就是当前键盘上按键情况的稳定值了。也就是说我们首先把在本次扫描中得到的采样数据作处理以后保存到snap_shot_matrix中,然后依据该变量中的值,过滤得到current_matrix,通过这样一个过程来做去毛刺处理。在得到了本次扫描的稳定值current_matrix以后,我们将其与上次得到的稳定值previous_matrix作比较,从而确定与上次扫描时相比,此刻键盘上的按键情况是否发生了变化,以及此刻键盘上是否有键按下。如果发现键盘上没有任何键被按下,则打开键盘中断,再次切回到中断模式。如果键盘上有键被按下,并且是不同于上次扫描到的被按下键,我们立刻调用按键处理函数process_key,它会调用键盘驱动中的上层

来源:https://www.tulaoshi.com/n/20160129/1488406.html

延伸阅读
卧室衣柜在卧室中有着举足轻重的作用,根据卧室装修的风格搭配不同款式的、不同色彩的衣柜,在保证 其本身的使用功能以外还有更好的装饰作用。在时下的家居装修中,衣柜设计也是多样化的,开放式衣柜、 嵌入式衣柜等等,个性化的设计也给卧室生活增加不少乐趣。 嵌入式衣柜的优点就是衣柜空间大,节省室内空间,并且可以随心所欲地定制样式...
      好几次看到有人提问问到如何实现 iframe 的自适应高度,能够随着页面的长度自动的适应以免除页面和 iframe 同时出现滚动条的现象,刚好我在工作中也碰到了类似问题,于是上网翻查,东抄抄西看看,弄出来这么一个函数,贴到页面里面就能用了。不敢独享,大家要是觉得有用,欢迎使用 源代码如下 <script type="t...
标签: Web开发
在当今信息社会,各单位都进行信息化改造以顺应社会发展趋势,使自己在激烈的竞争中立于不败之地。电子政务、电子商务在中国如火如荼的开展。高校网站在信息化改造中起了排头兵的作用。高校网站总体架构之下是各个系(学院)或部门网站。系(学院)网站是高校网站重要的子系统。 目前高校系(学院)网站的开发大部分采用IIS+ASP+data...
mini-itx的嵌入式linux开发的第一套设备 包括有:1.atiosys的mini-itx主板一块,cpu via c3 ebga 733Mhz2. 20G 2.5"硬盘一个3.dvd rom一个4.cf to ide转换卡一块5.256M cf卡6.2.5"硬盘线一条 整套设备: 主板: cf to ide
1. dotnet连接fb Embedded Server版本 firebird分为两种版本,一种为安装版一种为嵌入式版本(该版本只需要一个fbembed.dll文件支持即可,此文件一定要是嵌入式版本中的(1.5.2版的文件大小为1489KB),不能使用安装版的fbembed.dll文件) 使用方法: 首先把 fb Embedded Server 的 fbembed.dll 拷贝到应用程序目录下。并且要使用fb.net provid...

经验教程

488

收藏

85
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部