触摸屏的硬件原理.docx

上传人:b****6 文档编号:8388796 上传时间:2023-01-31 格式:DOCX 页数:14 大小:22.12KB
下载 相关 举报
触摸屏的硬件原理.docx_第1页
第1页 / 共14页
触摸屏的硬件原理.docx_第2页
第2页 / 共14页
触摸屏的硬件原理.docx_第3页
第3页 / 共14页
触摸屏的硬件原理.docx_第4页
第4页 / 共14页
触摸屏的硬件原理.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

触摸屏的硬件原理.docx

《触摸屏的硬件原理.docx》由会员分享,可在线阅读,更多相关《触摸屏的硬件原理.docx(14页珍藏版)》请在冰豆网上搜索。

触摸屏的硬件原理.docx

触摸屏的硬件原理

12.2.1触摸屏的硬件原理

按照触摸屏的工作原理和传输信息的介质,我们把触摸屏分为4种:

电阻式、电容感应式、红外线式以及表面声波式。

电阻式触摸屏利用压力感应进行控制,包含上下叠合的两个透明层,通常还要用一种弹性材料来将两层隔开。

在触摸某点时,两层会在此点接通。

四线和八线触摸屏由两层具有相同表面电阻的透明阻性材料组成,五线和七线触摸屏由一个阻性层和一个导电层组成。

所有的电阻式触摸屏都采用分压器原理来产生代表X坐标和Y坐标的电压。

如图12.4所示,分压器是通过将两个电阻进行串联来实现的。

电阻R1连接正参考电压VREF,电阻R2接地。

两个电阻连接点处的电压测量值与R2的阻值成正比。

为了在电阻式触摸屏上的特定方向测量一个坐标,需要对一个阻性层进行偏置:

将它的一边接VREF,另一边接地。

同时,将未偏置的那一层连接到一个ADC的高阻抗输入端。

当触摸屏上的压力足够大,两层之间发生接触时,电阻性表面被分隔为两个电阻。

它们的阻值与触摸点到偏置边缘的距离成正比。

触摸点与接地边之间的电阻相当于分压器中下面的那个电阻。

因此,在未偏置层上测得的电压与触摸点到接地边之间的距离成正比。

四线触摸屏包含两个阻性层。

其中一层在屏幕的左右边缘各有一条垂直总线,另一层在屏幕的底部和顶部各有一条水平总线,如图12.5所示。

为了在X轴方向进行测量,将左侧总线偏置为0V,右侧总线偏置为VREF。

将顶部或底部总线连接到ADC,当顶层和底层相接触时即可作一次测量。

为了在Y轴方向进行测量,将顶部总线偏置为VREF,底部总线偏置为0V。

将ADC输入端接左侧总线或右侧总线,当顶层与底层相接触时即可对电压进行测量。

图12.4电阻触摸屏分压图12.5四线电阻式触摸屏

S3C2410接4线电阻式触摸屏的电路原理如图12.6所示。

S3C2410提供了nYMON、YMON、nXPON和XMON直接作为触摸屏的控制信号,它通过连接FDC6321场效应管触摸屏驱动器控制触摸屏。

输入信号在经过阻容式低通滤器滤除坐标信号噪声后被接入S3C2410内集成的ADC(模数转换器)的模拟信号输入通道AIN5、AIN7。

图12.6S3C2410连接4线电阻式触摸屏

S3C2410内置了一个8信道的10位ADC,该ADC能以500KS/S的采样速率将外部的模拟信号转换为10位分辨率的数字量。

因此,ADC能与触摸屏控制器协同工作,完成对触摸屏绝对地址的测量。

S3C2410的ADC和触摸屏接口可工作于5种模式,分别如下。

1.普通转换模式(NormalConversonMode)

普通转换模式(AUTO_PST=0,XY_PST=0)用来进行一般的ADC转换,例如通过ADC测量电池电压等。

2.独立X/Y位置转换模式(SeparateX/YPositionConversionMode)

