键盘与驱动

2024-06-23

键盘与驱动(精选七篇)

键盘与驱动 篇1

键盘作为一种常用的输入工具,不但在PC机中是标准配置,在许多嵌入式系统中也是需要的。但是,嵌入式系统一般是针对具体应用而设计的,各种应用对输入设备的要求也各不相同。因此需要根据具体应用在嵌入式系统中扩展自己的键盘。

Linux具有源代码开放、稳定、高效、成本低廉、便于裁减定制、硬件支持广泛等优点,目前已迅速崛起成为嵌入式领域的一匹黑马。

国内广泛使用的Samsung的嵌入式处理器S3C2410x采用了ARM920T内核,核心频率最高可以达到203MHz[1],处理器内部集成了IIC总线、LCD、UART、DMA、PWM、定时器、GPIO口、USB主/从等控制器。它为手持设备和一般应用提供了低价格、低功耗、高性能的小型微控制器解决方案。本文结合当前嵌入式Linux应用的热点,在分析键盘硬件的基础上,深入讨论如何在linux操作系统里实现一个S3C2410x处理器的键盘驱动,并给出了具体的实现方案。

2 键盘的硬件

本系统采用一个5*4键盘,控制芯片是ZLG7290,它是周立功公司针对仪器仪表行业需要自行研制的一款芯片。该芯片能自动完成8位LED数码管的动态扫描和最多64(8*8)个按键扫描检测,大大减轻了嵌入式系统用于键盘处理的工作时间和程序负担,使它能集中资源进行信号的检测和控制。

ZLG7290芯片与处理器S3C2410x之间采用IIC总线方式通讯,见图1,所以对键盘的控制可通过操作IIC总线来实现。完成了IIC总线驱动的编写之后,只要设置IIC从设备地址为ZLG7290地址就能够与ZLG7290芯片建立通信。

键值读取采用中断方式,在键盘按下后在INT引脚产生中断触发电平通知处理器(键盘动作由芯片ZLG7290检测),之后处理器通过IIC总线读取芯片ZLG7290键值寄存器中保存的键值。

3 IIC工作原理

IIC(Inter-IC)总线是Philips公司推出的一种同步串行数据传输的标准总线,其标准总线传输速率为100kb/s,增强总线可达400kb/s,总线驱动能力为400p F。它是同步通信的一种特殊形式,具有接口线少、控制方式简单、器件封装形式小、通信速率较高等优点。IIC总线包括两根双向信号线:串行数据线(SDA)和串行时钟线(SCL)。SDA主要用于数据传输,SCL主要用于时钟同步。

按照总线规范版本的不同,IIC总线可构成多主和主从系统。在多主系统中,总线本身提供了一种冲突检测的方法,当多个挂载在总线上的设备试图控制总线进行通信时,IIC能够有效地管理多个挂载在总线上的设备。本系统中,IIC总线采用主从结构,即总线上只有一个主控节点,其它设备都是从设备。总线上设备的寻址由器件地址连线决定,与总线相连的每个器件都对应一个特定的地址,采用软件寻址方式,并且通过访问地址的最低位来决定读写方向。

S3C2410x提供了符合IIC协议的双向数据线IICSDA和IICSCL在主机总线和连接到IIC总线的外部设备之间传递信息,在IICSCL高电平期间,IICSDA的下降沿触发一个“START”状态,IIC总线变成“忙”。在IICSCL高电平期间,IICSDA的上升沿触发一个“STOP”状态,IIC总线变成“闲”。“START”和“STOP”状态只能由主设备触发,当开始数据传输时,一个7bit的地址被放在第1个被传输的字节中,决定与哪个从设备通信。剩下的第8bit指示传输的方向(读或写)[2]。在SDA线上传输的数据以字节为单位,每接收或传送一个字节都会紧随一个确认位(ACK),其数据格式见图2。在总线上传输的字节数没有限制。

4 IIC驱动程序结构

L i n u x系统中,每个打开的文件都继承了某类文件操作表,用户基于该文件的函数操作表来对该文件操作,对于设备文件来说,文件对象继承了它的主设备号所在驱动程序的文件操作表。设备的文件操作表是设备驱动的起点,但往往并不在这个层次上直接完成设备操作。而是采用了分层设计的思想[3]。如果在某个层次上对不同对象的某类操作具有某种共性,那么就可以像提取“公因式”那样将这类操作抽象出来,然后建立更低一级的操作层次来区分不同的对象,这样就形成了不同层次的驱动接口。

在Linux中,IIC驱动程序在drivers/IIC目录中,分为若干模块,如图3所示。其中,IIC-core是核心模块,定义了对总线及其设备进行操作的各种函数,在源代码中是IIC-core.c文件。IIC-proc是在proc文件系统中建立IIC总线及其设备接入点的文件,由IIC-proc.c文件构成。IIC-dev模块负责在/dev文件系统中建立IIC总线及其设备的接人点,它可以让IIC设备的驱动程序在用户空间可见。以上3个模块是硬件无关的,对所有的系统通用。

图中的IIC adapter/algo驱动实际上对应两个模块:适配器(adapter)和算法(algorithm),它们合在一起用于IIC总线的驱动,为IIC-core提供底层支持,是硬件相关的。不同的嵌入式系统,这两个模块的实现是不同的。

IIC client模块是连在IIC总线上的具体设备的驱动程序,它建立在IIC-core模块之上,与adapter和algorithm模块无关。每一种设备都有自己的IIC client驱动,因此它是硬件相关的。

从图中可以看出,这些驱动程序都在Linux的内核空间,它们的共同作用是使用户能在用户空间操作IIC总线及其设备。

5 IIC驱动程序设计

对具体的嵌入式系统,IIC驱动主要是实现与硬件相关的adapter,algorithm和client driver模块的程序设计。

5.1 adapter模块设计

adapter模块的功能是实现一个adapter数据结构并初始化,使IIC-core能找到IIC总线,并利用其提供的地址找到算法来具体操作总线。adapter数据结构在include/l i n u x/I I C.h中定义。具体的系统是通过其n a m e,i d,algo_data来区分的,其中algo_data实际上是算法的一些数据,在algo头文件(如include/linux/IIC-algo-s3c2410.h)中定义。具体实现根据IIC总线的硬件实现而不同。

本文在设计时,把这部分合并到了算法模块中。具体为初始化了一个struct s3c2410_IIC_adapter结构和一个struct s3c2410_IIC_algo_data结构,定义了这两个结构中的函数指针成员,并用已初始化的s3c2410_IIC_algo_data结构来初始化struct IIC_adapter结构中的algo_data成员变量。本文初始化的s3c2410_IIC_adapter结构为:

5.2 算法(algorithm)模块设计

算法模块主要是描述如何在IIC总线上传输数据。它通过数据结构struct IIC-algorithm(在include/linux/IIC.h中定义)决定数据传输的基本方法。该模块需要实现的函数见图4。在内核源代码drivers/IIC目录下有很多algorithm模块程序,设计具体硬件设备的算法程序时,可参考它们。

5.2.1 算法模块的初始化函数实现

在系统初始化时会执行module_init(IIC_s3c2410_init)函数从而调用IIC_s3c2410_init()函数,完成对中断、IIC特殊功能寄存器及其相关结构的初始化,最后调用上层提供的IIC_add_adapter()函数将s3c2410_IIC_adapter注册到IIC的设备驱动程序中,即添加到全局数组adapter中。adapter是内核中维护的一个表述IIC总线的全局数组。

同样的,当要卸载IIC驱动时,需要反初始化IIC的特殊功能寄存器,释放所申请的中断处理程序,并从adapter数组中删除相应节点。

5.2.2 数据传输函数的实现

IIC总线作为一个同步串行数据总线,其主要功能是实现数据的接收和发送,在IIC_core()中已实现了其总线级的数据传输函数IIC_transfer(),但在基于具体的总线设备进行数据传输时还需要实现其底层的硬件数据传输程序。本文主要是实现了s3c2410_IIC_algo结构中的主设备数据传输函数master_xfer(),这个函数通过s3c2410x IIC总线接口完成数据的收发。上层设备驱动程序就是最终通过调用master_xfer()来响应系统read()/write()调用的。

本文IIC总线采用主从结构,有主发送和主接收两种模式,这样就不需要多主系统中的总线仲裁,但是当多个从设备都要利用IIC总线传输数据时,需要实现对总线是否占用的检测和数据是否已经传输完毕的检测。本文对总线是否占用的检测采用信号量方法实现。对于数据是否已经传输完毕的检测采用中断方式来完成。

