搜索
bottom↓
回复: 0

《I.MX6U嵌入式Linux C应用编程指南》第十八章 输入设备应用编程

[复制链接]

出0入234汤圆

发表于 2021-8-21 16:12:05 | 显示全部楼层 |阅读模式
本帖最后由 正点原子 于 2021-8-21 16:12 编辑

1)实验平台:正点原子i.MX6ULL Linux阿尔法开发板
2)  章节摘自【正点原子】I.MX6U嵌入式Linux C应用编程指南
3)购买链接:https://item.taobao.com/item.htm?&id=603672744434
4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/arm-linux/zdyz-i.mx6ull.html
5)正点原子官方B站:https://space.bilibili.com/394620890
6)正点原子Linux技术交流群:1027879335
1.png

2.jpg


3.png

第十八章 输入设备应用编程

       本章学习输入设备的应用编程,首先要知道什么是输入设备?输入设备其实就是能够产生输入事件的设备就称为输入设备,常见的输入设备包括鼠标、键盘、触摸屏、按钮等等,它们都能够产生输入事件,产生输入数据给计算机系统。
       对于输入设备的应用编程其主要是获取输入设备上报的数据、输入设备当前状态等,譬如获取触摸屏当前触摸点的X、Y轴位置信息以及触摸屏当前处于按下还是松开状态。
       本章将会讨论如下主题内容。
       什么是输入设备;
       如何读取输入设备的数据;
       如何解析从输入设备中获取到的数据;
       按键、触摸屏设备如何解析数据。

1.1输入类设备编程介绍
1.1.1什么是输入设备
      先来了解什么是输入设备(也称为input设备),常见的输入设备有鼠标、键盘、触摸屏、遥控器、电脑画图板等,用户通过输入设备与系统进行交互。
1.1.2input子系统
       由上面的介绍可知,输入设备种类非常多,每种设备上报的数据又不一样,那么Linux系统如何管理呢?Linux系统为了统一管理这些输入设备,实现了一套能够兼容所有输入设备的框架,那么这个框架就是input子系统。驱动开发人员基于input子系统开发输入设备的驱动程序,input子系统可以屏蔽硬件的差异,向应用层提供一套统一的接口。
       基于input子系统注册成功的输入设备,都会在/dev/input目录下生成对应的设备节点(设备文件),通过读取这些设备节点可以获取输入设备上报的数据。
1.1.3读取数据的流程
如果我们要读取触摸屏的数据,假设触摸屏设备对应的设备节点为/dev/input/event0,那么数据读取流程如下:
①、应用程序打开/dev/input/event0设备文件;
②、应用程序发起读操作(譬如调用read),如果没有数据可读则会进入休眠(阻塞I/O情况下);
③、当有数据可读时,应用程序会被唤醒,读操作获取到数据返回;
④、应用程序对读取到的数据进行解析。
       当无数据可读时,程序会进入休眠状态(也就是阻塞),譬如应用程序读触摸屏,当前我们并没有去触摸触摸屏,所以自然无数据可读;当我们用手指触摸触摸屏时,此时就有数据可读了,应用程序会被唤醒,成功读取到数据。那么对于其它输入设备亦是如此,无数据可读时应用程序会进入休眠状态,当然我们这里说的是在阻塞式I/O方式下,当有数据可读时才会被唤醒。
1.1.4应用程序如何解析数据
        首先我们要知道,应用程序打开输入设备的设备文件,向其发起读操作,那么这个读操作获取到的是什么样的数据呢?其实每一次read操作获取的都是一个struct input_event结构体类型数据,该结构体定义在<linux/input.h>头文件中,它的定义如下:
示例代码 18.1.1 struct input_event结构体
  1. struct input_event {
  2.     struct timeval time;
  3.     __u16 type;
  4.     __u16 code;
  5.     __s32 value;
  6. };
