Skip to content

LV050-tslib应用实例

一、单点触摸

1. 代码编写

c
#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)编译时,链接库可以这样写:

shell
${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. 代码编写

c
#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