(1)master_xfer():所有数据的读写都调用这个函数,这个函数再根据读写标志位,调用IIC_s3c2410_readbytes()或IIC_s3c2410_writebytes()。

(2)IIC_s3c2410_readbytes():按照第2节中介绍的算法从IIC总线上读数据。

(3)IIC_s3c2410_writebytes():按照第2节中介绍的算法将数据写到IIC总线上。

在读写程序中,首先判断总线是否空闲,若总线空闲则清零ACK标志,接着进行数据读写传输,1字节数据的读写完成是根据ACK标志是否置位来判断的。因此,读写数据之后都需要等待应答位信号ACK的到来,以确定数据是否已经正确地写出或读回了。每个ACK应答或生成时,IIC接口单元控制器产生中断,中断服务程序被调用,中断服务程序就是置ACK标志。

此外对于数据是否已经传输完毕的检测还可以采用轮循方式检测,如果IIC总线上的设备并不是很长时间地占用总线,采用该方式也未尝不可。但由于IIC总线本身速率不高,如果总线设备需要传输较多的字节,采用轮询方式不断查询数据是否已经传输完毕将导致驱动程序在内核空间运行时长时间陷入循环等待,从而使整个系统的效率降低[4]。

5.2.3 数据传输控制的实现

为方便控制IIC总线,本文还实现了控制数据传输的自定义参数设置过程函数algo_control(),完成对通信从设备内部访问地址的设置和数据传输时钟频率的设置。通过此函数可响应系统ioctl()自定义参数设置的调用。如:

5.3 IIC client driver设计

这是具体设备的驱动程序,它利用IIC_core.c提供的函数来实现对具体设备的操作。这个程序主要需要实现struct IIC_driver结构并初始化设备。

5.4 IIC驱动程序的配置与编译

将编写好的IIC总线驱动的头文件和源程序文件分别保存为IIC-algo-s3c2410.h和IIC-algo-s3c2410.c,并将它们放在/kernel/dirvers/IIC目录下。如果要编译进Linux内核,还要对配置文件config.in和Makefile脚本文件进行修改。

最后,通过配置编译命令将IIC驱动编译进Linux内核。重新启动系统后,编写应用程序就可以操作键盘了。

6 基于IIC总线的键盘程序的实现

设计完成了IIC驱动后,键盘就可以作为一个IIC总线的从设备进行操作了,其从设备地址为0x70。由于是作为从设备来操作的,只能采用循环方式读取。程序流程见图5。

此外,我们还可以在IIC client driver中实现键盘设备的驱动。但是对于一般的应用,我们只要将键盘作为IIC总线的从设备,对其进行操作控制就可以了。

7 结束语

本文深入地研究了在嵌入式Linux平台上编写键盘驱动的设计过程,系统采用IIC总线控制键盘芯片,完成键值读取。通过这种方法开发的键盘驱动程序可在L in ux操作系统下稳定运行,并取得了良好的效果。该设计的实现使得此键盘可应用在嵌入式开发的多种领域,因此具有实用价值。

参考文献

[1]S3C2410X 32-Bit RISC Microprocessor USER'SMANUAL[Z].Revision 1.2 SAMSUNG Electronics,2003.

[2]田泽.嵌入式系统开发与应用教程[M].北京:北京航空航天大学出版社,2005.1.

[3]ALESSANDRO RUBINI,Jonathan Corbet.Linuxdevice drivers[M].2nd Edition.O’eilly,2001,251-260.

[4]田泽.嵌入式系统开发与应用实验教程(第二版)[M].北京:北京航空航天大学出版社,2004,6.

[5]朱华生,叶军.嵌入式系统IIC设备驱动程序设计与实现[J].微计算机信息,2006,(29:)170-172.

MIDI键盘的配重与选择 篇2

【关键词】MIDI键盘;手感;力度感应;配重;半配重;全配重

文章编号:10.3969/j.issn.1674-8239.2016.05.007

【Abstract】Through analysising the structure of without weight, semi weight and total weight MIDI keyboard and understanding their sense of strength, the MIDI keyboards with right feeling is selected.

【Key Words】MIDI keyboard; feel; intensity; weight; semi weight; total weight

MIDI(musical instrument digital interface),译作乐器数字接口,是一种通信协议。MIDI可以说是现代电声乐器的经脉,有MIDI,全世界的电声乐器才能在一起。MIDI键盘(图1①)是输出MIDI信号的键盘,从使用形式上来说,与计算机键盘有点类似②。

由于简洁、直观、方便的控制功能以及无限自由扩展的音色,现在越来越多的乐队键盘手选择使用MIDI键盘而不是传统的键盘合成器来做现场演出和音乐制作。③

那么,如何选择适合演奏者演奏风格、乐曲风格的MIDI键盘?下面通过分析无配重、半配重以及全配重MIDI键盘的结构,了解各自的力度感,从而选择手感适合的MIDI键盘。

1 键盘手感的分类

选购一款MIDI键盘,手感是非常重要的考量因素,因为手感会影响到乐手能否顺畅演奏音乐,以及对于细腻之处的表达。目前市面上的MIDI键盘手感,主要分成无配重、半配重以及全配重三种,分别具有不同的特点,适应不同的人群和演奏需求。

关于手感的选择,通常与乐手的演奏习惯、演奏风格有关。比如熟悉了钢琴的手感,转而弹奏没有配重的MIDI键盘,就会不习惯,这时就需要一款全配重的键盘,手感与真实的钢琴非常接近。再比如要在演奏中进行速弹,展示一段超高速炫技Solo,全配重键盘按起来可能有些费劲儿,这时就需要一个手感很轻、回弹快的无配重键盘,让弹奏更加轻松。

而结构最简单、手感最轻的无配重手感键盘出现的时间最早,经历了一系列发展才有了全配重的概念。

2 不同手感键盘的特性

2.1 无配重键盘

2.1.1 力度感应从无到有

说起乐器的力度感,从中世纪无力度感的键盘乐器,到后来能够表现出一定的力度,再到后来钢琴的出现和工艺的进一步发展,力度感表现已经非常的丰富。

钢琴出现于18世纪初期,采用独特而复杂的机械联动结构,并带动琴槌敲击琴弦的方式发声,具有相当出色的力度动态范围,允许钢琴手进行丰富的感情表现,钢琴也一直享有“乐器之王”的称号。

早期的MIDI键盘,无所谓配重、手感的问题,力度感应的功能不具备。也就是说,按下这个键,它就会接通一条电路发出一种声音,松开电路就断开了,只有响和不响两种选择,至于声音大小,这不是靠琴键能控制的。早期的合成器也是所谓No-Dynamic(无力度感应)的。

随后,键盘设计师、工程师为MIDI键盘加上了一个速度感应器(图2),键盘的移动速度越快则声音越响,达到了力度感应的目的。速度感应装置的结构非常简单(图3),它有两个位置感应点,键盘通过两点所需要的时间可以算出移动速度,从而根据速度发出一定响度的声音。而键盘下面还需要弹簧顶着,让键盘按下后还可以回弹。

目前市面上无配重键盘大致都是这样的基本结构,说到力度感应时,通常指的是英文中的Velocity-Sensitive,即速度感应。而其他的还包括有位移距离感应、压力感应等方式,不过最常见的还是简单又好用的速度感应。

2.1.2 无配重键盘的手感

无配重键盘通常给人以廉价、手感一般的印象,因为从机械结构上来说,它确实非常简单,同等的工艺规格来说造价要比配重键盘更低。但并不能因为造价低而认定它的手感差,更重要的是看是否合适,适合不同的人、不同的演奏习惯、不同的音乐风格,甚至是要适合乐曲中不同的乐段。

无配重的键盘常常使用塑料材质键盘,相比于钢琴键盘常采用的实木材质,手感非常轻盈,且回弹速度非常快,弹奏起来轻松不费力,适合速弹演奏,比如摇滚或Funk乐中急速的Solo段落,用无配重键盘来演奏就会感觉更加轻松些。

另外,对于没有钢琴基础的音乐人来说,上手无配重键盘也并不会有不习惯的感觉。但是对于有一定钢琴基础的乐手来说,这手感可能就相当糟糕了,毕竟其原理和结构与钢琴完全不同,导致手感差异特别大。

MIDI键盘演奏者享受到了力度感应带来的福利,可以通过手指的缓急来控制音量,演绎出更加丰富的顿挫感和动态感。但是,有些演奏者对钢琴键盘更有感觉,因此对软绵绵、轻飘飘手感的电子键盘提出了更高的要求。