独立X/Y轴坐标转换模式其实包含了X轴模式和Y轴模式。

为获得X、Y坐标,需首先进行X轴的坐标转换(AUTO_PST=0,XY_PST=1),X轴的转换资料会写到ADCDAT0寄存器的XPDAT中,等待转换完成后,触摸屏控制器会产生INT_ADC中断。

然后,进行Y轴的坐标转换(AUTO_PST=0,XY_PST=2),Y轴的转换资料会写到ADCDAT1寄存器的YPDAT中,等待转换完成后,触摸屏控制器也会产生INT_ADC中断。

3.自动(连续)X/Y位置转换模式(AutoX/YPositionConversionMode)

自动(连续)X/Y位置转换模式(AUTO_PST=1,XY_PST=0)运行方式是触摸屏控制自动转换X位置和Y位置。

触摸屏控制器在ADCDAT0的XPDATA位写入X测定数据,在ADCDAT1的YPADATA位写入Y测定数据。

自动(连续)位置转换后,触摸屏控制器产生INT_ADC中断。

4.等待中断模式(WaitforInterruptMode)

当触摸屏控制器等待中断模式时,它等待触摸屏触点信号的到来。

当触点信号到来时,控制器产生INT_TC中断信号。

然后,X位置和Y位置能被适当地转换模式(独立X/Y位置转换模式或自动X/Y位置转换模式)读取到。

5.待机模式(StandbyMode)

当ADCCON寄存器的STDBM位置1时,待机模式被激活。

在这种模式下,A/D转换动作被禁止,ADCDAT0的XPDATA位和ADXDATA1的YPDAT保留以前被转换的数据。

12.2.2触摸屏设备驱动中数据结构

触摸屏设备结构体的成员与按键设备结构体的成员类似,也包含一个缓冲区,同时包括自旋锁、等待队列和fasync_struct指针,如代码清单12.12所示。

代码清单12.12触摸屏设备结构体

1typedefstruct

2{

3unsignedintpenStatus;/*PEN_UP,PEN_DOWN,PEN_SAMPLE*/

4TS_RETbuf[MAX_TS_BUF];/*缓冲区*/

5unsignedinthead,tail;/*缓冲区头和尾*/

6wait_queue_head_twq;/*等待队列*/

7spinlock_tlock;

8#ifdefUSE_ASYNC

9structfasync_struct*aq;

10#endif

11structcdevcdev;

12}TS_DEV;

触摸屏结构体中包含的TS_RET值的类型定义如代码清单12.13所示,包含X、Y坐标和状态(PEN_DOWN、PEN_UP)等信息,这个信息会在用户读取触摸信息时复制到用户空间。

代码清单12.13TS_RET结构体

1typedefstruct

2{

3unsignedshortpressure;//PEN_DOWN、PEN_UP

4unsignedshortx;//x坐标

5unsignedshorty;//y坐标

6unsignedshortpad;

7}TS_RET;

在触摸屏设备驱动中,将实现open()、release()、read()、fasync()和poll()函数,因此,其文件操作结构体定义如代码清单12.14所示。

代码清单12.14触摸屏驱动文件操作结构体

1staticstructfile_operationss3c2410_fops=

2{

3owner:

THIS_MODULE,

4open:

s3c2410_ts_open,//打开

5read:

s3c2410_ts_read,//读坐标

6release:

7s3c2410_ts_release,

8#ifdefUSE_ASYNC

9fasync:

s3c2410_ts_fasync,//fasync()函数

10#endif

11poll:

s3c2410_ts_poll,//轮询

12};

12.2.3触摸屏驱动中的硬件控制

代码清单12.15中的一组宏用于控制触摸屏和ADC进入不同的工作模式,如等待中断、X/Y位置转换等。

代码清单12.15触摸屏和ADC硬件控制

1#definewait_down_int(){ADCTSC=DOWN_INT|XP_PULL_UP_EN|\

2XP_AIN|XM_HIZ|YP_AIN|YM_GND|\

3XP_PST(WAIT_INT_MODE);}

