Linux输入设备应用编程(触摸屏获取坐标信息)

上一章学习了开发板外接键盘并获取键盘的的输入

Linux输入设备应用编程(键盘,按键)-CSDN博客

本章编写触摸屏应用程序,获取触摸屏的坐标信息并将其打印出来

目录

一 触摸屏数据分析(触摸,点击,松开)

1.1 硬件须知 

1.2 触摸屏信息分析

二 触摸屏应用编程

2.1 获取触摸屏的最大同时触点

2.2  触摸屏单点触点编程


一 触摸屏数据分析(触摸,点击,松开)

1.1 硬件须知 

首先在测试触摸屏之前,需要保证开发板上已经连接了LCD屏

使用命令"cat /proc/bus/input/devices",确定触摸屏对应的设备节点(本人将指令封装成了cat_dev),如下所示:  

7寸的LCD屏 红线划的是我LCD的设备名与设备节点

1.2 触摸屏信息分析

执行input文件后,一个手指点击触摸屏后松开,终端将会打印如下信息:  

首先第一行上报了绝对位移事件EV_ABS(type=3)中的ABS_MT_TRACKING_ID(code=57)事件,并且value值等于246,也就是ID,这个ID是一个非负数,所以表示这是一个新的触摸点被创建,也就意味着触摸屏上产生了一个新的触摸点(手指按下)。

第二行上报了绝对位移事件EV_ABS(type=3)中的ABS_MT_POSITION_X(code=53)事件,其value对应的便是触摸点的X坐标;

第三行上报了ABS_MT_POSITION_Y(code=54)事件,其value值对应的便是触摸点Y坐标,所以由此可知该触摸点的坐标为(890, 445)。

第四行上报了按键类事件EV_KEY(type=1)中的BTN_TOUCH(code=330),value值等于1,表示这是触摸屏上最先产生的触摸点(slot=0、也就是触摸点0)。

第五行和第六行分别上报了绝对位移事件EV_ABS(type=3)中的ABS_X(code=0)和ABS_Y(code=1),其value分别对应的是触摸点的X坐标和Y坐标。多点触摸设备也会通过ABS_X、ABS_Y事件上报触摸点的X、Y坐标,但通常只有触摸点0支持,所以可以把多点触摸设备当成单点触摸设备来使用。

第七行上报了同步类事件EV_SYN(type=0)中的SYN_REPORT(code=0)事件,表示此次触摸点的信息全部上报完毕。

第八行当手指松开时,触摸点就会被销毁,上报ABS_MT_TRACKING_ID事件,并将value设置为-1(ID)

第四行上报了按键类事件EV_KEY(type=1)中的BTN_TOUCH(code=330),value值等于0,表示触摸屏上的触摸点销毁

最后一行上报同步事件(type=0、code=0),告知应用层数据完整。

二 触摸屏应用编程

2.1 获取触摸屏的最大同时触点

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>

int main(int argc, char *argv[])
{
    struct input_absinfo info;    //调用 ioctl()会将获取到的信息写入到struct input_absinfo对象
    int fd = -1;
    int max_slots;                            //最大触摸点数

    /* 校验传参 */
    if (2 != argc) {
        fprintf(stderr, "usage: %s <input-dev>\n", argv[0]);
        exit(-1);
    }

    /* 打开文件 */
    if (0 > (fd = open(argv[1], O_RDONLY))) {
        perror("open error");
        exit(-1);
    }

    /* 获取slot信息 */
    if (0 > ioctl(fd, EVIOCGABS(ABS_MT_SLOT), &info)) {
        perror("ioctl error");
        close(fd);
        exit(-1);
    }

    max_slots = info.maximum + 1 - info.minimum;
    printf("max_slots: %d\n", max_slots);

    /* 关闭、退出 */
    close(fd);
    exit(0);
}

 代码写完后,进行交叉编译,通过scp指令将文件发送到开发板上,然后执行input_slot文件

所以从打印结果可知,我们这个屏是一个5点触摸屏。 

2.2  触摸屏单点触点编程

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>