2.2 半配重键盘

2.2.1 配重的出现

为了让轻盈的塑料键盘手感更真实,人们想出了一个最直接的办法,为键盘加重量——往键盘里装一些金属块(图4)。金属重块直接镶嵌在键盘下面,为钢琴带来一定的重感。

这种为键盘直接进行配重的方式,称其为半配重,它的力度感应原理和无配重键盘如出一辙,同样是用键盘的移动速度来作为声音大小的依据,只不过是让它的手感不至于太轻飘。

当时市场对于仿真实手感的键盘需求很强,配重键盘一经推出便得到了市场的追捧,但刚推出时仍有一个很严重的问题,就是重量实在不容小觑,一个88键的全音域配重键盘通常在二三十公斤,携带演出很不方便。现在这种状况有了很大改善,如KeyStation 88这款半配重全音域键盘重量也就在10公斤左右。

nlc202309091003

2.2.2 对半配重键盘的评价

半配重键盘常被认为是介于全配重与无配重之间的折中方案,既能保留些许的真实钢琴手感,又不会有太高的价格。但它的手感还是相当独特的。它从无配重手感中取走了速度感应式的发声方式,以及全音域手感无差别,即高低音符的手感不会有轻重差异的两个主要特点;而从真实钢琴手感中汲取了更重的手感,相比于轻盈的无配重,演奏时手指需要更用些力气,会产生出一种让一些人感到舒服的回馈感。

综合来说,半配重的到来,了却了钢琴键盘手们的顾虑,它带来的阻尼感,让弹奏时不再有那种有劲使不出的感觉了。半配重和全配重相比,手感还是有自己的个性的,目前的使用也很广泛,并不能认定它就是一个高不成低不就的杂交品种。

2.3 全配重键盘

2.3.1 钢琴的特殊手感

原声钢琴的琴键是机械结构,通过琴槌与琴弦的物理接触来发声,而其中的每个零件都会对手感有一定的影响,因此不同种类的钢琴,甚至每架钢琴的手感都可能不同,但是仍然可以总结出一些共有的特性。

(1)非线性效应

由于弹奏的整个物理过程和联动装置十分精密也颇繁杂,有许多个杠杆、支点、弹簧、琴槌和减振器等,这种复杂的物理过程会造成这样的结果——弹奏的力度和最后的声音是非线性的关系,即力度-响度曲线是非线性的,用一个力度弹和两倍的力度弹,它出来的声音不一定是倍数关系。

(2)不同琴键不同手感

钢琴从低音到高音,琴弦的长度有所不同,琴锤杠杆的长度和重量也会有差异。最后会导致低音区琴键的手感与高音区的手感有差别,弹奏的音符越高,手感会更轻,阻尼感小,而弹奏低音符时,手感重,阻尼感大。

(3)弹响琴的门槛力度

重重的按下琴键,琴槌会重重地砸在琴弦上而发出很大声音,而用中等力度,声音则会小一些。但力度减小到一个临界值,这个杠杆可能就没有足够的力度驱动琴槌敲击琴弦,从而不出声。这也就是说,钢琴有一个最小力度的阈值,或门槛,只有弹奏力度超过了这个阈值才能出声音。

(4)惯性效应

由于琴槌是经过了一定的运动距离,才砸到琴弦上发出声音的,因此在这个运动过程中就有了惯性效应。对于演奏者,可以利用惯性效应进行一种特殊的弹奏,用力按下琴键但不按到底便立刻松开,虽然深度很浅,琴槌也会因为有较高初速度形成的惯性而去敲击琴弦,继而发出声响。

(5)琴槌琴弦一拍即散

琴槌砸向琴弦后,会因为回弹力而立刻离开琴弦,即便一直按着琴键到底不放手,琴槌也会毅然决然地离开,随着琴槌的下落就会产生一点送劲儿的感觉,这也是非常微妙且细致的手感。

(6)弱音器带来的微妙重感

按下琴键后弱音器会抬起,松开后弱音器又落在了琴弦上。而按下琴键一直不动,它会有很长的延音,因为弱音器此时是抬起的。琴键的末端会有一个抬起消音器的动作,这对手感也会有很微妙的影响。

2.3.2 全配重键盘对钢琴手感的模仿

为了满足钢琴演奏者的手感要求,需要尽可能地将钢琴中的机械结构移植到MIDI键盘中。其中有两个基本要素:一是杠杆带动琴槌的物理结构,即所谓的锤感是钢琴手感中很重要的部分;二是不同音高的琴键不同配重,这也是一个保留项目。至于其他更细微的点,比如2.3.1中的(5)、(6)两项,有时候会被忽略,因为它们对于手感来说影响并不大,都是很微妙的东西。一些高端型号的全配重可能会将其考虑在内。

(1) 杠杆—琴槌机械结构

按下琴键后会带动一个联动装置,当然也会装有一个琴槌和一个敲击点来代替琴弦。不同的品牌其内部机械结构不尽相同,以Casio为例来说明。

从Casio Privia系列全配重电钢琴的结构示意图(图5)可以看到其结构并不算复杂,只是经过了一个杠杆结构就可以带动琴槌了。因此售价也不高。

而其CELVIANO系列电钢琴的配重技术定位更高端一些,从原理图(图6)上看机械结构差别不大,传感器位置有所不同。从官网上看,它们都以模仿卧式钢琴的手感为主。而CELVIANO系列对音色的挖掘更深,包括相邻琴弦的共鸣作用、不同键区琴槌响应时间、指尖离开瞬间音色变化、琴盖打开关闭时的音色变化等,主要是在音色上的差异。

(2)不同的音高加上不同的配重

为了模仿钢琴的这一特性,主要以使用不同重量的琴槌来实现,实现此功能并不算复杂。

但需要注意的是,一般常见的全配重是Graded-Hammer(逐级配重),即按组区别配重,同组按键手感相同,此所谓逐级配重。另外,还有Progressive Hammer(逐个配重),每高一个音符,琴键的手感都会有差异,对真实钢琴的模仿更加细致入微,不过这么做的型号似乎并不算多。

(3) 多传感器的使用

更多位置摆放传感器,能够更好地模仿细微的手部动作,比如惯性效应、指尖离开琴键的变化等,细节处理更到位,带来音色变化。

3 用武之地

3.1 无配重键盘

首先,无配重键盘售价相对较低,而不具备原声钢琴的手感,适合没有钢琴基础的初学者上手,或者是乐队中的吉他手用来丰富乐队的配器等。

其次,它有着轻盈的手感和比较快速的回弹,速弹手们可以用它来进行激情的Solo演奏,当然前提是没有钢琴基础。

最后,也是非常重要的一点,它的体重相对于配重键盘十分轻便,对于演出或排练、出门进行旅途创作等移动便携的需求,无疑会更适合。

3.2 半配重键盘

被认为是想要全配重键盘,但又囊中羞涩的钢琴手适合的类型,在花费不太多的情况下有着接近真实钢琴的手感,是一种折中方案。

半配重键盘有着自己独特的手感,结合了无配重和全配重两种手感的一些特色,硬说它不伦不类那也无可厚非,但半配重手感已经在很多高端键盘中得到使用。

目前,市面上一些高端键盘常常被注明有Synth Action(合成器手感)这个词汇。简单地说一下这个词的概念。之前人们可能会被某些网站的说法所误导,认为无配重和Synth Action是等同的。其实不然,这种手感主要包含两个充分条件:弹簧回弹和速度感应,为键盘加了重块成为半配重,它依然是靠弹簧回弹和速度感应,因此它还是Synth Action。

3.3 全配重键盘

将真实钢琴的机械结构移植到电子键盘内,从而更加真实地模拟钢琴的手感,满足钢琴手们的需求,也是目前高端电子键盘的代表,最高端的型号基本都会上全配重。

钢琴手或者是想通过电子键盘过渡到钢琴演奏的人们,选择一款全配重键盘是必须的。

4 结语

通过对MIDI键盘每种配重方式的基本原理和手感特征的了解,相信对键盘选购能起到一些帮助,但是真正具体到每个品牌、每个型号的键盘,即使属于同一种类的配重,手感也可能会千差万别。如果有条件,在实体店亲手一试,便可知道自己真正喜欢哪一款键盘的手感,毕竟适合的手感能让演奏更加舒畅自如,对于音乐中最重要的技巧、情感表达是十分重要的。