复制代码

       结构体中的time成员变量是一个struct timeval类型的变量,该结构体在前面给大家介绍过,每个输入事件struct input_event中都包含了其发生的时间,就通过这个struct timeval类型的变量time来描述。时间参数通常不是很重要,而其它3个成员变量type、code、value更为重要。
       type:type用于描述发生了哪类事件,Linux系统所支持的输入事件类型如下所示:
  1. /*
  2. * Event types
  3. */

  4. #define EV_SYN                        0x00                //同步事件,用于分隔事件
  5. #define EV_KEY                        0x01                //按键事件
  6. #define EV_REL                        0x02                //相对位移事件(譬如鼠标)
  7. #define EV_ABS                        0x03                //绝对位移事件(譬如触摸屏)
  8. #define EV_MSC                        0x04                //其它杂类
  9. #define EV_SW                        0x05
  10. #define EV_LED                        0x11
  11. #define EV_SND                        0x12
  12. #define EV_REP                        0x14
  13. #define EV_FF                        0x15
  14. #define EV_PWR                        0x16
  15. #define EV_FF_STATUS                0x17
  16. #define EV_MAX                        0x1f
  17. #define EV_CNT                        (EV_MAX+1)
复制代码

       以上这些宏定义也是在<linux/input.h>头文件中,所以在应用程序当中需要包含该头文件;一种输入设备通常可以产生多种不同类型的事件,譬如鼠标点击按键(左键、右键,或鼠标上的其它按键)时会上报按键事件,移动鼠标时则会上报相对位移事件。
      code:code表示该类事件下的哪一个具体的事件,每一种事件类型都有对应的一系列事件。不同的事件类型所包含的事件是不同的,譬如对于按键事件来说,一个键盘上有很多的按键,譬如字母A、B、C、D或者数字1、2、3、4等,这每一个不同的按键都会对应一个具体的事件,如下所示:
  1. #define KEY_RESERVED                0
  2. #define KEY_ESC                        1                        //ESC键
  3. #define KEY_1                        2                        //数字1键
  4. #define KEY_2                        3                        //数字2键
  5. #define KEY_TAB                        15                        //TAB键
  6. #define KEY_Q                        16                        //字母Q键
  7. #define KEY_W                        17                        //字母W键
  8. #define KEY_E                        18                        //字母E键
  9. #define KEY_R                        19                        //字母R键
  10. ……
复制代码

相对位移事件的code值
  1. #define REL_X                        0x00        //X轴
  2. #define REL_Y                        0x01        //Y轴
  3. #define REL_Z                        0x02        //Z轴
  4. #define REL_RX                        0x03
  5. #define REL_RY                        0x04
  6. #define REL_RZ                        0x05
  7. #define REL_HWHEEL                0x06
  8. #define REL_DIAL                0x07
  9. #define REL_WHEEL                0x08
  10. #define REL_MISC                0x09
  11. #define REL_MAX                        0x0f
  12. #define REL_CNT                        (REL_MAX+1)
复制代码

绝对位移事件的code值
譬如对于触摸屏设备来说,一个触摸点有X轴坐标和Y轴坐标,甚至一个触摸点还有压力值等这些信息,这每一种信息都会对应一个具体的事件,也就是code值。
  1. #define ABS_X                        0x00                //X轴
  2. #define ABS_Y                        0x01                //Y轴
  3. #define ABS_Z                        0x02                //Z轴
  4. #define ABS_RX                        0x03
  5. #define ABS_RY                        0x04
  6. #define ABS_RZ                        0x05
  7. #define ABS_THROTTLE                0x06
  8. #define ABS_RUDDER                0x07
  9. #define ABS_WHEEL                0x08
  10. #define ABS_GAS                        0x09
  11. #define ABS_BRAKE                0x0a
  12. #define ABS_HAT0X                0x10
  13. #define ABS_HAT0Y                0x11
  14. #define ABS_HAT1X                0x12
  15. #define ABS_HAT1Y                0x13
  16. #define ABS_HAT2X                0x14
  17. #define ABS_HAT2Y                0x15
  18. #define ABS_HAT3X                0x16
  19. #define ABS_HAT3Y                0x17
  20. #define ABS_PRESSURE                0x18
  21. #define ABS_DISTANCE                0x19
  22. #define ABS_TILT_X                0x1a
  23. #define ABS_TILT_Y                0x1b
  24. #define ABS_TOOL_WIDTH                0x1c
  25. ......