int main(int argc, char *argv[])
{
	int fd = -1;
	struct input_event in_ev;
	int x = 0;                                      //触摸点 x和 y坐标 
	int y = 0;
	int start = 3;                             //用于记录 BTN_TOUCH事件的 value,1表示按下,0表示松开,-1表示移动
	int valid = -1;                             //用于记录数据是否有效(我们关注的信息发生更新表示有效,1表示有效,0表示无效

	/* 校验传参 */
	if (2 != argc) {
		fprintf(stderr, "usage: %s <input-dev>\n", argv[0]);
		exit(-1);
	}

	/* 打开文件 */
	if (0 > (fd = open(argv[1], O_RDONLY))) {
		perror("open error");
		exit(-1);
	}

	while(1)
	{
		if(sizeof(struct input_event) != read(fd,&in_ev,sizeof(struct input_event)))
		{
			perror(" ");
			exit(-1);
		}
		switch (in_ev.type)
		{
			case EV_KEY:  //按键事件
				if (BTN_TOUCH == in_ev.code)    //触摸屏第一个点
				{                
					start = in_ev.value;       //触摸屏状态
					valid = 1;           //同步时间标志位
				}
				break;
			case EV_ABS:    //绝对位移事件             
				switch (in_ev.code) 
				{             
					case ABS_X: //X坐标
						x = in_ev.value;
						valid = 1;                 
						break;             
					case ABS_Y: //Y坐标                 
						y = in_ev.value;                 
						valid = 1;                 
						break;             
				}             
				break; 
			case EV_SYN:    //同步事件
				if (SYN_REPORT == in_ev.code) {
					if (valid) {//判断是否有效
						switch (start) {//判断状态
							case 1:
								printf("按下(%d, %d)\n", x, y);
								break;
							case 0:
								printf("松开\n");
								break;
							case -1:
								printf("移动(%d, %d)\n", x, y);
								break;
						}

						valid = 0; //重置valid
						start = -1; //重置start
					}
				}
				break;
		}
	}

	/* 关闭、退出 */
	close(fd);
	exit(0);
}

程序中首先校验传参,通过传参的方式将触摸屏设备文件路径传入到程序中,main()函数中定义了4个变量:

  1. 变量x表示触摸点的X坐标;
  2. 变量y表示触摸点的Y坐标;
  3. 变量start表示手指状态时候按下、松开还是滑动,start=1表示手指按下、start=0表示手指松开、start=-1表示手指滑动;
  4. 变量valid表示数据是否有效,valid=1表示有效、valid=0表示无效;有效指的是我们检测的信息发生了更改,譬如程序中只检测了手指的按下、松开动作以及坐标值的变化。

接着调用open()打开触摸屏设备文件得到文件描述符fd;在for循环之前,首先对x、y、start、valid这4个变量进行初始化操作。在for循环读取触摸屏上报的数据,将读取到的数据存放在struct input_event数据结构中。在switch…case语句中对读取到的数据进行解析,获取BTN_TOUCH事件的value数据,判断触摸屏是按下还是松开状态,获取ABS_X和ABS_Y事件的value变量,得到触摸点的X轴坐标和Y轴坐标。

当上报同步事件时,表示数据已经完整,接着对我们得到的数据进行分析、打印坐标信息。

将编译得到的可执行文件拷贝到开发板,准备进行测试。

当手指点击触摸屏时会打印"按下(X, Y)",松开时会打印"松开",手指在触摸屏上滑动时会打印"移动(X, Y)"等信息。

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Linux 应用编程、系统编程和网络编程是三个不同的概念,它们在Linux环境下的应用领域和技术侧重点有所不同。 Linux 应用编程是指在Linux操作系统上开发应用程序的过程。这包括使用各种编程语言(如C、C++、Python等)和开发工具来编写应用程序,涉及到图形界面(GUI)编程、数据库访问、文件操作、多线程编程等。应用程序开发者主要关注的是实现软件功能、用户交互以及提供高效的应用性能。 系统编程是指开发与操作系统内部交互的软件。这包括开发驱动程序、操作系统内核模块、系统服务等。系统编程需要深入了解操作系统的内部机制和数据结构,以便与硬件设备和操作系统进行交互,实现底层功能。C语言是常用的系统编程语言,它提供了访问底层API和系统调用的接口。 网络编程是指在计算机网络中开发应用程序的过程。Linux下的网络编程主要涉及使用套接字(socket)API来实现网络通信。开发者可以利用套接字API建立客户端和服务器之间的连接,发送和接收数据等。网络编程需要了解网络协议(如TCP/IP、UDP等)、网络通信原理以及常见的网络编程技术,如多线程/多进程服务器、异步IO、网络安全等。 所以,Linux应用编程、系统编程和网络编程在技术和应用领域上有所不同,但它们都是在Linux环境下开发软件的重要领域。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@ChenPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值