1、基于 PXA255 的触摸屏控制器 ADS7843 程序设计来源 :网络 作者:李外云 胡文静 刘锦高 发布时间:2011-01-25 点击: 121 次摘要:在研发具有操作系统的设备时,高质量的设备驱动程序可以大大提高设备的稳定性与可靠性。本文以触摸屏控制器 ADS7843 为例, 介绍了其内部结构、工作原理, 并详细阐述了在 Linux 操作系统的设备文件系统机制中编写设备驱动程序的过程与方法,同时给出基于 PXA255 微外理器的触摸屏控制器 ADS7843 中断方式的驱动程序。关键词: 嵌入式 Linux;触摸屏;ADS7843;PXA255 微处理器在便携式的电子类产品中,触摸屏由于
2、其便、灵活、占用空间少等优点 ,已经逐渐取代键盘成为嵌入式计算机系统常选用的人机交互输入设备。触摸屏输入系统由触摸屏、触摸屏控制器、微控制器及其相应的驱动程序构成。本文从触摸屏控制器的驱动程序设计着手,介绍触摸屏控制器 ADS7843 的内部结构及工作原理和在嵌入式 Linux 操作系统中基于PXA255 微处理器的 ADS7843 驱动程序设计。1 触摸屏控制器 ADS7843 的介绍 1.1 ADS7843 的内部结构 ADS7843 内驻一个多路低导通电阻模拟开关组成的供电-测量电路网络、12bit 逐次逼近A/D 转换器和异步串行数据输入输出,ADS7843 根据微控制器发来的不同测量
3、命令导通相应的模拟开关,以便向触摸屏电极对提供电压,并把相应电极上的触点坐标位置所对应的电压模拟量引入 A/D 转换器,图 1 为 ADS7843 内部结构图。X+ 、Y+、X-、Y- 为触摸屏电极模拟电压输入;CS 为 ADS7843 的片选输入信号,低电平有效;DCLK 接外部时钟输入, 为芯片进行A/D 转换和异步串行数据输入 /输出提供时钟;DIN 串行数据输入端 ,当 CS 低电平时,输入数据在时钟的上升沿将串行数据锁存;DOUT 串行数据输出端, 在时钟下降沿数据由此移位输出,当CS 为高电平时,DOUT 呈高阻态。 BUSY 为系统忙标志端, 当 CS 为低电平, 且 BUSY
4、为高电平时,表示 ADS7843 正在进行数据转换;VREF 参考电压输入端 ,电压值在+1V 到+VCC 之间变化;PENIRQ 为笔触中断,低电平有效 ;IN3、IN4 为辅助 ADC 转换输入通道;+VCC 为电源输入。图 1 ADS7843 内部结构 1.2 ADS7843 的转换时序 ADS7843 完成一次数据转换需要与微控制器进行 3 次通信, 第一次微处理器通过异步数据传送向 ADS843 发送控制字,其中包括起始位、通道选择、8/12 位模式、差分/单端选择和掉电模式选择,其后的两次数据传送则是微控制器从 ADS7843 取出 16bitA/D 转换结果数据(最后四位自动补零
5、 ),每次通信需要 8 个时钟周期,完成一次数据转换共需 24 个时钟周期,图 2 为 ADS7843 转换时序。图 2 ADS7843 转换时序 2 ADS7843 与 PXA255 硬件接口 PXA255 微处理器是 Intel 公司生产的第二代基于 32 位 XScale 微架构的集成系统芯片(ISOC),PXA255 具有高性能、低功耗等优点 ,它除了 XScale 微内核外, 还集成了许多适用于手持设备市场需要的外围设备。图 3 为 ADS7843 触摸屏控制器与 PXA255 微处理器的硬件连线示意图。当屏触发生时 ADS7843 向 PXA255 发出中断请求 ,由 PXA255
6、 响应该中断请求,启动通信过程,读取 ADS7843 的转换结果,从而得到触摸点的坐标。ADS7843 各信号的时序受外部输入时钟信号频率的影响,一旦外部输入时钟频率固定 ,各信号的时序便完全确定,因此需要配置 PXA255 的接口信号时序,使之完全符合 ADS7843 的时序。 图 3 ADS7843 触摸屏控制器与 PXA255 微处理器的连线示意图 3 ADS7843 驱动程序的设计 Linux 作为一个宏内核操作系统,其设备驱动都在内核,即系统空间实现,实现方式有两种,一种是将有关的设备驱动程序和数据结构静态地连接在内核映像中;另一种是将具体的设备驱动程序和数据结构独立加以编译,成为可
7、安装的模块,需要时由应用程序通过系统调用动态地予以安装或拆卸。设备驱动的实现方法也有两种,一种是轮询 (polling)方式, 另一种是中断(inter-rupt)方式 ,轮询方式对设备的操作完全由 CPU 掌握, 外部设备则完全处于被动状态。中断方式是由外部设备主动提出申请,CPU 响应申请后对外部设备进行处理, 是现在常用的设备驱动方式。Linux 的设备驱动具有两个显著的特点,其一是把所有的设备视为一种设备文件, 每个设备都呈现于文件系统的/dev 目录下,设备驱动与文件操作具有相同的界面和语义,并通过同一组系统调用进行操作;另一个显著特点是 Linux 的设备驱动有着分明的层次和结构。
8、Linux 内核的新近版本为设备入口提供了一种特殊的文件系统,即设备文件系统devfs(device file system)。新的 devfs 机制的优点在于:各种设备驱动模块动态地向系统登记, 设备初始化时在/dev 目录下创建设备入口点 ,移除设备时将其删除。设备驱动程序可以指定设备名、所有者和权限位。不需要为设备驱动程序分配主设备号以及次设备号。当装载和卸载模块时,不再需要运行脚本来创建设备文件 ,驱动程序自主地管理其设备文件。采用 devfs 机制的设备驱动程序调用下面的函数来处理设备的创建和删除工作。devf s_hander_t devf s_mk_dir ( devf s_ h
9、an2 der_t dir ,const char 3 name ,void 3 info) devf s_hander_t devf s_register ( devf s_ han2 der_t dir ,const char 3 name ,unsigned int flags , unsigned int major ,unsigned int minor ,umode_t mode ,void 3 op s ,void 3 info) void devf s_unregister (devf s_hander_t de)在 Linux 操作系统编写设备驱动程序时有几个固定的功能模块:
10、 向 Linux 内核注册该设备时的初始化设备驱动程序模块; 用于系统卸载模块时删除设备驱动程序的模块;提供用户使用该设备驱动程序的文件操作接口模块。对于各类具体设备编写驱动程序时还应具有对该设备进行操作的应用函数。下面就以 ADS7843 驱动程序设计为例分析以上几个功能模块。1) ADS7843 向 Linux 内核注册设备时的初始化函数 int _init ads7843_t s_init (void) / / 设备初始化函数 int ret ; if ( ( ret = devf s _ register _ chrdev ( TS _ MAJOR , TS _ NAME , retu
11、rn ret ; devf s_t s_dir = devf s_mk_dir (NULL , “ touchscreen“ , NULL) ; / / 建立触摸屏设备目录 devf s_handle = devf s_register ( devf s_t s_dir , “ t s“ ,DEVFS_ FL_ DEFAUL T , TS _ MAJOR , 0 , S _ IFCHR | S _ IRUSR | S _ IWUSR , / / 注册设备 if ( ( ret = request_irq( IRQ_ GPIO_ADS7843 , ads7843_t s_inter-rupt ,
12、 SA_SHIRQ| SA_INTERRUPT , TS_NAME , dev_ id) ) ) / / 申请中断 print k (“ads7843_t s_init : failed to register IRQ n“ ) ; f ree_irq( IRQ_GPIO_ADS7843 , dev_id) ; return ret ; if ( ( ret = ads7843_init () ) ! = 0) / / 初始化触摸屏 f ree_irq( IRQ_GPIO_ADS7843 , dev_id) ; return ret ; GPDR0 GPDR0 Ads7843_Enable_I
13、RQ() ;/ / 开启中断 print k (“ads7843 touch screen driver initialized n“ ) ; return 0 ;2) 系统卸载 ADS7843 驱动程序功能函数 void _exit ads7843_t s_cleanup (void) / / 卸载驱动程序函数 if (in_timehandle) del_timer ( f ree_irq( IRQ_GPIO_ADS7843 , dev_id) ; / / 释放中断 devf s_unregister_chrdev( TS_MAJOR , TS_NAME) ;/ / 从系统中删除设备驱动程
14、序 print k (“ ads7843 touch screen driver removed n“ ) ;3) 在驱动程序最后用于模块初始化和删除驱动的功能函数 module_init (ads7843_t s_init) ;/ / 初始化驱动模块函数 module_exit (ads7843_t s_cleanup) ;/ / 删除驱动模块函数4) ADS7843 设备文件操作结构体 static st ruct file_operations ads7843_t s_fops = read :ads7843_t s_read , / / 从设备中读数据操作 poll :ads7843_
15、t s_poll , / / 查询设备操作 ioctl : ads7843_t s_ioctl , / / 设备 IO 控制操作 fasync : ads7843_t s_fasync , / / 异步通知操作 open : ads7843_t s_open , / / 打开设备操作 release : ads7843_t s_release , ; / / 当文件结构被释放时 ,调用释放操作由于文章篇幅所限,对设备文件操作的功能函数不再一一列出。5) ADS7843 具体操作函数 ADS7843 串行输出控制字函数 void ADS7843_din (char command) udelay
16、(DELA Y) ; / / 延时 for (int i = 0 ; i i) / / 数据位为 1 el se ADS7843_ClearBit (0 , ADS7843_DIN) ; / / 数据位为 0 udelay (DELA Y) ; ADS7843_SetBit (0 , ADS7843_CL K) ; / / 时钟变高微处理器读取 X 坐标值函数 (读取 Y 坐标值函数相类似 ,控制字为 0x90) int ADS7843_t s_measure_x (void) char i , int touch_data = 0 ; ADS7843_ClearBit (0 , ADS784
17、3_CS) ; / / 片选端置低电平 udelay(DELA Y) ; ADS7843_din (0xD0) ; / / 向 ADS7843 发送读 X 坐标控制字 0xD0 ADS7843_ClearBit (0 , ADS7843_CL K) ; udelay(DELA Y) ; while ( ! ( GPLR0 ADS7843_ClearBit (0 , ADS7843_CL K) ; for (i = 0 ; i = 3 ;/ / 对最后 4 位自动置 0 处理 return (touch_data 4 驱动模块的安装 在 Linux 操作系统中,对于已编好的设备驱动程序,利用编译
18、工具将驱动程序编译成驱动模块。对于驱动模块的安装,一种方法是重新编译 Linux 内核将驱动程序加载到系统内核, 另一种方法就是利用 inmod 和 rmmod 函数动态地装载和卸载设备驱动模块。我们在IntelXscalePXA255 评估板上利用重新编译 Linux 内核的方法将触摸屏控制器 ADS7843 的驱动模块加载到系统内核。运行后取得了理想的效果。5 结束语 触摸屏已成为现代嵌入式设备人机交互的首选输入设备,触摸屏控制器的驱动程序设计当然也就成为嵌入式设备研发的必需工作。本文以 ADS7843 为例介绍了在嵌入式 Linux 操作系统中触摸屏控制器驱动程序设计的编程方法。对于在嵌入式 Linux 操作系统下进行其它设备的驱动开发具有一定的启示作用。