复制代码

       除了以上列举出来的之外,还有很多,大家可以自己浏览<linux/input.h>头文件(这些宏其实是定义在input-event-codes.h头文件中,该头文件被<linux/input.h>所包含了),关于这些具体的事件,后面再给大家进行介绍。
       value:value表示事件值,对value值的解释随着code类型的变化而变化。譬如对于按键事件来说,如果code表示按键1,那么value等于1表示按键1按下,value等于0表示按键1被松开,如果value等于2则表示按键被长按。譬如在绝对位移事件中,如果code表示X轴坐标ABS_X,那么value值就表示触摸点在X轴坐标的位置。所以对value值的解释需要根据不同的code类型而定!
事件之间的分隔、同步
      上面我们提到了同步事件EV_SYN,同步事件用于对不同事件进行分隔、实现同步操作。应用程序读取输入设备的数据时,一次read操作只能读取一个struct input_event类型数据,譬如对于触摸屏来说,一个触摸点会上报X轴坐标位置、Y轴坐标位置,还有可能会上报压力值,对于这样情况,那么应用程序需要执行3次read操作才能把一个触摸点上报的数据全部读取到;这还只是单个触摸点的情况,如果触摸屏设备支持多点触摸,同一时间触摸屏上有多个触摸点,那么程序当中需要把所有触摸点的数据读取出来,这样才算完整。
       那么应用程序如何知道已经读取到完整数据了呢?其实就是通过同步事件来实现的,驱动程序中将完整数据上报完之后(譬如触摸点的X轴、Y轴以及压力等之类的数据),会上报一个同步事件,以告知应用程序数据已经完整、进行同步。
       同步事件类型也包含了多种不同的事件,也就是code值,如下所示:
  1. /*
  2. * Synchronization events.
  3. */

  4. #define SYN_REPORT                0
  5. #define SYN_CONFIG                1
  6. #define SYN_MT_REPORT                2
  7. #define SYN_DROPPED                3
  8. #define SYN_MAX                        0xf
  9. #define SYN_CNT                        (SYN_MAX+1)
复制代码

       上报的同步事件通常是第一个SYN_REPORT(code值),而value值通常为0。对于同步事件,应用程序通常不需要去管是哪个具体的同事事件,只需知道type等于EV_SYN则表示数据完整了。
1.2编写程序读取输入设备的数据
      本例程源码对应的路径为:开发板光盘->11、Linux C应用编程例程源码->18_input->read_input.c。
      根据前面的介绍,我们编写一个简单地示例代码进行测试,示例代码如下所示:
      示例代码 18.2.1 读取输入设备的数据
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7. #include <linux/input.h>

  8. int main(int argc, char *argv[])
  9. {
  10.     struct input_event in_ev = {0};
  11.     int fd = -1;

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

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

  22.     for ( ; ; ) {

  23.         /* 循环读取数据 */
  24.         if (sizeof(struct input_event) !=
  25.             read(fd, &in_ev, sizeof(struct input_event))) {
  26.             perror("read error");
  27.             exit(-1);
  28.         }

  29.         printf("type:%d code:%d value:%d\n",
  30.                 in_ev.type, in_ev.code, in_ev.value);
  31.     }
  32. }
复制代码

       执行程序时需要传入参数,这个参数就是对应的输入设备的设备节点(设备文件),程序中会对传参进行校验。程序中首先调用open()函数打开设备文件,之后在for循环中调用read()函数读取文件,将读取到的数据存放在struct input_event结构体对象中,之后将结构体对象中的各个成员变量打印出来。注意,程序中使用了阻塞式I/O方式读取设备文件,所以当无数据可读时read调用会被阻塞,知道有数据可读时才会被唤醒!
使用交叉编译工具编译上述代码得到可执行文件testApp:
第十八章 输入设备应用编程5676.png

图 18.2.1 编译示例代码

1.3在开发板上测试
将上小节编译得到的可执行文件testApp拷贝到开发板根文件系统中,譬如拷贝到开发板Linux系统的家目录下:
第十八章 输入设备应用编程5801.png

图 18.3.1 将testApp文件拷贝到开发板家目录

在阿尔法Linux开发板上有一个用户按键KEY0,它就是一个典型的输入设备,如下图所示:
第十八章 输入设备应用编程5920.png