注释:

① 本文所选用的配图全部来源于网络。

② 来源于https://zhuanlan.zhihu.com/p/19593176.

③ 同②。

作者简介:

宋鹏,草莓地音乐网主编,主要负责撰写音乐制作相关的技术文章,翻译国外优秀的混录、编曲教程;并作为音乐制作人和摇滚乐队的吉他手,从事音乐制作和表演相关工作。

键盘与驱动 篇3

随着嵌入式系统的飞速发展,嵌入式PC在许多领域得到广泛应用。其中嵌入式键盘作为一种人机交互工具,有着非常重要的作用。通常的键盘设计采用阵列的设计方式,例如一个含有9个键值的键盘需要6个通用I/O口来实现通信。键盘的键值越多,需要的通用I/O口也越多。

I2C(Inter-Integrated Circuit)总线是一种由Philips公司开发的2线式串行总线,用于连接微控制器及其外围设备。I2C总线最主要的优点是其简单性和有效性。由于接口直接在组件上,因此I2C总线占用的空间非常小。I2C总线的另一个优点是,它支持多主控(multimastering),其中任何能够进行发送和接收的设备都可以成为主总线。一个主控能够控制信号的传输和时钟频率。但在任何时间点上只能有一个主控。

I2C的这些特点使得在许多设计中备受青睐,本文所介绍的MAX7347-7349系列芯片,即是一款I2C兼容芯片。它将键值扫描等一系列操作封装在芯片内部完成,CPU只需要通过I2C总线与芯片通信,通过向芯片写入一定的命令完成某些操作。从而简化了键盘驱动的处理。而且由于I2C支持多主控,因此不影响系统其他设备的操作。整个过程只需要3个通用I/O口与CPU通信,可以处理多达64个键值的响应,有效地节省了通用I/O口。

2 基本原理

2.1 键盘驱动实现原理

通常的键盘采用矩阵式原理,例如对于一个含20个键值的键盘,采用4×5的矩阵阵列,即4行5列。其中行和列直接与CPU的I/O口相连,4个I/O口作为中断I/O口。一旦外部有键按下,就会产生中断,由于键盘被按下后,该键对应的行和列被连通,因此根据判断各列对应的I/O口的电平,可以得到被按下键的位置,从而采取相应的响应。

本文所采用的MAX7347-7349系列芯片内部有一个FIFO队列,他在内部完成按键去抖、扫描键值、按键自动重复,以及某些时刻报警等一系列复杂的操作,而键盘驱动本身是需要通过发送一系列的命令来得到所需要的某些状态值,从而进行相应的操作。

2.2 I2C总线通信原理

I2C总线是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。各种被控制电路均并联在这条总线上,每个电路和模块都有惟一的地址。CPU会发出地址码用来选址,即接通需要控制的电路。所以,各控制电路虽然挂在同一条总线上,却彼此独立,互不相关。

I2C总线定义了严格的传输信号来完成一次传输。

开始信号:当SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。

结束信号:当SCL为低电平时,SDA由低电平向高电平跳变,结束传送数据。如图1所示。

注意:SDA线上的数据状态仅在SCL为低电平的期间才能改变,SCL为高电平的期间,SDA状态的改变会被识别为起始和停止条件。

应答信号:接收数据的IC在接收到8 b数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。CPU向受控单元发出1个信号后,等待受控单元发出1个应答信号,CPU接收到应答信号后,根据实际情况做出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。如图2所示。

3 具体实现

3.1 接口电路

如图3所示MAX7347芯片电路示意图。

其中11个脚为键盘阵列输入连接到键盘外设,3行8列,最多可以控制24个不同按键。3个脚与PXA 270直接通信,INT为中断脚,按键按下为低电平,SCL为I2C兼容串行时钟输入,SDA为I2C兼容串行I/O口。

当有键按下时,连接到键盘的11个脚会有电平的变化,芯片会根据电平的变化得到按下键的键值,然后存放在芯片内部的FIFO中,同时把INT脚下拉为低电平。此时键盘驱动在检测到INT变低之后会通过SDA向芯片发送一系列命令,芯片通过SDA传回给驱动相应的状态及值。SCL和SDA的电平变化严格遵循2.2节介绍的I2C总线通信信号规律。

3.2 软件实现框架

Windows CE操作系统驱动层分为MDD层(Model Device Driver,模型设备驱动)和PDD(Platform Dependent Driver,平台相关驱动)两层,框架结构如图4所示。MDD层是抽象出来的一些功能,不与硬件直接相关,他接收PDD层传来的数据,完成处理得到的键值,发出消息通知处理处理响应操作的程序,PDD层与硬件直接相关,实现硬件接口以及获得的硬件特性传递给MDD层。

驱动实现流程,PDD层主要实现键盘的监控,开辟两个线程,线程MaxKeyCheckPro监控INT脚的电平变化。当有键按下,INT拉低,此时在I2C总线准备完毕的情况下,通过I2C总线发送读取键值的命令读取芯片的FIFO,芯片在接收到命令之后会将FIFO中存储的键值通过I2C总线发出传回给线程MaxKeyCheckPro,同时发出通知给线程KeybdIstThreadProc,将传递回来的键值传给线程KeybdIstThreadProc,再由线程KeybdIstThreadProc负责将键值传给MDD层,MDD层负责存储键值,并发出消息通知相应的程序对键值做出响应。

采用两个线程的目的是让各自完成自己的操作,不会造成相互的影响,在按键频繁触发的情况下,线程MaxKeyCheckPro可以在快速得到键值传递出去之后立即等待下一次按键的发生,不会因为在处理其他的操作而使得下一次按键的响应有所延迟。

3.3 I2C总线的通信流程

由于按键的频繁按下会导致不停地使用I2C总线读取芯片FIFO,所以防止2次读写之间的干扰(即在一次读写没有完成之前另一次读写操作也占用I2C总线,两次的数据会造成紊乱)是一个重要的问题。

针对一次读写操作,考虑到其不可打断性以防止数据的破坏,采用mutex互斥锁。即每次只允许1个读写操作占用I2C总线。在1次读写操作开始之前,等待互斥锁,直到读写操作完毕,释放互斥锁。这样当在一次读写没有完成之前,另一次读写无法占用I2C总线,而只能等待。具体流程如图5所示:

3.4 具体读写操作

这里的键盘驱动与普通键盘驱动不同,不需要通过判断键盘矩阵的电平变化来得到键值,这些操作由芯片内部完成。键盘控制器对按键操作去抖并且自动存入FIFO中,因此所需要做的操作就是在检测到键盘按下之后读取FIFO。如图6所示。

但值得注意的是,每次按键按下之后,INT脚会被拉高,但是只有在将FIFO清空之后INT才会被拉低,拉低之后如果继续有键盘按下,会继续把键值存放在FIFO中。所以每次的读取操作需要清空FIFO。但是在实际应用中发现当键盘在被快速按下时,对于FIFO中的操作都做出响应会影响系统的性能,所以选择丢掉FIFO队列中其他键值,只保留最后一个。

4 性能分析

整个过程CPU通过3根主线和芯片通信,实现了按键操作的快速响应和处理,可以控制最多达64个按键的防抖及响应,由于芯片封装了一部分功能,由硬件来处理使得速度变快。由于I2C的多主控特点,不会影响挂在I2C上的其他外设的工作和性能。

5 结 语

本文介绍基于PXA270处理器和Windows CE 5.0操作系统上的键盘驱动的设计和实现。目前已经在本平台上稳定运行,具有很好的按键处理能力。

摘要:键盘是嵌入式系统中非常重要的一个组件。该设计基于Windows CE5.0操作系统、PXA270处理器,采用MAX7347芯片,以I2C总线通信为基础。不同于通常的扫描式键盘阵列,键值的扫描由芯片处理。芯片作为为I2C的外设器件,驱动通过与CPU的通信完成对键盘操作的管理。这种设计可以实现多达64个按键的管理,与CPU通信只需要3条总线,有效地节省了GPIO口。把一部分原先需要软件完成的工作放到硬件中完成,提高了按键处理速度。实验结果表明采用此方案键盘的处理速度迅速、有效、可行性很高。

关键词:嵌入式系统,I2C,MAX7347,键盘与驱动

参考文献

[1]傅曦,陈黎,董磊鋆,等.Windows CE嵌入式开发入门基于Xscale架构[M].北京:人民邮电出版社,2006.

[2]Intel Corporation.Intel RPXA27x Processor Family Deve-loper′s Manual[S].April 2004.