4#definewait_up_int(){ADCTSC=UP_INT|XP_PULL_UP_EN|XP_AIN|\

5XM_HIZ|YP_AIN|YM_GND|XP_PST(WAIT_INT_MODE);}

6#definemode_x_axis(){ADCTSC=XP_EXTVLT|XM_GND|YP_AIN\

7|YM_HIZ|XP_PULL_UP_DIS|XP_PST(X_AXIS_MODE);}

8#definemode_x_axis_n(){ADCTSC=XP_EXTVLT|XM_GND|YP_AIN|\

9YM_HIZ|XP_PULL_UP_DIS|XP_PST(NOP_MODE);}

10#definemode_y_axis(){ADCTSC=XP_AIN|XM_HIZ|YP_EXTVLT\

11|YM_GND|XP_PULL_UP_DIS|XP_PST(Y_AXIS_MODE);}

12#definestart_adc_x(){ADCCON=PRESCALE_EN|PRSCVL(49)|\

13ADC_INPUT(ADC_IN5)|ADC_START_BY_RD_EN|\

14ADC_NORMAL_MODE;\

15ADCDAT0;}

16#definestart_adc_y(){ADCCON=PRESCALE_EN|PRSCVL(49)|\

17ADC_INPUT(ADC_IN7)|ADC_START_BY_RD_EN|\

18ADC_NORMAL_MODE;\

19ADCDAT1;}

20#definedisable_ts_adc(){ADCCON&=~(ADCCON_READ_START);}

12.2.4触摸屏驱动模块加载和卸载函数

在触摸屏设备驱动的模块加载函数中,要完成申请设备号、添加cdev、申请中断、设置触摸屏控制引脚(YPON、YMON、XPON、XMON)等多项工作,如代码清单12.16所示。

代码清单12.16触摸屏设备驱动的模块加载函数

1staticint__inits3c2410_ts_init(void)

2{

3intret;

4tsEvent=tsEvent_dummy;

5...//申请设备号,添加cdev

6

7/*设置XP、YM、YP和YM对应引脚*/

8set_gpio_ctrl(GPIO_YPON);

9set_gpio_ctrl(GPIO_YMON);

10set_gpio_ctrl(GPIO_XPON);

11set_gpio_ctrl(GPIO_XMON);

12

13/*使能触摸屏中断*/

14ret=request_irq(IRQ_ADC_DONE,s3c2410_isr_adc,

15SA_INTERRUPT,DEVICE_NAME,s3c2410_isr_adc);

16if(ret)

17gotoadc_failed;

18ret=request_irq(IRQ_TC,s3c2410_isr_tc,SA_INTERRUPT,

19DEVICE_NAME,s3c2410_isr_tc);

20if(ret)

21gototc_failed;

22

23/*置于等待触点中断模式*/

24wait_down_int();

25

26printk(DEVICE_NAME"initialized\n");

27

28return0;

29tc_failed:

30free_irq(IRQ_ADC_DONE,s3c2410_isr_adc);

31adc_failed:

32returnret;

33}

在触摸屏设备驱动的模块卸载函数中,要完成释放设备号、删除cdev、释放中断等工作,如代码清单12.17所示。

代码清单12.17触摸屏设备驱动模块卸载函数

1staticvoid__exits3c2410_ts_exit(void)

2{

3...//释放设备号,删除cdev

4free_irq(IRQ_ADC_DONE,s3c2410_isr_adc);

5free_irq(IRQ_TC,s3c2410_isr_tc);

6}

12.2.5触摸屏驱动中断、定时器处理程序

由12.2.1小节对触摸屏和ADC模式的分析,可知触摸屏驱动中会产生两类中断,一类是触点中断(INT-TC),一类是X/Y位置转换中断(INT-ADC)。

在前一类中断发生后,若之前处于PEN_UP状态,则应该启动X/Y位置转换。

另外,将抬起中断也放在INT-TC处理程序中,它会调用tsEvent()完成等待队列和信号的释放,如代码清单12.18所示。