图 18.3.2 用户按键KEY0

       该按键是提供给用户使用的一个GPIO按键,底层驱动基于Linux input输入子系统而实现,所以在/dev/input目录下存在该按键设备的设备节点,具体是哪个设备节点,可以使用13.1.1小节介绍的方法进行判断,这里不再重述!也可以通过查看/proc/bus/input/devices文件得知,查看该文件可以获取到系统中注册的所有输入设备相关的信息,如下所示:
第十八章 输入设备应用编程6194.png

图 18.3.3 查看/proc/bus/input/devices文件

       需要注意的是,当按键KEY0被按下时,底层驱动会上报按键事件(EV_KEY),并且对应的事件为KEY_VOLUMEDOWN(也就是键盘上的VOLUMEDOWN按键,普通键盘上貌似没有这个按键,笔记本自带的键盘有这个按键),该事件到code值等于114,大家可以对比<linux/input.h>头文件进行查找。这个是阿尔法开发板出厂系统已经配置好的。
       接下来我们使用这个按键进行测试,执行下面的命令(笔者测试使用的开发板按键KEY0对应的设备节点为/dev/input/event2),然后对KEY0按键执行按下、松开等操作:
第十八章 输入设备应用编程6540.png

图 18.3.4 测试

第一行中type等于1,表示上报的是按键事件EV_KEY,code等于114,也就是上面说的KEY_VOLUMEDOWN按键,value等于1,表示按下,所以整个第一行的意思就是按键KEY_VOLUMEDOWN被按下。
第二行,type等于0,表示上报的是同步事件EV_SYN,表示前面上报的数据已经是完整的了,因为对于按键来说,只有按下和松开两种状态,所以只要获取到了EV_KEY事件的value值就表示数据已经完整了。
第三行,type等于1,表示按键事件,code等于114、value等于0,所以表示按键KEY_VOLUMEDOWN被松开。
第四行,又上报了同步事件。
所以整个上面4行的打印信息就是开发板上的KEY0按键被按下以及松开这个过程,底层驱动所上报的数据。
我们试试长按按键KEY0,按住不放,如下所示:
第十八章 输入设备应用编程6960.png

图 18.3.5 长按按键KEY0

可以看到上报按键事件时,对应的value等于2,表示长按状态。
接下来我们对示例代码 17.2.1进行修改,不直接打印struct input_event数据结构中各个成员变量,而是通过对这些数据进行解析,判断按键当前是按下、松开或长按状态,并将结果打印出来,修改之后的代码如下所示:
本例程源码对应的路径为:开发板光盘->11、Linux C应用编程例程源码->18_input->read_key.c。
示例代码 18.3.1 判断按键KEY0当前的状态
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7. #include <linux/input.h>

  8. int main(int argc, char *argv[])
  9. {
  10.     struct input_event in_ev = {0};
  11.     int fd = -1;
  12.     int value = -1;

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

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

  23.     for ( ; ; ) {

  24.         /* 循环读取数据 */
  25.         if (sizeof(struct input_event) !=
  26.             read(fd, &in_ev, sizeof(struct input_event))) {
  27.             perror("read error");
  28.             exit(-1);
  29.         }

  30.         switch (in_ev.type) {
  31.         case EV_KEY:    //按键事件
  32.             if (KEY_VOLUMEDOWN == in_ev.code)
  33.                 value = in_ev.value;
  34.             break;

  35.         case EV_SYN:    //同步事件
  36.             switch (value) {
  37.             case 0:
  38.                 printf("按键松开\n");
  39.                 break;
  40.             case 1:
  41.                 printf("按键按下\n");
  42.                 break;
  43.             case 2:
  44.                 printf("按键长按\n");
  45.                 break;
  46.             }

  47.             value = -1;
  48.             break;
  49.         }
  50.     }
  51. }
复制代码

       上述程序中没有直接打印读取到的数据,而是对数据进行了解析,从而判断按键KEY0当前的状态。当上报按键事件时,将value值保存起来,当上报同步事件时,表示上报的数据已经是完整数据了,接着便判断value值等于0、1、还是2,以此来判断按键KEY0当前的状态是松开、按下还是长按。
