008触摸屏的原理与应用

触摸屏的原理与应用

1.基本概念

项目实现过程中为了提高用户体验,一般都需要实现人机交互,常见的人机交互的方式有触摸按键、触摸屏、语音识别等方案,其中最常用的就是触摸屏。

img

在Linux系统下连接操作系统的输入设备不止一种,可能是一个键盘、一个 USB 鼠标或者是一块触摸屏,甚至是一个游戏机摇杆,Linux在处理这些复杂多样的输入设备时,采用的办法就是用中间层来屏蔽各种细节,所以就设计出输入子系统(输入设备的集合)来管理这些输入设备。

img

2.驱动原理

在Linux内核中,对输入设备的使用,实际上运用了3大块来管理,它们分别是所谓的输入设备驱动层输入子系统核心层以及事件触发层

(1) 设备驱动层提供对硬件各寄存器的读写访问和将底层硬件对用户输入访问的响应转换为标准的输入事件,再通过核心层提交给事件处理层。

(2) 子系统核心层对下提供了设备驱动层的编程接口,对上又提供了事件处理层的编程接口。

(3) 事件处理层就为我们用户空间的应用程序提供了统一访问设备的接口和驱动层提交来的事件处理。所以这使得我们输入设备的驱动部分不在用关心对设备文件的操作,而是要关心对各硬件寄存器的操作和提交的输入事件。

img

举例:当手指在屏幕上滑动的时候,驱动层中的触摸屏驱动会源源不断地产生触摸屏相关数据,并向上递送给内核输入子系统,输入子系统进一步将这些信息规整为统一的结构体,并借助事件触发层发往对应的设备节点文件,至此,应用程序即可从这些设备节点文件读取相关信息。

注意:底层驱动产生的设备数据与上层应用读取设备数据是两个完全异步的过程,彼此之间是没有耦合和约束的,例如:当底层驱动产生的触摸屏坐标信息比应用层读取的速度要快时,应用程序将会丢失一部分坐标信息。

3. 硬件信息

在最靠近应用程序的事件触发层上内核所获知的各类输入事件,比如键盘被按了一下、触摸屏被滑了一下等,都将被统一封装在一个叫做input_event的输入信息结构体当中,该结构体在名字叫做input.h的头文件中定义,头文件路径为*/usr/inlucde/linux/input.h*

img

img

img

3.1 type

事件类型(type) 说明
EV_SYN 事件间的分割标志,有些事件可能会在时间和空间上产生延续,比如持续按住一个按键,为了更好地管理这些持续的事件,EV_SYN用以将他们分割成一个个的小的数据包。
EV_KEY 用以描述键盘,按键或者类似键盘的设备的状态变化。
EV_REL 相对位移,比如鼠标的移动,滚轮的转动等。
*EV_ABS* 绝对位移,比如触摸屏上的坐标值。
EV_LED 用于控制设备上的LED灯的开关,比如按下键盘的大写锁定键会同时产生 ”EV_KEY” 和 ”EV_LED” 两个事件。
… … … …

3.2code

用于对事件的类型作进一步的描述。比如:当发生EV_KEY事件时,则可能是键盘被按下了,那么究竟是哪个按键被按下了呢?此时查看code就知道了。当发生EV_REL事件时,也许是鼠标动了,也许是滚轮动了。这时可以用code的值来加以区分。

事件类型(type) 事件代码(code) 说明
EV_KEY BTN_TOUCH 触摸屏发生了按压、松开事件
EV_KEY KEY_LEFT 键盘的左箭头发生了按压、松开事件
EV_KEY KEY_RIGHT 键盘的右箭头发生了按压、松开事件
EV_ABS ABS_X 触摸屏发生了x轴坐标事件
EV_ABS ABS_Y 触摸屏发生了y轴坐标事件
EV_REL ABS_Y 触摸屏发生了y轴坐标事件
… … … … … …

3.3value

当code都不足以区分事件的性质的时候,可以用value来确认。比如由EV_REL和REL_WHEEL确认发生了鼠标滚轮的动作,但是究竟是向上滚还是向下滚呢?再比如由由EV_KEY和KEY_F确认了发生键盘上F键的动作,但究竟是按下呢还是弹起呢?这时都可以用value值来进一步判断。

事件类型(type) 事件代码(code) 发生值(value) 说明
EV_KEY BTN_TOUCH 大于0 手指按压了触摸屏
EV_KEY BTN_TOUCH 0 手指松开了触摸屏
EV_ABS ABS_X 213 触摸屏产生了一个233的 x 轴坐标
EV_ABS ABS_Y 448 触摸屏产生了一个448的 y 轴坐标
… … … … … … … …

4.设备文件

触摸屏属于字符设备,所以在开发板的Linux系统已经默认把触摸屏的驱动程序安装在Linux内核中,当触摸屏的驱动安装完成后,系统内核会自动在开发板的Linux系统的 /dev目录生成对应的设备文件,所以触摸屏的设备文件的路径:*/dev/input/event0*

img

5.程序设计

image-20260122204837299

注意:触摸屏的坐标要和LCD屏幕的坐标对应起来

image-20260122204951933

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include "linux/input.h"
int main(int argc,char * argv[])
{
	int x=0;
	int y=0;
	int cnt=0;
	//1、打开触摸屏
	int ts_fd=open("/dev/input/event2",O_RDWR);
	//2、读取
	struct input_event ts_event;
	//3、分析打印
	while(1){
	read(ts_fd,&ts_event,sizeof(ts_event));
	if(ts_event.type == EV_ABS ){
		if(ts_event.code == ABS_X){
			x=ts_event.value;
			cnt++;
		}
		if(ts_event.code == ABS_Y){
			y=ts_event.value;
			cnt++;
		}
		if(cnt>=2){
			printf("x=%d,y=%d\n",x,y);
			cnt=0;
	}
	}

	}
		//4、关闭
	close(ts_fd);
	return 0;
}	
posted @ 2026-01-22 20:56  郭小胖  阅读(4)  评论(0)    收藏  举报