代码清单12.18触摸屏设备驱动的触点/抬起中断处理程序

1staticvoids3c2410_isr_tc(intirq,void*dev_id,structpt_regs*reg)

2{

3spin_lock_irq(&(tsdev.lock));

4if(tsdev.penStatus==PEN_UP)

5{

6start_ts_adc();//开始X/Y位置转换

7}

8else

9{

10tsdev.penStatus=PEN_UP;

11DPRINTK("PENUP:

x:

%08d,y:

%08d\n",x,y);

12wait_down_int();//置于等待触点中断模式

13tsEvent();

14}

15spin_unlock_irq(&(tsdev.lock));

16}

当X/Y位置转换中断发生后,应读取X、Y的坐标值,填入缓冲区,如代码清单12.19所示。

代码清单12.19触摸屏设备驱动X/Y位置转换中断处理程序

1staticvoids3c2410_isr_adc(intirq,void*dev_id,structpt_regs*reg)

2{

3spin_lock_irq(&(tsdev.lock));

4if(tsdev.penStatus==PEN_UP)

5s3c2410_get_XY();//读取坐标

6#ifdefHOOK_FOR_DRAG

7else

8s3c2410_get_XY();

9#endif

10spin_unlock_irq(&(tsdev.lock));

11}

上述程序中调用的s3c2410_get_XY()用于获得X、Y坐标,它使用代码清单12.15的硬件操作宏实现,如代码清单12.20所示。

代码清单12.20触摸屏设备驱动中获得X、Y坐标

1staticinlinevoids3c2410_get_XY(void)

2{

3if(adc_state==0)

4{

5adc_state=1;

6disable_ts_adc();//禁止INT-ADC

7y=(ADCDAT0&0x3ff);//读取坐标值

8mode_y_axis();

9start_adc_y();//开始y位置转换

10}

11elseif(adc_state==1)

12{

13adc_state=0;

14disable_ts_adc();//禁止INT-ADC

15x=(ADCDAT1&0x3ff);//读取坐标值

16tsdev.penStatus=PEN_DOWN;

17DPRINTK("PENDOWN:

x:

%08d,y:

%08d\n",x,y);

18wait_up_int();//置于等待抬起中断模式

19tsEvent();

20}

21}

代码清单12.18、12.20中调用的tsEvent最终为tsEvent_raw(),这个函数很关键,当处于PEN_DOWN状态时调用该函数,它会完成缓冲区的填充、等待队列的唤醒以及异步通知信号的释放;否则(处于PEN_UP状态),将缓冲区头清0,也唤醒等待队列并释放信号,如代码清单12.21所示。

代码清单12.21触摸屏设备驱动的tsEvent_raw()函数

1staticvoidtsEvent_raw(void)

2{

3if(tsdev.penStatus==PEN_DOWN)

4{

5/*填充缓冲区*/

6BUF_HEAD.x=x;

7BUF_HEAD.y=y;

8BUF_HEAD.pressure=PEN_DOWN;

9

10#ifdefHOOK_FOR_DRAG

11ts_timer.expires=jiffies+TS_TIMER_DELAY;

12add_timer(&ts_timer);//启动定时器

13#endif

14}

15else

16{

17#ifdefHOOK_FOR_DRAG

18del_timer(&ts_timer);

19#endif

20

21/*填充缓冲区*/

22BUF_HEAD.x=0;

23BUF_HEAD.y=0;

24BUF_HEAD.pressure=PEN_UP;

25}

26

27tsdev.head=INCBUF(tsdev.head,MAX_TS_BUF);

28wake_up_interruptible(&(tsdev.wq));//唤醒等待队列

29

30#ifdefUSE_ASYNC

31if(tsdev.aq)

32kill_fasync(&(tsdev.aq),SIGIO,POLL_IN);//异步通知

33#endif

34}

在包含了对拖动轨迹支持的情况下,定时器会被启用,周期为10ms,在每次定时器处理函数被引发时,调用start_ts_adc()开始X/Y位置转换过程,如代码清单12.22所示。

代码清单12.22触摸屏设备驱动的定时器处理函数

1#ifdefHOOK_FOR_DRAG

2staticvoidts_timer_handler(unsignedlongdata)

3{

4spin_lock_irq(&(tsdev.lock));

5if(tsdev.penStatus==PEN_DOWN)

6{

7start_ts_adc();//开始X/Y位置转换

8}

9spin_unlock_irq(&(tsdev.lock));

10}

11#endif

12.2.6触摸屏设备驱动的打开、释放函数

在触摸屏设备驱动的打开函数中,应初始化缓冲区、penStatus和定期器、等待队列及tsEvent时间处理函数指针,如代码清单12.23所示。

代码清单12.23触摸屏设备驱动的打开函数

1staticints3c2410_ts_open(structinode*inode,structfile*filp)

2{

3tsdev.head=tsdev.tail=0;

4tsdev.penStatus=PEN_UP;//初始化触摸屏状态为PEN_UP

5#ifdefHOOK_FOR_DRAG//如果定义了拖动钩子函数

6init_timer(&ts_timer);//初始化定时器

7ts_timer.function=ts_timer_handler;

8#endif

9tsEvent=tsEvent_raw;

10init_waitqueue_head(&(tsdev.wq));//初始化等待队列

11

12return0;

13}

触摸屏设备驱动的释放函数非常简单,删除为用于拖动轨迹所使用的定时器即可,如代码清单12.24所示。

代码清单12.24触摸屏设备驱动的释放函数

1staticints3c2410_ts_release(structinode*inode,structfile*filp)

2{

3#ifdefHOOK_FOR_DRAG

4del_timer(&ts_timer);//删除定时器

5#endif

6return0;

7}

12.2.7触摸屏设备驱动的读函数

触摸屏设备驱动的读函数实现缓冲区中信息向用户空间的复制,当缓冲区有内容时,直接复制;否则,如果用户阻塞访问触摸屏,则进程在等待队列上睡眠,否则,立即返回-EAGAIN,如代码清单12.25所示。

代码清单12.25触摸屏设备驱动的读函数

1staticssize_ts3c2410_ts_read(structfile*filp,char*buffer,size_tcount,

2loff_t*ppos)

3{

4TS_RETts_ret;

5

6retry:

7if(tsdev.head!

=tsdev.tail)//缓冲区有信息

8{

9intcount;

10count=tsRead(&ts_ret);

11if(count)

12copy_to_user(buffer,(char*)&ts_ret,count);//复制到用户空间

13returncount;

14}

15else

16{

17if(filp->f_flags&O_NONBLOCK)//非阻塞读

18return-EAGAIN;

19interruptible_sleep_on(&(tsdev.wq));//在等待队列上睡眠

20if(signal_pending(current))

21return-ERESTARTSYS;

22gotoretry;

23}

24

25returnsizeof(TS_RET);

26}

12.2.8触摸屏设备驱动的轮询与异步通知

在触摸屏设备驱动中,通过s3c2410_ts_poll()函数实现了轮询接口,这个函数的实现非常简单。

它将等待队列添加到poll_table,当缓冲区有数据时,返回资源可读取标志,否则返回0,如代码清单12.26所示。

代码清单12.26触摸屏设备驱动的poll()函数

1staticunsignedints3c2410_ts_poll(structfile*filp,structpoll_table_struct*wait)

2{

3poll_wait(filp,&(tsdev.wq),wait);//添加等待队列到poll_table

4return(tsdev.head==tsdev.tail)?

0:

(POLLIN|POLLRDNORM);

5}

而为了实现触摸屏设备驱动对应用程序的异步通知,设备驱动中要实现s3c2410_ts_fasync()函数,这个函数与第9章给出的模板完全一样,如代码清单12.27所示。

代码清单12.27触摸屏设备驱动的fasync()函数

1#ifdefUSE_ASYNC

2staticints3c2410_ts_fasync(intfd,structfile*f

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 工学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1