[3]Microsoft.Microsoft Developer Network Library.April[S].2005.

[4]Microsoft.Microsoft Windows CE.NET HLEP[S].March2003.

[5]石秀民.嵌入式系统设计与开发实验[M].北京:北京航空航天大学出版社,2006.

[6]田泽.嵌入式系统开发与应用实验教程[M].北京:北京航空航天大学出版社,2004.

[7]陈向群,王雷,马洪兵.Windows CE.NET系统分析及实验教程[M].北京:机械工业出版社,2003.

[8]Microsoft希望.Microsoft Windows CE Device Driver Kit设备驱动程序开发指南[M].北京:希望电子出版社,1999.

[9]MAX7347系列芯片文档[EB/OL];Maxim Integrated Prod-ucts;www.maxim-ic.com.cn.

键盘与驱动 篇4

关键词:WDM,USB接口,驱动程序

计算机发展速度飞快,传统的计算接口已经不能满足当前计算机高速发展的需求,键盘、鼠标、调制解调器、打印机、扫描仪、摄像头、数码相机、MP3随身听、外置硬盘、光驱设备往哪儿接呢?计算机业界迫切需要新的通用型、高速总线接口。

USB是一种应用在计算机领域的新型接口技术,它使得计算机周边设备连接标准化,具有安装方便、高带宽、易于扩展的特点。

本文利用Visual C++6.0、Driver Works以及Windows 2000 DDK开发包作为开发工具,采用WDM驱动程序模式,开发USB接口驱动程序,实现了USB键盘驱动程序的开发、安装及测试。

1 WDM驱动程序模型

在WDM驱动程序模型中,每个硬件设备包括两个驱动程序。一个驱动程序是硬件设备驱动程序,也称功能驱动程序,主要为用户提供适合的控制方式。它了解硬件工作的所有细节,负责初始化I/O操作,处理I/O操作完成时所带来的中断事件。通常由两个分离的执行文件组成。一个文件是类驱动程序,它了解如何处理操作系统使用的WDM协议,以及如何管理整个设备的基本特征。另一个文件称为微小驱动程序,它包含类驱动用于管理设备实例的厂商专有特征例程。类驱动程序和微小驱动程序合在一起才成为一个完整的功能驱动程序。

另一个驱动程序称为总线(BUS)驱动程序,负责管理硬件与计算机的连接。

一个完整的驱动程序包含许多例程,当操作系统遇到IRP时,它就调用驱动程序的例程来执行IRP的各种操作。

2 WDM驱动程序的结构

WDM驱动程序实行分层处理,被分成高层驱动程序、中间层驱动程序、底层驱动程序。每层驱动再把I/O请求划分成更简单的请求,以传给更下层的驱动执行。最底层的驱动程序在收到I/O请求后,通过硬件抽象层,与硬件进行交互,从而完成I/O请求工作。

WDM还引入了功能设备对象FDO(Functional Device Object)与物理设备对象PDO(Physical Device Object)两个新类来描述硬件。总线驱动程序(Bus Driver)位于最底层,控制对总线上所有设备的访问,并为每个设备创建一个PDO,功能驱动程序(Function Driver)管理FDO所代表的设备,过滤驱动程序(Filter Driver)用于监视和修改IRP流。

3 USB键盘驱动程序的开发

3.1 USB键盘驱动程序的实现和运行

用Driver Wizard3.0创建Usbkbd的WDM框架将自动生成一个工作区和两个工程,Test_Usbkbd files和Usbkbd files。其中Test_Usbkbd files是测试应用程序工程,Usbkbd files是驱动程序工程。

Test_Usbkbd files测试应用程序工程

OpenByIntf.cpp:OpenByIntf.cpp包含OpenByInterface函数,OpenByInterface函数用GUID接口方式与WDM进行通信。

Test_Usbkbd.cpp:是整个测试应用程序的主要文件,在这里添加相关代码,其作用是,打开设备的一个句柄,用于对设备进行读操作,并对DeviceIoControl函数进行调用, DeviceIoControl函数包含了对驱动程序的通信的命令。

Test_Usbkbd.cpp的文件结构

UsbkbdDriverInterface.h:定义设备接口的GUID。

Usbkbdioctl.h:定义驱动程序的控制代码。

Usbkbd.cpp:功能驱动程序,包含设备的初始化,DriverEntry例程和AddDevice历程。还重载了注册信息参数。

UsbkbdDevice.cpp:设备驱动程序,主要包括一些IRP的操作,如:清除(CleanUp(KIrp I))、关闭(Close(KIrp I))、创建(Create(KIrp I))、PnP管理(DefaultPnp(KIrp I))、电源管理(DefaultPower(KIrp I))、I/O控制(DeviceControl(KIrp I))、开始设备(OnStartDevice(KIrp I))、停止设备(OnStopDevice(KIrp I))、移除设备(OnRemoveDevice(KIrp I))、对设备进行读操作(Read(KIrp I))、系统控制(SystemControl(KIrp I))、通信控制(USBKBD_IOCTL_800_Handler(KIrp I))等。

在以上文件中添加代码。

function.h预定义相关的例程。

Usbkbd.h描述设备的相关信息,包括初始化时在注册表中的路径,注册表的参数,数据成员在 DriverEntry 期间被载入。

Usbkbdioctl.h为设备定义I/O控制命令。

Usbkbd.inf安装文件,在生成工程时自动生成。安装WDM设备驱动程序需要的所有必须的信息,包括要复制的文件列表、创建的注册表项等。

驱动程序通常使用DriverEntry作为驱动程序的默认入口点, 当PnP管理器发现一个硬件设备时,首先调用DriverEntry例程,DriverEntry例程是驱动程序初始化的入口点,它负责创建一个设备对象,定义其它的例程名称,设置例程的入口指针,从注册表中获取信息,初始化驱动程序,并初始化其它在驱动程序范围内的数据结构和资源。在DriverEntry中,主要的工作是在传递的驱动程序对象中存储一系列的回调例程指针。DRIVER_OBJECT结构由操作系统用于存储与驱动程序有关的任何信息。以后使用一个分开的结构存储每个设备的信息。Default Pnp(即插即用)主要是实现一个IRP_MJ_PNP处理程序。在驱动程序中,即插即用的基本处理包括:处理设备的添加和删除;得到分配的资源;处理查询停止和查询删除消息;处理停止设备消息;处理意外删除消息。Dispatch(分发例程)主要用来处理应用程序和驱动程序之间的通信,包括Great、Close、Cleanup、Read、Write、Control。分发例程是可选的,是为设备的硬件层编程服务的,通过该例程可以达到应用程序控制设备的目的。

WDM驱动程序通常由PnP管理器载入内存,然后调用它之中的AddDevice例程来创建设备。用一个inf安装文件来指明该驱动程序的一些参数。

一般情况下,DriverEntry例程要设置以下几个IRP处理函数:

DriverUnload 指向驱动程序的清除例程。I/O管理器会在卸载驱动程序前调用该例程。通常,WDM驱动程序的DriverEntry例程一般不分配任何资源,所以DriverUnload例程也没有什么清除工作要做。

DriverExtension→AddDevice 指向驱动程序的AddDevice函数。PnP管理器将为每个硬件实例调用一次AddDevice例程。这样将创建一个该设备对象。

DriverStartIo 如果驱动程序使用标准的IRP排队方式,应该设置该成员,使其指向驱动程序的StartIo例程。

MajorFunction 是一个指针数组,I/O管理器把每个数组元素都初始化成指向一个空函数,这个空函数仅返回失败。驱动程序可能仅需要处理几种类型的IRP,所以至少应该设置与那几种IRP类型相对应的指针元素,使它们指向相应的派遣函数。

3.2 功能驱动程序的相关步骤

用IoCreateDevice创建设备对象,并建立一个私有的设备扩展对象。

注册一个或多个设备接口,以便应用程序能够发现设备的存在。另外,还可以给出设备名并创建符号连接。

初始化设备扩展对象和设备对象的Flag成员。

调用IoAttachDeviceToDeviceStack函数,把新设备对象放到堆栈中。

Power例程。WDM驱动程序支持电源管理,电源管理器通过IRP指示驱动程序来改变电源状态,等待并响应系统唤醒事件和查询驱动程序设备,如果设备不支持电源管理,仅有一个默认的Power例程即可。

CreatFile:应用程序要想和设备进行通信,必须先打开设备,因此,应用程序用CreatFile函数来打开设备。

