触摸屏控制器驱动程序设计在便携式的电子类产品中 ,触摸屏由于其便、灵活、占用空间少等优点 ,已经逐渐取代键盘成为嵌入式计算机系统常选用的人机交互输入设备。
触摸屏输入系统由触摸屏、触摸屏控制器、微控制器及其相应的驱动程序构成。
本文从触摸屏控制器的驱动程序设计着手 ,介绍触摸屏控制器 ADS7843 的内部结构及工作原理和在嵌入式 Linux 操作系统中基于PXA255微处理器的ADS784羽驱动程序设计。
1触摸屏控制器ADS7843的介绍1.1ADS7843的内部结构ADS7843内驻一个多路低导通电阻模拟开关组成的供电-测量电路网络、12bit逐次逼近A/D转换器和异步串行数据输入输出,ADS7843艮据微控制器发来的不同测量命令导通相应的模拟开关 ,以便向触摸屏电极对提供电压 ,并把相应电极上的触点坐标位置所对应的电压模拟量引入A/D转换器,图1为ADS7843内部结构图。
X+、Y+ X-、丫为触摸屏电极模拟电压输入;CS为ADS7843的片选输入信号,低电平有效;DCLK接外部时钟输入 ,为芯片进行 A/D 转换和异步串行数据输入 /输出提供时钟;DIN串行数据输入端,当CS低电平时,输入数据在时钟的上升沿将串行数据锁存;DOUT串行数据输出端,在时钟下降沿数据由此移位输出,当 CS 为高电平时,DOUT呈高阻态。
BUSY为系统忙标志端,当CS为低电平, 且BUSY为高电平时,表示ADS7843正在进行数据转换;VREF参考电压输入端,电压值在+1V到+VCC之间变化;PENIRC为笔触中断,低电平有效;IN3、IN4为辅助ADC转换输入通道;+VCC为电源输入。
图1ADS7843内部结构1.2ADS7843的转换时序ADS7843完成一次数据转换需要与微控制器进行3次通信,第一次微处理器通过异步数据传送向 ADS843 发送控制字 ,其中包括起始位、通道选择、 8/12 位模式、差分 /单端选择和掉电模式选择 ,其后的两次数据传送则是微控制器从 ADS7843 取出 16bitA/D 转换结果数据(最后四位自动补零),每次通信需要 8 个时钟周期 ,完成一次数据转换共需 24 个时钟周期周2为ADS7843转换时序。
图2ADS7843转换时序2ADS7843与 PXA255硬件接口PXA255微处理器是In tel公司生产的第二代基于32位XScaie微架构的集成系统芯片(ISOC),PXA25具有高性能、低功耗等优点,它除了 XScale 微内核外 ,还集成了许多适用于手持设备市场需要的外围设备。
图 3 为ADS7843触摸屏控制器与PXA255微处理器的硬件连线示意图。
当屏触发生时ADS7843向PXA255发出中断请求,由PXA255响应该中断请求,启动通信过程,读取ADS7843的转换结果,从而得到触摸点的坐标。
ADS7843 各信号的时序受外部输入时钟信号频率的影响 ,一旦外部输入时钟频率固定 ,各信号的时序便完全确定 ,因此需要配置 PXA255 的接口信号时序,使之完全符合ADS7843的时序。
图3ADS7843触摸屏控制器与PXA255微处理器的连线示意图3ADS78435驱动程序的设计Linux 作为一个宏内核操作系统 ,其设备驱动都在内核 ,即系统空间实现 , 实现方式有两种 ,一种是将有关的设备驱动程序和数据结构静态地连接在内核映像中 ;另一种是将具体的设备驱动程序和数据结构独立加以编译,成为可安装的模块 ,需要时由应用程序通过系统调用动态地予以安装或拆卸。
设备驱动的实现方法也有两种,一种是轮询(polling)方式另一种是中断(inter-rupt)方式,轮询方式对设备的操作完全由 CPU掌握,夕卜部设备则完全处于被动状态。
中断方式是由外部设备主动提出申请 , CPU响应申请后对外部设备进行处理,是现在常用的设备驱动方式。
Linux 的设备驱动具有两个显著的特点 ,其一是把所有的设备视为一种设备文件,每个设备都呈现于文件系统的/dev目录下,设备驱动与文件操作具有相同的界面和语义 ,并通过同一组系统调用进行操作 ;另一个显著特点是Linux的设备驱动有着分明的层次和结构。
Linux 内核的新近版本为设备入口提供了一种特殊的文件系统 ,即设备文件系统devfs(devicefilesystem。
新的devfs机制的优点在于:①各种设备驱动模块动态地向系统登记 ,设备初始化时在 /dev 目录下创建设备入口点 , 移除设备时将其删除。
② 设备驱动程序可以指定设备名、所有者和权限位。
③ 不需要为设备驱动程序分配主设备号以及次设备号。
④ 当装载和卸载模块时 ,不再需要运行脚本来创建设备文件 ,驱动程序自主地管理其设备文件。
采用devfs机制的设备驱动程序调用下面的函数来处理设备的创建和删除工作。
devfs_hander_tdevfs_mk_dir(devfs_han2der_tdir,constchar3name,void3i nfo)devfs_hander_tdevfs_register(devfs_han2der_tdir,constchar3NAME,unsig nedintflags,unsignedintmajor,unsignedintminor,umode_tmode,void3ops,v oid3info)voiddevfs_unregister(devfs_hander_tde)在 Linux 操作系统编写设备驱动程序时有几个固定的功能模块:向 Linux 内核注册该设备时的初始化设备驱动程序模块 ;用于系统卸载模块时删除设备驱动程序的模块;提供用户使用该设备驱动程序的文件操作接口模块。
对于各类具体设备编写驱动程序时还应具有对该设备进行操作的应用函数。
下面就以ADS784羽驱动程序设计为例分析以上几个功能8°」)ADS7843可匚nuxwM 羊串菇瞅卑3裆毬矣因選infinigds7843fs inif(void)//菇瞰裆毬因選宀infraif((「elldevfsl 「egis(Dr_ch 「dev(TSIMAJORHSINAMEdads7843lfslfops))H0)宀prinfkQegisCDringopTSINAME 二 sfa=ed一rrmefulnrec devfslfsldi 〒 devfslmkid i「(N UL L =f ouchscree n =N U LL)-B H ^淋淑菇瞰四>devfslhand_eHdevfsl 「egis(D 「(devfslfsldi「=fs=DEVFSIFLIDEFAULTHSIMAJOROSI_FCHR_sl_RUSR_sl_WUSRdads7843lfslfopszul^菇瞅 if((「ell 「equesfli 「q(-RQIG 卫OIADS7843bds7843lfslin(D 「—nJPLSAISH_RQ_SA」NTERRUPTHSINAMECLevliaw甘s宀prinfkvadszBAUIfsIinir-rfai-edforegisCDr-RCArr)八freelirq(-RQIG 卫OIADS7843CLevlid)m2.umrecif((「ellads7843linio)Ho)二裆毬矣裁淋淑 宀f 「eeli 「q(-RQIG卫OIADS7843CLevlid)m2.uln 「ecGPDR0QO¥GP_olbif(ADS7843IBUSY=GPDR0QO9G卫 olbif(ADS7843IDOUTXAds7843IEnab_el_RQP 申M甘sprintk("ads7843touchscreendriverinitialized\n");return0;}2)系统卸载ADS784羽驱动程序功能函数void__exitads7843_ts_clea nup(void)// 卸载驱动程序函数{if(in_timehandle) del_timer(&timer);free_irq(IRQ_GPIO_ADS7843,dev_id);释放中断devfs_u nregister_chrdev(TS_MAJOR,TS_NAME)从系统中删除设备驱动程序printk("ads7843touchscreendriverremoved\n");}3)在驱动程序最后用于模块初始化和删除驱动的功能函数module_init(ads7843_ts_init);// 初始化驱动模块函数module_exit(ads7843_ts_clea nu p);// 删除驱动模块函数4)ADS7843设备文件操作结构体staticstructfile_operationsads7843_ts_fops={read:ads7843_ts_read,〃从设备中读数据操作poll:ads7843_ts_poll,〃查询设备操作ioctl:ads7843_ts_ioctl,〃设备 IO 控制操作fasync:ads7843_ts_fasync,/屏步通知操作 open : ad s 7 843_ts_open , //打开设备操作 release:ads7843_ts_release,};/当文件结构被释放时,调用释放操作由于文章篇幅所限 ,对设备文件操作的功能函数不再一一列出。
5)ADS7843具体操作函数①ADS7843串行输出控制字函数 voidADS7843_din(charcommand) udelay(DELA Y);/延时for(inti=0;i>i)&0x1)ADS7843_SetBit(0,ADS7843_DIN)数据位为 1elseADS7843_ClearBit(0,ADS7843_DIN)数据位为 0 udelay(DELAY);ADS7843_SetBit(0,ADS7843_CLK);}}// 钟变高②微处理器读取X坐标值函数(读取Y坐标值函数相类似,控制字为0x90)intADS7843_ts_measure_x(void) {chari,inttouch_data=0;ADS7843_ClearBit(0,ADS7843_CS)片选端置低电平udelay(DELAY);ADS7843_din(OxDO);/佝 ADS7843发送读 X 坐标控制字 OxDOADS7843_ClearBit(0,ADS7843_CLK);udelay(DELAY);while(!(GPLR0&GPIO_bit(ADS7843_BUSY)))printk("BUSY1\n");ADS7843_ClearBit(0,ADS7843_CLK);for(i=0;i>=3;〃对最后4位自动置0处理return(touch_data&0xfff);}4驱动模块的安装在 Linux 操作系统中 ,对于已编好的设备驱动程序 ,利用编译工具将驱动程序编译成驱动模块。