将上述代码进行编译,拷贝到开发板家目录下进行测试:
第十八章 输入设备应用编程8741.png

图 18.3.6 测试结果

1.4读取触摸屏数据
        本小节介绍如何解析触摸屏设备上报的数据,触摸屏设备是一个绝对位移设备,可以上报绝对位移事件,可以上报的绝对位移事件如下:
  1. #define ABS_X                        0x00        //X轴坐标
  2. #define ABS_Y                        0x01        //Y轴坐标
  3. #define ABS_Z                        0x02        //Z轴坐标
  4. #define ABS_RX                        0x03
  5. #define ABS_RY                        0x04
  6. #define ABS_RZ                        0x05
  7. #define ABS_THROTTLE                0x06
  8. #define ABS_RUDDER                0x07
  9. #define ABS_WHEEL                0x08
  10. #define ABS_GAS                        0x09
  11. #define ABS_BRAKE                0x0a
  12. #define ABS_HAT0X                0x10
  13. #define ABS_HAT0Y                0x11
  14. #define ABS_HAT1X                0x12
  15. #define ABS_HAT1Y                0x13
  16. #define ABS_HAT2X                0x14
  17. #define ABS_HAT2Y                0x15
  18. #define ABS_HAT3X                0x16
  19. #define ABS_HAT3Y                0x17
  20. #define ABS_PRESSURE                0x18        //按压力
  21. #define ABS_DISTANCE                0x19
  22. #define ABS_TILT_X                0x1a
  23. #define ABS_TILT_Y                0x1b
  24. #define ABS_TOOL_WIDTH                0x1c

  25. #define ABS_VOLUME                0x20

  26. #define ABS_MISC                0x28

  27. #define ABS_MT_SLOT                0x2f        /* MT slot being modified */
  28. #define ABS_MT_TOUCH_MAJOR        0x30        /* Major axis of touching ellipse */
  29. #define ABS_MT_TOUCH_MINOR        0x31        /* Minor axis (omit if circular) */
  30. #define ABS_MT_WIDTH_MAJOR        0x32        /* Major axis of approaching ellipse */
  31. #define ABS_MT_WIDTH_MINOR        0x33        /* Minor axis (omit if circular) */
  32. #define ABS_MT_ORIENTATION        0x34        /* Ellipse orientation */
  33. #define ABS_MT_POSITION_X        0x35        /* Center X touch position */        //X轴坐标
  34. #define ABS_MT_POSITION_Y        0x36        /* Center Y touch position */        //Y轴坐标
  35. #define ABS_MT_TOOL_TYPE        0x37        /* Type of touching device */
  36. #define ABS_MT_BLOB_ID                0x38        /* Group a set of packets as a blob */
  37. #define ABS_MT_TRACKING_ID        0x39        /* Unique ID of initiated contact */
  38. #define ABS_MT_PRESSURE                0x3a        /* Pressure on contact area */        //按压力
  39. #define ABS_MT_DISTANCE                0x3b        /* Contact hover distance */
  40. #define ABS_MT_TOOL_X                0x3c        /* Center X tool position */
  41. #define ABS_MT_TOOL_Y                0x3d        /* Center Y tool position */


  42. #define ABS_MAX                        0x3f
  43. #define ABS_CNT                        (ABS_MAX+1)