DeviceControl:应用程序可以调用DeviceIoControl函数与WDM驱动程序进行通信。DeviceIoControl函数分为同步调用和异步调用方式,采用同步方式时,应用程序调用DeviceIoControl函数将被阻塞,直到驱动程序完成响应的数据传输时才往下执行,因此这里采用异步调用方式,但是通常采用异步方式完成的驱动程序只允许一个应用程序,为了打开多个应用程序,应用程序调用并修改DeviceControl,使得每次只能有一个IRP处于等待中,这样可以打开多个应用程序。

ReadFile函数:应用程序和驱动程序进行通信的目的就是通过驱动程序对设备进行读、写、或控制等操作。在键盘驱动程序中,通过调用ReadFile函数,来读取键盘数据。

4 驱动程序的安装

用DriverWizard创建WDM框架程序之后,将自动生成一个工作区和两个工程文件。在相关文件添加相关代码后,将光标定位在Usbkbd file上,点击右键,选择“Set as Active Project”设置该工程为当前活动工程。然后点击编译,如果编译没有错的情况下,将会在sys文件夹下生成一些文件,包括一些自由构造和检查构造等文件,还生成一个objfre文件,生成的安装程序的系统文件Usbkbd.sys就包含在该文件里。

要安装上面生成的Usbkbd.sys文件,必须用驱动程序安装文件(inf)来安装。安装Usbkbd.sys文件有三种方法,但是在安装之前都要将sys文件下的Usbkbd.inf复制到“..sysobjferi386”目录下。因为Usbkbd.inf是在生成工作区时生成的,当时并没有sys文件,因此要将Usbkbd.inf复制到Usbkbd.sys所在目录下,Usbkbd.inf文件包含了安装WDM设备驱动程序需要的所有必须的信息,例如要复制的文件列表、创建的注册表项等。

从“控制面板”→“系统”→“硬件”→“添加硬件向导…”开始运行,按照向导一步一步找到Usbkbd.inf文件,完成该USB键盘驱动程序的安装。

驱动程序安装成功后将在设备管理器里可以看到安装的USBKBD设备的详细信息。如果驱动程序安装不上,可以用DriverStudio提供的Monitor跟踪测试。当驱动程序可以正常运行时,显示驱动程序的状态信息,当驱动程序不能运行时显示错误信息。

参考文献

[1]武安河.Windows2000/XP WDM设备驱动程序的开发[M].第2版.北京:电子工业出版社,2005.

[2]张惠娟,周利华,翟鸿鸣.Windows环境下的设备驱动程序设计[M].西安:西安电子科技大学出版社,2002.

键盘与驱动 篇5

随着多媒体时代到来,各种各样的嵌入式音视频播放系统(mp3/mp4)逐渐成为社会主流。一款类似产品中,直接与用户打交道的就是其操作部分;操作稳定且方便,很大程度决定了产品能否得到用户青睐。一般mp3/mp4最重要的输入设备是小键盘,所有复杂的内部功能,都由这个设备所控制。

与产品所能实现的功能比起来,输入设备键的数目很少。所以设备需为每个键重载功能。如长按、短按、自动重复按键等等,由实际产品的操作需要决定。可见,开发一个高效稳定的输入设备驱动,是产品开发中不可或缺的一个环节。

传统的类似产品的多种按键功能一般都是放在用户层,即在GUI(Graphical User Interface)中实现各种按键功能,而驱动层面上只提供很简单的按键响应。在本文中,将这些按键功能封装在硬件驱动层中,使得GUI的操作更加简便,方便移植,而且操作响应更快,更稳定。上层GUI本文使用QT-embedded作用户界面,只要做很少的修改就能够支持新的驱动程序。

1 软硬件的设计与实现

本文论述的是在一个嵌入式计算机上实现针对mp3/mp4小键盘控制的驱动程序方案,并在ml403验证板上测试通过。ml403是一块FPGA验证板,内含Power架构软核,以及Virtex-4 FPGA,验证板上所有的外设都是通过EDK(集成开发环境)生成bit文件写入FPGA,驱动程序所要操作的硬件,其实也就是这些外设中的一部分。系统硬件框图如图1所示。

软件方面本文采用的是MontaVista linux,内核版本2.6.10。作为一个实时操作系统,可以提高产品的效率和实时性。

硬件部分。ml403上的硬件是通过EDK将硬件IP挂在OPB总线(On-Chip Peripheral Bus)上,再写入FPGA的,处理按键、LED等设备的GPIO(General Purpose Input/Output)就是其中之一。GPIO为32位OPB总线提供了一个通用的输入/输出接口,可配置成单通道或双通道,每个通道都可配置为input或output。每个配置为input的32位端口的任何一位发生电平变化,都会产生中断。

2 驱动程序部分

从用户需要的角度来看,本键盘驱动要求完成以下的功能:

(1)用中断方式检测ml403上面的五个按键被按下,并且检测相应的按键类型。

(2)按键抬起时,依据按键被按下的时间长度判别长按键或者短按键,并且记录不同的键值。

(3)当一个按键被长时间按下时,驱动程序应判别这个键被长时间按下(比如说超过某个时间阈值),这时每隔一段时间记录一个(auto repeat)键值,当长时间按键结束时记录一个(auto repeat end)键值。这个功能主要运用在调节音量或者快进快退功能中。

Linux下的驱动程序分为两种,一种是直接编译进内核;另一种是作为模块按需加载。本驱动程序是采用前者,使得系统启动伊始便可以通过键盘对系统进行控制。五方向功能键的驱动程序和其它字符设备驱动程序类似,包括模块初始化代码、模块提供给用户的接口、以及模块的卸载代码三部分,如图2所示。

硬件GPIO在按键按下或者抬起时,都会触发一个中断。考虑到驱动程序中的auto repeat功能,设计思想采用了“中断+轮询”方式,即当按键按下时,在中断服务程序(ISR)中启动一个轮询机制,同时禁用GPIO中断。该机制每隔一段时间对GPIO端口进行查询,如果按键抬起,则根据时间间隔长短记录long press或short press键值;一旦时间超过一个阈值,一般来讲是1.5秒左右,那么接下来每隔0.3秒记录一个auto repeat press或auto repeat end press。程序流程如图3所示。

在驱动程序实现中,轮询机制并不是在ISR中实现,而是由ISR中启动的内核定时器来实现,因此ISR响应很快。具体时间参数视各种平台的HZ不同可能会有出入。

驱动程序中的数据结构如下:

在驱动程序中,键码储存在数据结构的keyevents[](循环缓冲区)中,以供用户通过用户接口读出。每个键码就是一个8bit char型数。高四位代表按键种类(长、短按键等),低四位代表不同的按键类型(UP,DOWN,LEFT,RIGHT,CENTER)。具体如表1所示:

图2中驱动程序各部分的简要介绍如下:

(1) 模块初始化部分:完成GPIO初始化、驱动程序数据结构内存申请、信号量和定时器的初始化,以及字符设备的注册。

(2) 驱动用户接口:linux下面的字符设备驱动都是由fileoperation结构定义的,它包含了一套完整的操作集和驱动的描述,通过实现fileoperation结构包含的函数指针来实现驱动程序的主体部分。在本文的驱动程序中,只需要实现open,release,read,ioctl即可。

①open函数,主要完成中断申请。

在驱动程序中不推荐在模块的初始化过程中申请中断,而应在设备第一次打开(调用open操作)时完成中断申请。这在有中断共享的设备驱动程序中非常重要。

②read函数,完成用户对设备键码的读取功能

3 GUI底层和驱动程序接口

本文使用QTembedded(简称QT)作为GUI。QT是基于C++的一种多平台图形用户界面应用程序框架。在QT底层,键盘操作用发送键盘事件实现控制,因此需要将驱动通过接口文件同QT底层结合,才能真正实现各种操作。

在QT底层,默认的键盘驱动接口文件是qkbdttyqws.cpp。首先在QT根目录下的configure文件中把“kbd-drivers+=tty”改为“kbd-drivers+=vr41xx”,重新配置后,在生成的src/Makefile中发现了键盘驱动接口文件名“qkbdvr41xxqws.cpp”。以这个文件为基础,产生可用的接口文件。

首先在qkbdvr41xxqws.cpp文件里将QWSVr41xxKbPrivate类构造函数中的字符设备文件名terminalName修改为“/dev/keyboard”,这是在板上文件系统中本驱动程序的设备文件名,这个设备文件已经在系统启动脚本中事先建立好。

