找回密码
 立即注册
首页 业界区 安全 ARM开发板——实时获取用户点击触摸屏的LCD坐标信息(阻 ...

ARM开发板——实时获取用户点击触摸屏的LCD坐标信息(阻塞式读取)

闰咄阅 2025-6-11 15:10:52
ARM开发板——实时获取用户点击触摸屏的LCD坐标信息(阻塞式读取)


目录

  • ARM开发板——实时获取用户点击触摸屏的LCD坐标信息(阻塞式读取)

    • 1、硬件信息
    • 2、代码需求
    • 3、代码实现


1、硬件信息

ARM开发板使用的内核为CotexA53芯片,LCD屏为七寸800 * 480像素,触摸屏为1024 * 600
2、代码需求

实时监听用户点击触摸屏的事件,并获取点击位置(LCD坐标)
3、代码实现

基本步骤:

  • 打开触摸屏设备文件,触摸屏设备文件位于/dev/input/event0;
  • 创建输入事件结构体,该结构体定义于/usr/include/linux/input.h;
    1. /*
    2. * /usr/include/linux/input.h 摘录
    3. */
    4. /*
    5. * The event structure itself
    6. */
    7. struct input_event {
    8.         struct timeval time;
    9.         __u16 type;
    10.         __u16 code;
    11.         __s32 value;
    12. };
    13. // ...省略
    14. /*
    15. * Event types
    16. */
    17. #define EV_SYN                        0x00
    18. #define EV_KEY                        0x01
    19. #define EV_REL                        0x02
    20. #define EV_ABS                        0x03     // 绝对位置
    21. #define EV_MSC                        0x04
    22. #define EV_SW                        0x05
    23. #define EV_LED                        0x11
    24. #define EV_SND                        0x12
    25. #define EV_REP                        0x14
    26. #define EV_FF                        0x15
    27. #define EV_PWR                        0x16
    28. #define EV_FF_STATUS                0x17
    29. #define EV_MAX                        0x1f
    30. #define EV_CNT                        (EV_MAX+1)
    31. // ...省略
    32. /*
    33. * Absolute axes
    34. */
    35. #define ABS_X                        0x00                        // x轴
    36. #define ABS_Y                        0x01                        // y轴
    37. #define ABS_Z                        0x02
    38. #define ABS_RX                        0x03
    39. #define ABS_RY                        0x04
    40. #define ABS_RZ                        0x05
    41. #define ABS_THROTTLE                0x06
    42. #define ABS_RUDDER                0x07
    43. #define ABS_WHEEL                0x08
    44. #define ABS_GAS                        0x09
    45. #define ABS_BRAKE                0x0a
    46. #define ABS_HAT0X                0x10
    47. #define ABS_HAT0Y                0x11
    48. #define ABS_HAT1X                0x12
    49. #define ABS_HAT1Y                0x13
    50. #define ABS_HAT2X                0x14
    51. #define ABS_HAT2Y                0x15
    52. #define ABS_HAT3X                0x16
    53. #define ABS_HAT3Y                0x17
    54. #define ABS_PRESSURE                0x18
    55. #define ABS_DISTANCE                0x19
    56. #define ABS_TILT_X                0x1a
    57. #define ABS_TILT_Y                0x1b
    58. #define ABS_TOOL_WIDTH                0x1c
    复制代码
  • 循环读取事件(阻塞式读取);
    在ARM开发板的触摸屏事件监听中,看似“死循环”的代码设计其实并非低效的忙等待(busy-waiting),而是基于阻塞式读取(blocking read)的事件驱动机制:

    • 当调用 read(fd, &event, sizeof(event)) 时,若设备文件(如 /dev/input/event0)无事件发生,内核会将进程挂起(进入阻塞状态),此时不占用CPU资源,直到有触摸事件触发中断,内核唤醒进程并返回数据。
    • 示例代码中的 while(1) 循环本质上是等待事件的“休眠-唤醒”过程,而非持续消耗CPU的忙等待。
    行为资源占用实现场景阻塞式读取(read)无事件时CPU占用率接近0%适用于实时事件监听忙等待(轮询)持续占用CPU(如 while(1) { poll(); })需避免,仅用于极低延迟场景嵌入式系统中类似机制广泛存在(如传感器数据采集),均依赖阻塞IO而非主动轮询,在典型ARM Linux系统中,阻塞式读取触摸屏事件的进程在无操作时CPU占用率为0%,触摸事件响应延迟在10ms以内

  • 根据event结构体的type 判断是否为绝对位置,code判断是y轴还是x轴数据;
  • 将触摸屏坐标转换为LCD坐标后输出坐标信息;
具体实现如下:
  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <stdio.h>
  5. #include <linux/input.h>
  6. #include <unistd.h>
  7. #include <stdlib.h>
  8. int main(int argc, char const *argv[])
  9. {
  10.     // 1、打开触摸屏设备文件
  11.     int touch = open("/dev/input/event0", O_RDWR);
  12.     if (touch == -1)
  13.     {
  14.         printf("文件打开出错!");
  15.         exit(-1);
  16.     }
  17.    
  18.     // 2、创建输入事件结构体
  19.     struct input_event event;
  20.     // 3、循环读取事件(阻塞式读取)
  21.     int count = 0;
  22.     int x = 0;
  23.     int y = 0;
  24.     while (1)
  25.     {
  26.         ssize_t size = read(touch, &event , sizeof(struct input_event));
  27.         if(event.type == EV_ABS){
  28.             if(event.code == ABS_X)
  29.             {
  30.                 count ++;
  31.                 x = event.value * 800 / 1024;  // lcd_width: 800,触摸屏x:1024
  32.             }
  33.             if(event.code == ABS_Y)
  34.             {
  35.                 count ++;
  36.                 y = event.value * 480 / 600; // lcd_height: 480, 触摸屏y:600
  37.             }
  38.             if(count ==2) {
  39.                 printf("x = %d\t", x);
  40.                 printf("y = %d\n", y);
  41.                 count = 0;
  42.             }
  43.         }
  44.     }
  45.    
  46.     // 4、关闭文件
  47.     close(touch);
  48.     return 0;
  49. }
复制代码
编译后传输至开发板测试:
[root@GEC6818 /workspace/touchtest]#./touchtest
x = 316 y = 229
x = 402 y = 332
x = 388 y = 336
x = 133 y = 377
x = 29  y = 412
x = 1   y = 468
x = 1   y = 236
x = 5   y = 222
x = 58  y = 231
x = 114 y = 250
x = 444 y = 272
x = 576 y = 271
x = 723 y = 262
x = 798 y = 244
x = 798 y = 254
测试无误,需求实现!

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册