复制代码

       一般常用的是ABS_X、ABS_Y、ABS_PRESSURE、ABS_MT_POSITION_X、ABS_MT_POSITION_Y、ABS_MT_PRESSURE,后面三个带有MT的事件通常在支持多点触摸的设备中被使用到,阿尔法开发板配套使用的触摸屏支持5点触摸,10.1寸屏甚至支持多达10点触摸,如果在应用程序中需要获取多个触摸点的坐标信息,则需要捕获设备上报的ABS_MT_POSITION_X、ABS_MT_POSITION_Y事件,获取事件对应的value值。
       触摸屏除了可以上报绝对位移事件之外,还可以上报按键事件,当我们的手指点击触摸屏或手指从触摸屏上松开时,底层驱动都会上报按键事件,对应的按键事件为BTN_TOUCH(code等于0x14a),按下时上报的BTN_TOUCH事件对应的value等于1,松开时value等于0;在触摸屏上滑动不会上报BTN_TOUCH事件。
       以下示例代码演示了如何读取单个触摸点,包括触摸点的X轴坐标位置和Y轴坐标位置。读取单个触摸点的X轴坐标位置和Y轴坐标位置,只需捕获设备上报的ABS_X、ABS_Y事件,获取对应的value数据即可!
       本例程源码对应的路径为:开发板光盘->11、Linux C应用编程例程源码->18_input->read_ts.c。
       示例代码 18.4.1 读取触摸屏数据
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7. #include <linux/input.h>

  8. int main(int argc, char *argv[])
  9. {
  10.     struct input_event in_ev = {0};
  11.     int x_val, y_val, key_val;
  12.     int fd = -1;

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

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

  23.     x_val = y_val = key_val = -1;
  24.     for ( ; ; ) {

  25.         /* 循环读取数据 */
  26.         if (sizeof(struct input_event) !=
  27.             read(fd, &in_ev, sizeof(struct input_event))) {
  28.             perror("read error");
  29.             exit(-1);
  30.         }

  31.         switch (in_ev.type) {
  32.         case EV_KEY:    //按键事件
  33.             if (BTN_TOUCH == in_ev.code)
  34.                 key_val = in_ev.value;  //保存BTN_TOUCH的value
  35.             break;

  36.         case EV_ABS:    //绝对位移事件
  37.             if (ABS_X == in_ev.code)    //X轴
  38.                 x_val = in_ev.value;    //保存X轴坐标位置
  39.             else if (ABS_Y == in_ev.code)//Y轴
  40.                 y_val = in_ev.value;    //保存Y轴坐标位置
  41.             break;

  42.         case EV_SYN:    //同步事件
  43.             if (1 == key_val)   //按下
  44.                 printf("按下, X=%d Y=%d\n", x_val, y_val);
  45.             else if (0 == key_val)
  46.                 printf("松开\n");
  47.             else
  48.                 printf("X=%d Y=%d\n", x_val, y_val);

  49.             key_val = -1;
  50.             break;
  51.         }
  52.     }
  53. }
复制代码

       程序中首先校验传参,通过传参的方式将设备文件路径传入到程序中,接着调用open()打开文件,在for循环读取设备文件,将读取到的数据存放在struct input_event数据结构中。在switch…case语句中对读取到的数据进行解析,判断上报的BTN_TOUCH事件,判断触摸屏是按下还是松开状态,捕获ABS_X和ABS_Y事件获取对应的value变量,则可以获取到触摸点的X轴坐标位置和Y轴坐标位置。
硬件连接
       阿尔法I.MX6U开发板出厂系统配套支持多种不同分辨率的LCD屏,包括4.3寸480*272、4.3寸800*480、7寸800*480、7寸1024*600以及10.1寸1280*800,在启动开发板之前需要将LCD屏通过软排线连接到开发板的LCD接口,开发板连接好LCD屏之后上电启动开发板运行开发板出厂烧录的系统。
第十八章 输入设备应用编程13040.png

图 18.4.1 硬件连接

       触摸屏与LCD液晶屏面板是粘合在一起的,也就是说触摸屏是直接贴在了LCD液晶屏上面,我们可以直接通过手指或其它可用于触摸的物体对安装在LCD液晶屏上面的触摸屏进行触摸、滑动等操作。
为了测试方便,可以将出厂系统的GUI应用程序退出,如何退出呢?点击屏幕进入设置页面,可以看到在该页面下有一个退出按钮选项,直接点击即可!
       编译测试
       使用交叉编译工具编译示例代码 17.4.1将其拷贝到开发板家目录下,执行程序(笔者测试使用的开发板触摸屏对应的设备节点为/dev/input/event1),程序执行之后,接着可以对触摸屏进行触摸、松开、滑动等操作,串口终端将会打印出相应的信息:
第十八章 输入设备应用编程13428.png

图 18.4.2 测试结果

       当手指点击触摸屏时会打印"按下, X=xxx Y=yyy",松开时会打印"松开",手指在触摸屏上滑动时只会打印坐标信息。大家可以自己动手测试,对代码不理解的,可以对照测试结果进行对比。


回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-20 15:48

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表