上述类的构造函数中存在一个QSocketNotifier类对上述打开的设备文件进行监视,一旦有键码可读,就调用readKeyboardData成员函数读入键码,然后依据键码的不同,发送不同的键盘事件。因此主要应该对这个函数进行修改,如下所示(伪代码):

通过上述操作,为QT的上层用户提供了一个封装接口,上层用户可以简单的用事件驱动响应的方式,来响应硬件做出的任何操作。封装接口如表2所示:

注:p代表“按下”(press)事件,r为抬起(release)

4 结束语

在本文中介绍的硬件驱动程序的开发,使得开发板实现了用五方向功能键进行控制,满足了后续进行的用户程序开发的要求。同时使得GUI响应更加快速,移植更为方便,满足了高性能、高稳定性、低成本的要求。至今为止,板上操作系统仍然正常运行中,实验证明,验证板可以正常稳定工作,完成mp3/mp4播放所需要的所有键盘事件响应。而且随着上层用户开发中不断增加功能,GUI对键盘的控制要求日益复杂,底层驱动及GUI仍然可以充分满足要求。

参考文献

[1]魏永明,耿岳,等.LINUX设备驱动程序[M].3版.中国电力出版社,2006.

[2]李善平,刘文峰,等.Linux与嵌入式系统[M].清华大学出版社,2003.

初级键盘和声的学习与实践 篇6

学习键盘和声, 应该具备什么样的能力呢?一般说, 要能看懂乐谱, 并且把握和弦的结构, 在脑子里加以想象, 耳朵能够正确的分辨。在弹奏时, 必须能真切的感觉钢琴的演奏与和声密不可分。真正的感觉到和声所形成的空间感。同时还要能够感觉到因和弦的变化, 或调的变化所产生的情绪变化, 声音色彩的层次, 更要感受到和声流动中所产生的魅力。

在学习钢琴时, 乐谱上标记着演奏的各种要求, 除了音符之外, 还使用各种表情术语与记号, 批示有关速度、强弱及表情的事项。关于和声, 除了用音符表示外, 谱面没有任何批示。学习者只能自己根据乐谱去读取和声。

现归纳几种在最初阶段的键盘和声的学习与实践。

首先, 基本的和声尽量从单纯明快的形态开始学习, 以学习时所使用的教材为依据。

(1) 和弦的种类——主三和弦;属三和弦;下属三和弦;Ⅱ级和弦

(2) 和弦的记号——T (Tonic) 主和弦;D (Dominant) 属和弦;S (Subdominant) 下属和弦。也有注为Ⅰ主和弦、Ⅴ属和弦、Ⅳ、下属和弦。

(3) 终止式——完全终止:Ⅴ—Ⅰ;半终止 (乐曲中途用属和弦形成一个阶段Ⅴ) 。

(4) 和声的进行模式

这些就是在从前钢琴演奏技法上, 又加入乐理, 移调演奏、视奏、即兴演奏;以及键盘和声的练习。首先从G谱号开始, 逐渐在各个调上进行。

这些和声进行需要反复弹奏练习, 才能真正的掌握, 重视移调演奏;为使学习者实际去感受与把握和声与钢琴演奏的关系, 多引用钢琴曲或是熟悉的旋律、歌曲及伴奏做为学习的谱例。

主三和弦;属和弦;下属和弦的训练方式如下:

和声进行 (终止式的模式) 终止式在确立调性音乐中担任着最重要的任务。终止式的把握就是调性的把握, 也是曲式结构的把握有关。

Ⅰ-Ⅴ-Ⅰ是最普通的结尾构造, 又叫完全终止。有些教材中经常使用Ⅴ7-Ⅰ, 在键盘和声中, 运用省略导音, 解决到Ⅰ的方式进行。

使用Ⅰ-Ⅴ-Ⅰ的模式, 进行简单的和声编配练习。

在下面的旋律上, 用左手配上Ⅰ和Ⅴ7的和弦。

左手的伴奏形式是密集的三和弦, 以上使用Ⅴ7的第一转位, 虽然容易与旋律产生连续的五、八度现象, 但在最初的练习中可以乎略, 最主要的是熟悉和声的位置及变化。有时在实际的练习中也尽量的避免密集和弦的应用, 会让声音听起来过于沉重。

下面可以试用分解伴奏的形式, 用例5的主旋律:

这种伴奏的形式在圆舞曲中运用的较多。也比较容易接受, 这样的形式叫做阿贝提低音方式, 在拜尔钢琴教程中, 就有很多这样的形式, 如No55、No58等等

在下面的旋律上使用左手的阿贝提低音配上Ⅰ和Ⅴ的伴奏。

下面是配的左手伴奏

在初级的钢琴教材中大部分都是依照1, Ⅰ-Ⅳ-Ⅴ-Ⅰ;2, Ⅰ-Ⅳ-Ⅰ-Ⅴ-Ⅰ的和弦进行来写作的, 只要是熟悉的旋律或者歌曲, 都可以用这种形式来配和声。要对基本的和声中的密集型与分解和弦非常的熟悉。

激光投影虚拟键盘的研究与设计 篇7

1 硬件系统设计

激光投影虚拟键盘系统设计的关键在于对用户手指动作的识别,即对手指位置的检索。本系统设计采用单摄像头与一字远红外激光头对用户落点进行检测,由于该方法采用单个摄像头进行图像采集,因而成本较低,且功耗较小。而采用不可见光作为检索标志,和摄像头中滤光片的配合可以很好地消除可见光的干扰,消除由于环境光线的变化而造成的图像特征分离困难的问题。因为仅采用单个摄像头,采集数据量较低:且微控制器可满足图像的采集和处理,因而可以较容易在嵌入式系统中实现该设计的功能,同时可以控制设计成本,达到降低成本、降低推广障碍等目的。

1.1 键盘电路设计

激光投影虚拟键盘电路设计的系统框图见图1。

激光投影虚拟键盘系统的工作过程是:通过OV7620数字摄像头采集图像并发送到微控制器MK60DN512VLQ10,由微控制器进行图像处理、识别用户手指落点,将落点信息转换为按键消息响应,通过PDIUSBD12芯片采用USB协议将按键消息响应发送给USB主机,从而实现键盘的功能。而2.4 in(1 in=2.54 cm)TFT真彩屏和独立按键的加入,是为了保证图像调试更加方便,使设计更加快捷、有效。

1.2 摄像头接口设计

本系统的设计采用CMOS数字摄像头,具体图像传感器为Omni Vision公司生产的OV7620。这款视频摄像芯片属于CMOS数字式彩色与灰度芯片,采用高度集成工艺,拥有640×480的高分辨率可以进行隔行或者连续扫描。该数字视频端口支持60 Hz的YCrC b4∶2∶2的16 bit/8 bit格式,ZV端口输出格式,RGB阵列数据的16 bit/8 bit输出的格式以及CCIR601/CCIR656输出的格式。该芯片内建SCCB接口给用户提供了对芯片内建功能更加轻松的控制方式。芯片本身自带10位的双通道模数转换器,可以进行自动的白平衡以及自动增益控制,可以在γ校正、对比度、亮度和饱和度等方面进行调节;其视频时序产生电路能够产生像素时序以及行的同步、场的同步、混合视频的同步等数种时序的信号以及数种同步的信号[2]。该摄像头支持VGA和QVGA两种图像格式,帧传输速率为30 f/s(帧/秒)。在电路设计时预留了OV7620摄像头的数据、时序接口,具体电路如图2所示。其中CameD 0~CameD 7为摄像头输出的数字图像信号,CameP CLK为像素同步信号,CameH为行中断信号,CameV为奇偶场信号。由于OV7620默认配置完全满足本系统的设计,不需要通过SCCB协议对摄像头内建功能进行修改,故未接出SCCB信号SDA和SCL。摄像头输出信号的时序如图3所示。

由图3可知,当HREF时序信号在上升沿或下降沿时,表示一行图像的开始,而在PCLK信号的上升沿发生时,表示一次像素的传输,通过将HREF时序信号接入微控制器外部中断引脚中,设置为上升沿或下降沿触发中断方式,而PCLK作为DMA边沿触发信号,便可以对图像进行DMA采集。

1.3 USB驱动电路设计

