关于触摸驱动程序是否应该使用中断驱动,事实上在范例的驱动程序中用的就是中断驱动方式。坦率地讲,我之所以这样做是因为使用中断很有趣。千万不要由这个例子推断出采用中断永远是最好或最正确的设计方式,也不要听信别人说不采用中断驱动方式的触摸驱动程序就是"错误的"。
之所以这样说只是因为"轮询"对嵌入式系统程序员来说似乎变成了贬义词。我曾经问过一位客户,他的输入设备采用的是轮询还是中断服务方式。回答是"这是嵌入式系统,我们不做任何轮询"。我当时感觉问这个问题时我就像一个傻瓜,但进一步探讨后发现查询其实也是一种合理且值得考虑的方式。如果使用的是RTOS,并且所有任务经常为了等待某类外部事件而被中断,处理器经常处于空闲的循环状态,没有什么有意义的事做。这种情况下使用空闲任务查询触摸屏上的输入也许是更好的设计方式。根据你的总体系统需求,查询也可能是一个值得考虑的合理的设计方式。
配置中断的方法因具体操作系统而异。读者会发现对于每一个支持的RTOS都有被(#ifdef)限定的代码段。在所有情况下驱动程序实际会使用二种不同的中断: 1 当屏幕被初次触摸时唤醒主机的中断,称为PEN_DOWN中断 2 当完成一组模数数据转换时的第二种中断信号
后文会详细介绍这些中断和它们产生的过程。
接下来的问题是我们希望以多快的速度从ADC接收采样输入读数。采样速度会影响我们需要如何配置时钟来驱动触摸屏和ADC。我们希望时钟有足够快的速度来提供可响应的输入和实现精确的跟踪,但也不要太快,以至于影响转换精度,或让系统消耗超过所需的功率。
根据我的经验,触摸屏至少需要以20Hz或50ms间隔的速度向更高层软件提供位置更新数据,只要高层软件跟得上,速度越快越好,我们不太担心功耗问题。如果触摸输入响应比这慢得多,那么在用户的触摸输入和显示屏上可观察到的响应之间会出现明显和烦人的迟滞现象。
20Hz的更新速度听起来并不是太有挑战性,但提供20Hz的更新速度实际上要求采样速度接近200Hz,具体数值取决于我们在确定输入稳定之前准备采用多少读数。为了去抖动和对触摸输入位置值进行平均,我们需要进行过采样。电阻触摸屏,特别是便宜的那种,一般会有很大的噪声和抖动。 在向更高层软件发送位置更新数据之前,驱动程序需要多次采样每个轴上的输入。我们提供的驱动程序默认情况下将以最少200Hz(5ms)的采样速率配置各自处理器上的ADC时钟。这样就能让驱动程序对输入原始数据进行充分的去抖动和过滤,并仍能向高层用户接口软件提供20Hz的实际位置更新速率。
飞思卡尔i.MX处理器中的触摸控制器模块叫做模拟信号处理器(ASP),i.MX处理器提供两个由内核CPU时钟分频得到的外设时钟。输入ASP模块端口的是PERCLK2(外设时钟2),它经过再分频产生ASP所需的最终输入时钟。需要注意的是,PERCLK2除了驱动ASP模块外,还驱动包括内部LCD控制器在内的其它子模块,因此触摸驱动程序无法只是为了更好的配合触摸采样而对PERCLK2进行编程。PERCLK2被编程为所有附属外设所要求的最高速率(在大多数情况下是LCD控制器),然后通过分频产生速度较慢的外设所需的时钟。MC9328MX1参考手册中包含一份表格,该表格定义了达到200Hz数据输出速率所需的时钟编程值。
夏普LH79524在硬件配置时要求对几个GPIO引脚进行编程以便给这些引脚分配ADC功能,并要求编程和激活ADC时钟,还要对ADC序列器编程。
LH79524 ADC本身是一个令人称奇的电路系统,能够实现完全可编程的状态机和序列器。该ADC无需核心CPU的任何干预就可以通过编程完成:驱动一个触摸层;延时;进行测量;驱动另一层;延时;进行测量等操作。理解如何对LH79524 ADC序列器控制单元编程可能是一个挑战,不过利用夏普(www.sharpsma.com)公司提供的应用指南可以使这项工作简单很多。本文提供的驱动程序完全符合该应用指南对如何配置夏普ADC序列控制器提出的建议。
 图3:X轴移动时Y轴上的偏移。
屏幕被触摸到了吗?
一旦完成了基本的硬件设置,接下来就需要一种可靠的方法判断屏幕是否被触摸了。如果用户没有触摸屏幕,那么运行ADC获得转换后的读数毫无意义。上述两个控制器都提供了屏幕是否被触摸的检测机制,并且当触摸事件发生时还可选择是否中断主处理器。判断屏幕是否被触摸的驱动程序的函数名叫WaitForTouchState()。
当控制器处于触摸检测模式时,Y轴触摸层通过一个上拉电阻上拉到高电平,X轴触摸层则连接到地。当用户触摸屏幕的任何地方时,这两层就发生短接,Y轴层被拉到低电平。该事件可以在驱动程序内部连接到名为PEN_OWN IRQ的中断发生机制。
在正常工作期间,当触摸事件发生时驱动程序利用PEN_DOWN IRQ唤醒触摸驱动任务。这样做可以让驱动程序在屏幕没有被触摸时中断自己的执行,而不消耗任何CPU资源,而一旦用户触摸屏幕,驱动程序就被唤醒并进入转换模式。我们也可以在转换模式没被激活时停止(disable)ADC时钟来节省功耗。
在校准和主动采样期间,驱动程序使用与上述基本相同的机制检测屏幕是否被触摸;不过在这些模式下驱动程序会屏蔽实际的中断,并通过人工方式简单的检查触摸状态。对于飞思卡尔的处理器,这时要求把控制器编程到触摸检测模式,并检查PEN_DOWN IRQ的数据位。对于夏普的处理器,触摸检测内建在ADC命令序列中,不需要额外的步骤。
读取触摸数据
在校准和正常操作期间,我们需要读取X和Y轴的原始数据并去抖动,然后确定屏幕被触摸时是否有稳定的读数。该过程在两个驱动程序中都叫TouchScan()。该过程的要点是:
1. 检查屏幕是否被触摸; 2. 采集每个轴上的多个原始读数用于以后的过滤; 3. 检查屏幕是否仍在被触摸。
在执行模数转换时,两个控制器都提供了由编程产生延迟的方法,以在给触摸层加电和开始实际的模数转换之间插入一段时延。飞思卡尔把这段时延称作数据建立计数(DSCNT),在两层切换后会有很多个ASP输入时钟长度的延时。夏普把这段时延称为预充时延。
两种CPU都需要这种时延,因为电阻触摸面板是二块由薄绝缘层隔离的大面积导体,正好形成一个电容。当从将要执行模数转换的层切换到正在加电的层时,需要一定的延时才能保证电容达到稳定状态。
对于飞思卡尔的i.MX1处理器来说,一旦我们启动转换过程,那么由ADC产生的数据将被保存在一个16位宽x12个条目深度的FIFO中。ADC产生9位无符号数据,因此每个16位条目的高7位将被忽略掉。这意味着这种触摸控制器的全部数据范围从0到511,不过实际上没有ADC或电阻触摸屏会产生接近这个极限值的数据。
我们可以通过编程让处理器在FIFO存有任何有效数据时就产生中断,或在输入FIFO装满时产生中断。由于我们通常会做多次读取,因此驱动程序一般会在FIFO装满时产生中断。当该中断产生时,会有12个原始的模数转换数据等待处理,分别对应于X轴的6次读数和Y轴的6次读数。
夏普LH79524处理器允许在产生中断前通过编程完成精确的步骤序列。在执行每个步骤时,结果同样会保存在输入FIFO中,等待驱动程序软件的读取。结果是以16位数值进行保存。每个结果的高10位是模数转换值,最低4位是序列索引。10位转换结果意味着这种触摸控制器的最大数值范围是0到1023,当然你永远也不会观察到接近极限值的结果。
一旦序列器控制字在LH79524上被编好程,驱动程序获取原始读数所需要做的就是命令序列器执行。当EOS(序列结束)中断产生时,我们获得的结果就可以用于采集和检查了。序列器可以被配置为当屏幕被触摸时自动触发、根据软件命令触发或连续触发三种模式。
要注意原始转换器读数中经常会有一些噪声和偏差,这是正常的。你只有紧紧压住电阻触摸屏才能得到两个连续的读数,并取得一致的9位或10位原始数据。然而你会发现当触控笔或手指按上或离开触摸屏时,读数的变化要比你保持稳定压力时大得多。要记住用户是以机械的方式连通二个平面电阻-触摸层。当用户按压和释放触摸屏时,在很短的一段时间内两层之间的电气连接处于临界状态。我们需要丢弃这些读数直到系统稳定下来,否则我们提交的触摸位置读数会产生大幅跳跃,导致更高层的软件无法进行合适的操作。
这里不可避免要进行折衷考虑。如果我们要求较窄的稳定窗口,那么驱动程序将无法跟踪快速的"拖曳"操作。对于在签名输入期间发生的滑动或笔划跟踪事件来说快速拖曳是非常重要的。如果我们加宽稳定窗口,我们就可能面临着风险,这些风险包括接收到不精确的触摸数据和上文描述过的处于临界状态的层连接结果。因此需要通过实验来确定适合自己系统的最佳值。智能化的触摸控制器同样允许你通过软件命令调整这些参数。
每个样值所需的读取次数、连续读取间允许的偏差以及采样速率是每个驱动程序的全部可编程参数。可以通过#defines调整这些参数以便在你的系统上产生最佳结果。智能化的外部触摸控制器一般会以很快的速度读取数十或数百个数据用以改善精度。由于我们是用核心CPU完成这种过滤,因此我们需要确定有多少时间可以合理地分配给触摸采样任务。嵌入式系统包含折衷,你的任务就是想出最佳的折衷办法,以产生能使用户满意的系统。
出于游戏目的,我喜欢测试日常生活中所遇到的商业触摸系统。下一次当你使用触摸屏进行购物签名或包裹签名时,你可以尝试快速大范围波浪形地移动触控笔,然后观察结果,查看屏幕跟踪你移动的程度如何。如果你能看到漂亮光滑的跟踪轨迹,你就知道驱动程序的采样速率相当快,可能在200Hz以上。经常你会观察到移动轨迹变成了一条直线(慢速采样)或完全丢失(由于数值改变过大而被拒绝输入)。当你在零售商店进行这种小测试的时候千万不要大呼小叫,否则人们会用异样的目光看你。正常人是不会理解什么东西会使工程师那么激动。
触摸屏的校准
到此我们已经介绍了驱动程序所支持的全部功能,这是我们进入下一步之前必须完成的繁琐工作。既然各种功能都已就绪,可以让用户实际触摸屏幕了。电阻触摸屏需要校准。我们需要一些参考值,以便我们能够将接收到的原始模数转换值转换成高层软件所需的屏幕像素坐标。理想情况下校准程序只要在产品初次加电测试过程中运行一次就可以了,参考值被存储在非易失性存储器中。我已经安排好让触摸驱动程序在一启动时就运行校准程序,但要记住,你要把参考值保存起来,以免让用户在以后的加电启动期间再做校准。不过无论如何你仍然需要向用户提供一种进入校准例程的途径,从而在由于温度漂移或其它因素造成校准不准确时进行重新校准。
|