LV17-01-输入类设备-05-触摸屏tslib开源库-03-应用开发实例

本文主要是输入类设备控制——触摸屏tslib开源库应用开发实例的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
PC端开发环境 Windows Windows11
Ubuntu Ubuntu20.04.2的64位版本
VMware® Workstation 17 Pro 17.6.0 build-24238078
终端软件 MobaXterm(Professional Edition v23.0 Build 5042 (license))
Win32DiskImager Win32DiskImager v1.0
Linux开发板环境 Linux开发板 正点原子 i.MX6ULL Linux 阿尔法开发板
uboot NXP官方提供的uboot,NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03)
linux内核 linux-4.15(NXP官方提供)
点击查看本文参考资料
分类 网址 说明
官方网站 https://www.arm.com/ ARM官方网站,在这里我们可以找到Cotex-Mx以及ARMVx的一些文档
https://www.nxp.com.cn/ NXP官方网站
https://www.nxpic.org.cn/NXP 官方社区
https://u-boot.readthedocs.io/en/latest/u-boot官网
https://www.kernel.org/linux内核官网
其他网站 kernel - Linux source code (v4.15) - Bootlin linux内核源码在线查看
点击查看相关文件下载
分类 网址 说明
NXP https://github.com/nxp-imx NXP imx开发资源GitHub组织,里边会有u-boot和linux内核的仓库
https://elixir.bootlin.com/linux/latest/source 在线阅读linux kernel源码
nxp-imx/linux-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga NXP linux内核仓库tags中的rel_imx_4.1.15_2.1.0_ga
nxp-imx/uboot-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga NXP u-boot仓库tags中的rel_imx_4.1.15_2.1.0_ga
I.MX6ULL i.MX 6ULL Applications Processors for Industrial Products I.MX6ULL 芯片手册(datasheet,可以在线查看)
i.MX 6ULL Applications ProcessorReference Manual I.MX6ULL 参考手册(下载后才能查看,需要登录NXP官网)

一、单点触摸

1. 代码编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.h>
#include <stdlib.h>

#include "../../lib/tslib-1.16/include/tslib.h" //包含tslib.h头文件

int main(int argc, char *argv[])
{
struct tsdev *ts = NULL;
struct ts_sample samp = {0};
int pressure = 0;//用于保存上一次的按压力,初始为0,表示松开

/* 打开并配置触摸屏设备 */
ts = ts_setup(NULL, 0);
if (NULL == ts)
{
fprintf(stderr, "ts_setup error");
exit(EXIT_FAILURE);
}

/* 读数据 */
while(1)
{

if (0 > ts_read(ts, &samp, 1))
{
fprintf(stderr, "ts_read error");
ts_close(ts);
exit(EXIT_FAILURE);
}

if (samp.pressure)
{
//按压力>0
if (pressure) //若上一次的按压力>0
printf("move(%d, %d)\n", samp.x, samp.y);
else
printf("press(%d, %d)\n", samp.x, samp.y);
}
else
printf("lift\n");//打印坐标

pressure = samp.pressure;
}

ts_close(ts);
exit(EXIT_SUCCESS);
}

代码中通过判断按压力大小确定触摸的状态,如果按压力等于 0 则表示手指已经松开;按压力大于 0,则需根据上一次的按压力是否大于 0 来判断。

注意:

(1)在编译的时候需要链接ts库文件,我们要是将移植的tslib库拷贝到其他地方使用一定要注意是不是与windows的共享目录,在windows下没有软链接的概念,所以即便cp命令加上-a -p这些参数也无济于事,我们需要手动复制文件然后重命名。

(2)注意指定包含的头文件的路径,可以在makefile中指定,我这里在c文件中也直接指定了,这是为了在不配置clangd工具的情况下让其也能找到对应头文件的位置,以防止语法检测的标红。

(4)编译时,链接库可以这样写:

1
${CC} -I <tslib安装目录>/include -L <tslib安装目录>/lib -lts -o app_demo app_demo.c

-I 选项指定头文件的路径,也就是指定 tslib 安装目录下的 include 目录,如果不指定头文件路径,编译时将会找不到 tslib.h 头文件; -L 选项用于指定库文件的路径, 也就是指定 tslib 安装目录下的 lib 目录; 我们将 tslib 编译成了动态库文件, 以库文件的形式提供,编译时需要链接到这些库文件;而-l(小写的L) 选项则用于指定链接库(也可写成-l ts,也就是 libts.so 库文件, Linux 中,动态库文件的命名方式为 lib+名字+.so)。

2. 开发板测试

测试结果如下:

image-20240922221518086

二、多点触摸

1. 代码编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <linux/input.h>

#include "../../lib/tslib-1.16/include/tslib.h"

int main(int argc, char *argv[])
{
struct tsdev *ts = NULL;
struct ts_sample_mt *mt_ptr = NULL;
struct input_absinfo slot;
int max_slots;
unsigned int pressure[12] = {0}; //用于保存每一个触摸点上一次的按压力,初始为0,表示松开
int i;

/* 打开并配置触摸屏设备 */
ts = ts_setup(NULL, 0);
if (NULL == ts)
{
fprintf(stderr, "ts_setup error");
exit(EXIT_FAILURE);
}

/* 获取触摸屏支持的最大触摸点数 */
if (0 > ioctl(ts_fd(ts), EVIOCGABS(ABS_MT_SLOT), &slot)) {
perror("ioctl error");
ts_close(ts);
exit(EXIT_FAILURE);
}

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

/* 内存分配 */
mt_ptr = calloc(max_slots, sizeof(struct ts_sample_mt));

/* 读数据 */
while(1)
{

if (0 > ts_read_mt(ts, &mt_ptr, max_slots, 1))
{
perror("ts_read_mt error");
ts_close(ts);
free(mt_ptr);
exit(EXIT_FAILURE);
}

for (i = 0; i < max_slots; i++)
{

if (mt_ptr[i].valid)
{
//有效表示有更新!
if (mt_ptr[i].pressure)
{
//如果按压力>0
if (pressure[mt_ptr[i].slot])//如果上一次的按压力>0
printf("slot<%d>, move(%d, %d)\n", mt_ptr[i].slot, mt_ptr[i].x, mt_ptr[i].y);
else
printf("slot<%d>, press(%d, %d)\n", mt_ptr[i].slot, mt_ptr[i].x, mt_ptr[i].y);
}
else
printf("slot<%d>, lift\n", mt_ptr[i].slot);

pressure[mt_ptr[i].slot] = mt_ptr[i].pressure;
}
}
}

/* 关闭设备、释放内存、退出 */
ts_close(ts);
free(mt_ptr);
exit(EXIT_SUCCESS);
}

这个没什么好说的,跟之前的大差不差,这里也要注意链接库。

2. 开发板测试

测试结果如下:

image-20240922222352275