由于本系统作为按键消息响应的从机,需要通过一定的接口协议传输消息响应给主机。本系统的设计采用USB接口协议来实现按键消息的主从机传输。虽然MK60DN512VLQ10微控制器内部含有USB驱动模块,但由USB协议的设计可知,USB协议的硬件驱动频率为48 MHz的整数倍,而MK60DN512通过配置PLL锁相环倍频及分频最终仅有48 MHz和96 MHz两种频率满足USB通信的要求,但为保证摄像头数据采集频率足够,微控制器MK60DN512VLQ10的工作主频最终需要超频至150 MHz才可以满足图像实时采集的要求。因此本工程采用了外接专用USB驱动芯片PDI-USBD12进行USB接口协议的实现。PDIUSBD12芯片具体电路及使能时序图分别如图4和图5所示。

2 软件系统设计

本系统的工作过程主要为:在程序开始,首先进行系统频率的初始化,将CPU运行频率超频至150 MHz,接着进行摄像头的行中断端口、场中断端口初始化,以及摄像头数据采集端口输入/输出方向的初始化,而后程序初始化PDIUSBD12芯片,设置其工作模式和工作频率,而后进行USB设备的枚举过程,使USB主机识别并设置本系统,枚举成功后,开启行中断、场中断,采集图像并进行图像处理,图像特征提取后得出按键坐标,将其映射为具体按键编码,通过USB消息响应发送至USB主机。

2.1 摄像头采集图像流程

本系统最基本的步骤为摄像头的采集。摄像头图像扫描时,将图像分为奇偶场两场信号,奇场即采集1,3,5…行的图像,偶场即采集0,2,4…行的信号,在每一场图像采集时,摄像头首先输出场同步脉冲信号,即VSYNC输出脉冲信号,该信号脉冲为60 Hz。而后在场信号有效后,摄像头输出的行基准信号开始有效,即HREF信号,该信号表明一行图像采集的开始。在每两个行基准信号之间,8 bit图像信号与像素同步信号PCLK一起输出,每个PCLK的脉冲边沿均可采集有效信号。而一幅图像奇偶场信号的确定由ODD来确定,ODD高电平表示当前采集为奇场信号,低电平表示当前采集为偶场信号,因此ODD输出为频率30 Hz,占空比50%的高低电平信号。考虑到本系统对分辨率要求不高,而对内存大小要求较为严格,因此本系统采用隔行采点的方式进行图像采集,将ODD奇偶场信号作为行同步信号,ODD信号上升沿作为中断触发信号,即一幅图像仅采集其偶场信号,便可以达到隔行采点的目的。而PCLK上升沿作为DMA传输触发信号,摄像头输出8 bit图像信号作为DMA输入数据源,则可以实现DMA采集图像。由于直接使用摄像头的默认设置方式可以满足本系统的使用要求,因此本系统未在初始化采用SCCB协议对摄像头进行设置,在初始化时仅初始化DMA采集以及相关中断信号的初始化。在本系统中,对图像采集的步骤为:首先进行摄像头引脚、中断信号的初始化,而后在场中断中开启行中断,并对行计数指针清零,而后等待行中断发生,在行中断中初始化DMA采集,并判断是否采集完一幅图像,并在采集完所有图像后,返回图像数组指针作为图像像素的索引。具体采集流程如图6所示。

2.2 数字图像处理流程

由于摄像头工作过程中,由其选型介绍可知,CMOS摄像头内部由于采用不同放大器对同一行内不同像素进行放大,放大一致性较差,因此采集图像噪点较多。而由于摄像头生产工艺、安装误差,以及广角镜头的使用和系统中摄像头安装机械结构中具有倾角等因素,都会造成采集图像发生畸变[3]。因此,采用摄像头进行标定、校正以及对图像进行滤波等数字图像处理技术非常必要[4]。

本系统采用MATLAB的摄像头标定工具箱(Camera Calibration Toolbox)和图像处理工具(Image Process Toolbox)箱进行采集图像的校正、直方图的获取、二值化阀值的确定等过程。摄像头标定工具箱是由加州理工大学开发,专门用于标定摄像头的图形界面工具箱。而图像处理工具箱是MATLAB自带用于图像处理的专用工具[5]。

在本系统中,首先通过微控制器串口将图像传输至PC的图像采集上位机中,而后将图像截图,保存得到原始采集图像,如图7所示。而后,将该图像导入MATLAB的摄像头标定工具箱中进行标定,得到图像大概坐标的确定,从而将该坐标与世界坐标进行对应,具体标定如图8所示。

由标定后图像,通过摄像头标定工具箱的Calibration可以得出关于标定图像的若干校正参数,通过该参数可进行图像的校正。该工具箱输出的参数有:

1)焦距:有效像素的焦距存储在2×1向量fc中。

2)主点:主点坐标存储在2×1向量CC中。

3)倾斜系数:倾斜系数定义为x像素和y像素坐标轴的夹角,该角存储于标量alpha_c中。

4)畸变系数:图像的畸变系数(旋转畸变和几何畸变)存储于5×1的向量kc中。

对于校正图像,通过输出的以上参数,经过以下过程可以得到校正图像,其中Xc,Yc,Zc是坐标点相对于摄像头的向量,而xn为世界坐标投射到摄像头内的投影坐标[6],则有

设r2=x2+y2,则换算到的新的世界坐标系中由式(2)得到

式中:dx是几何畸变向量,具体如式(3)所示

而向量kc包括了扭曲畸变和几何畸变系数。当使用有畸变发生时,最后世界坐标系中该点的像素坐标x pixel=[xp,yp]有如同式(4)的对应关系

这样,像素坐标向量x_pixel与世界坐标向量xd则有如下的线性方程

而KK为摄像头参数矩阵[7,8],且定义为

由本系统的图像标定,最后得出标定参数如下

由该参数最终得出校正图像如图9所示。

而后将该参数导入到微控制器中进行图像校正,在图像处理部分,程序首先将读取到的图像进行数字滤波,而后采用MATLAB计算得到的参数进行图像校正,再通过八连通闭合区域检测提取出手指按下后反射的光斑的质心坐标,将其映射为按键编码[9]。

3 系统测试

3.1摄像头采集图像设置

摄像头上电后,要进行图像采集,而为保证图像采集正常,最直观的办法是进行摄像头采集图像的显示,在本系统的调试中,采用将图像实时显示在TFT屏上的办法来测试摄像头采集是否正常。

测试方法:在摄像头下方摆放特定的图案,使摄像头正常工作进行采集,将采集到的图像显示在TFT显示屏上。测试结果如图10所示。

测试结果:摄像头可以正常工作,且采集图像效果良好。

3.2 系统测试

软硬件测试系统正常后,本文最终对整个系统进行测试,将该系统连接USB主机—PC进行功能测试,确定其是否达到设计最初的目的和功能。最终测试结果如图11所示。

最终,本系统可以正常与USB主机枚举成功并由USB主机正确识别为USB键盘类设备,且通过用户在投影图案上进行操作,可以使系统准确识别按键消息并将其正常、及时地返回到USB主机中,实现作为键盘的目的[10]。最终测试表明,本系统可以较好地完成激光投影键盘所承担的任务,达到激光投影键盘的目的。

4 结束语

作为便携式设备进行办公、工作汇报等大批量文字输入的情况下,激光投影虚拟键盘能够实现准确的按键信息发送,可以全部实现传统键盘的功能,同时在机械结构的优化,体积便携性方面都有很大的提升。

参考文献

[1]蔡睿妍.激光虚拟键盘的设计与实现[J].激光与红外,2012,42(8):875-878.

[2]Omni Vision.OV7620 Single-chip CMOS VGA color digital camera[EB/OL].[2015-12-06].http://joule.bu.edu/~hazen/Rockets/Cam/DS-OV7620-1.3.pdf.

[3]BRADSKI G,KAEHLER A.学习Open CV(中文版)[M].北京:清华大学出版社,2009.

[4]张金,成媛媛,李洋.一种基于虚拟键盘图像坐标变换的几何失真校正方法[J].计算机应用与软件,2012,29(6):84-88.

[5]RAFAEL C G.数字图像处理(MATLAB版)[M].北京:电子工业出版社,2014.

[6]范勇,张佳成,陈念年.图像几何畸变校正方法[J].计算机工程与应用,2009,45(29):194-197.

[7]贾洪涛,朱元昌.摄像机图像畸变纠正技术[J].电子测量与仪器学报,2005,19(3):46-49.

[8]朱铮涛,黎绍发.镜头畸变及其校正技术[J].光学技术,2005,31(1):136-138.

[9]胡君.一种快速求图像目标质心的方法[J].光学精密工程,1998,6(5):19-25.

上一篇:预应力混凝土受力分析下一篇:概率积分