当前位置:   article > 正文

粤嵌6818开发板触摸屏应用_gec6818开发板触摸屏

gec6818开发板触摸屏

一、触摸屏应用

1.触摸屏设备的名字

在Linux下,一切皆文件,触摸屏也是一个文件。

触摸屏设备的名字:/dev/input/event0

2.触摸屏的两个专业术语

  • 事件 ->event0

当一些外接控制设备(鼠标、键盘,wifi,触摸屏,按键)接入到嵌入式平台(GEC6818)时,这些外接设备的状态发生了改变(鼠标的左键被按下了,键盘的R键被按下,有人连接上wifi了,触摸屏被滑动了一下,按键被按下了)时,这个动作就称之为事件.

  • 输入子系统 ->input

当事件发生的时候,就是由输入子系统来计算这些事件中产生的值。并将这些值整合到一个名为input_event结构体中。(例如:触摸屏被触摸后,输入子系统就会计算出被触摸的坐标值)

3.代码实现流程

1.打开event0文件

2.读取event0文件的数据

3.判断事件类型,打印出数据

4.关闭文件

4.触摸屏数据对应的类型

如果想知道从event0这个文件中读取出来的这个文件的数据是什么类型的,那么就必须先知道输入子系统计算完这个结果之后,是以什么形式放到这个event0这个文件中。

以前我们学习结构体的时候知道描述一个需要很多值的事件,我们可以使用结构体来描述,所以输入子系统处理好触摸屏数据后,也是将这些数据存放到一个结构体中。

该结构体已经定义好了,是被封装在一个头文件,头文件的路径在: /usr/include/linux/input.h

  1. /* * The event structure itself   //事件结构体 */
  2. struct input_event {       -> 专门用于描述一个事件。
  3.   struct timeval time;   -> 事件发生的时间。
  4.   __u16 type;           -> 事件的类型 (输入子系统会用这个值来描述刚才发生事件的硬件设备)
  5.   __u16 code;           -> 事件的编码 -> 对事件进一步的描述 左键/右键 A键/R键 x轴/y轴
  6.   __s32 value;           -> 事件的值
  7. };
  8. struct timeval {        
  9.   long   tv_sec;         /**/        
  10.   long   tv_usec;       /* 微秒 */
  11. };

知道触摸屏数据是存放在一个结构体中后,那么我们可以写一段代码来打印出这些数据看看:

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <unistd.h>
  6. #include <string.h>
  7. #include <linux/input.h>
  8. int main()
  9. {
  10. •   // 1.打开event0文件
  11. •   int ts_fd;
  12. •   ts_fd = open("/dev/input/event0", O_RDONLY);
  13. •   if(ts_fd == -1)
  14. •   {
  15. •       printf("open ts failed!\n");
  16. •       return 0;
  17. •   }
  18. •   // 2.读取event0文件的数据
  19. •   struct input_event ts_buf;
  20. •   read(ts_fd, &ts_buf, sizeof(ts_buf));
  21. •    
  22. •   // 3.判断事件类型,打印出数据
  23. •   printf("type = %d", ts_buf.type);
  24. •   printf("code = %d", ts_buf.code);
  25. •   printf("value = %d", ts_buf.value);
  26. •   // 4.关闭文件
  27. •   close(ts_fd);
  28. •   return 0;
  29. }

其实这个结构体结果的值也被封装在一个头文件中:/usr/include/linux/input-event-codes.h

input_event结构体的四个成员:

1.time(时间戳)

输入事件发生的时间戳,精确到微秒。时间结构体定义如下:

  1. struct timeval
  2. {
  3. __time_t tv_sec; //
  4. long int tv_usec; // 微秒(1微秒 = 10-3毫秒 = 10-6秒)
  5. };

2.type(输入事件类型)

输入事件的类型。比如:

3.code(事件代码)

这个 事件代码用于对事件的类型作进一步的描述。比如:当发生EV_KEY事件时,则可能是键盘被按下了,那么究竟是哪个按键被按下了呢?此时查看code就知道了。当发生EV_REL事件时,也许是鼠标动了,也许是滚轮动了。这时可以用code的值来加以区分。

4.value(数据值)

当code都不足以区分事件的性质的时候,可以用value来确认。比如由EV_REL和REL_WHEEL确认发生了鼠标滚轮的动作,但是究竟是向上滚还是向下滚呢?再比如由由EV_KEY和KEY_F确认了发生键盘上F键的动作,但究竟是按下呢还是弹起呢?这时都可以用value值来进一步判断。

举一个实例帮助理解输入子系统:

  1. 我们先规定
  2. type:
  3. = 0 吃饭
  4. = 1 睡觉
  5. code:
  6. = 0 早餐
  7. = 1 午餐
  8. = 2 晚餐
  9. = 0 午觉
  10. = 1 晚觉
  11. value:
  12. = 0 吃饱了
  13. = 1 没吃饱
  14. = 0 睡得着
  15. = 1 睡不着
  16. struct input_event{   -> 代表输入子系统分析出来
  17.   .type = 0
  18.   .code = 1
  19.   .value = 1
  20.   }
  21. 我们再获取输入子系统整合的input_event结构体的值
  22. struct input_event{   -> 代表输入子系统分析出来: 你刚刚吃晚餐没吃饱
  23.   .type = 0
  24.   .code = 2
  25.   .value = 1
  26.   }
  27. struct input_event{   -> 代表输入子系统分析出来: 你刚刚睡午觉没睡着
  28.   .type = 1
  29.   .code = 0
  30.   .value = 3
  31.   }
 

练习:编写代码,实现打印出触摸点的坐标。

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <unistd.h>
  6. #include <linux/input.h>
  7. int main()
  8. {
  9.   int ts_fd;
  10.   struct input_event ts_buf;
  11.   ts_fd = open("/dev/input/event0",O_RDONLY);
  12.   if(ts_fd == -1)
  13.   {
  14.       printf("open ts failed!\n");
  15.       return -1;
  16.   }
  17.   int x,y;
  18.   while(1)
  19.   {
  20.       read(ts_fd, &ts_buf, sizeof(ts_buf));
  21.       if(ts_buf.type == EV_ABS && ts_buf.code == ABS_X)//判断是否发生X轴绝对位移事件
  22.       {
  23.           x = ts_buf.value;
  24.       }
  25.       if(ts_buf.type == EV_ABS && ts_buf.code == ABS_Y)//判断是否发生Y轴绝对位移事件
  26.       {
  27.           y = ts_buf.value;
  28.       }
  29.       if(ts_buf.type == EV_KEY && ts_buf.code == BTN_TOUCH && ts_buf.value == 0)//松手检测
  30.       {
  31.           printf("(x, y) = (%d, %d)\n",x,y);
  32.       }  
  33.   }
  34.   close(ts_fd);
  35.   return 0;
  36. }

作业1:观察打印出的坐标,得出触摸屏和LCD像素对应的关系

黑色边的开发板触摸屏坐标范围是:1024*600

蓝色边的开发板触摸屏坐标范围是:800*480

练习8:通过触摸屏实现显示图片切换。

  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #include <stdio.h>
  6. #include <linux/input.h>
  7. #include <sys/mman.h>
  8. int ts_fd, lcd_fd;
  9. int ts_x,ts_y;
  10. struct input_event ts_buf;
  11. int *p;
  12. char *pic_path[] = {"./1.bmp" , "./2.bmp", "./3.bmp", "./4.bmp", "./5.bmp"};
  13. /*
  14. *函数名:show_bmp
  15. *函数功能:显示bmp图片
  16. *参数:
  17. * path: 图片的路径
  18. * zs_x: 图片显示的原点x轴坐标
  19. * zs_y: 图片显示的原点y轴坐标
  20. * whide: 图片的宽度(单位像素)
  21. * high: 图片的高度(单位像素)
  22. */
  23. int show_bmp(char *path, int zs_x, int zs_y, int w, int h)
  24. {
  25.   // 1、打开bmp文件
  26.   int bmp_fd = open(path, O_RDONLY);
  27.   if (bmp_fd == -1)
  28.   {
  29.       printf("open bmp error!\n");
  30.       return -1;  
  31.   }
  32.   //2、 跳过bmp文件头和信息头
  33.   lseek(bmp_fd, 54, SEEK_SET);  
  34.   //3、读取bmp文件的数据
  35.   char bmp_buf[w*h*3];
  36.   read(bmp_fd, bmp_buf, 800*480*3); // 读取bmp文件数据到bmp_buf
  37.    
  38.   //4、数据处理
  39.   int lcd_buf[w*h];
  40.   int n;
  41.   for (n = 0; n < 800*480; n++)
  42.   {
  43.      
  44.       lcd_buf[n] = bmp_buf[3*n] | bmp_buf[3*n+1]<<8 | bmp_buf[3*n+2]<<16;
  45.   }
  46.    
  47.   int *new_p = p + zs_x + zs_y*800;
  48.   //6// 5、将数据拷贝到映射空间
  49.   int x, y;
  50.   for(y=0;y<h;y++)
  51.   {
  52.       for(x=0;x<w;x++)
  53.       {
  54.           *(new_p+x+(h-1-y)*800) = lcd_buf[x+y*w];
  55.       }
  56.   }
  57.   close(bmp_fd);
  58. }
  59. void get_xy()
  60. {
  61.   // 2.读取event0文件的数据
  62.   read(ts_fd, &ts_buf, sizeof(ts_buf));
  63.   // 3.判断事件类型,打印出数据
  64.   if(ts_buf.type == EV_ABS && ts_buf.code == ABS_X)//获取X轴坐标
  65.   {
  66.       ts_x = ts_buf.value;//0-1024 ---> 0-800
  67.       ts_x = ts_x * 800 / 1024;
  68.   }  
  69.   if(ts_buf.type == EV_ABS && ts_buf.code == ABS_Y)//获取Y轴坐标
  70.   {
  71.       ts_y = ts_buf.value;//0-600
  72.       ts_y = ts_y * 480 / 600;
  73.   }      
  74.   if(ts_buf.type == EV_KEY && ts_buf.code == BTN_TOUCH && ts_buf.value == 0)//松手检测
  75.   {
  76.       printf("(x,y) = (%d,%d)",ts_x,ts_y);
  77.   }
  78. }
  79. int main()
  80. {
  81.   // 1.打开fb0、event0文件
  82.   lcd_fd = open("/dev/fb0", O_RDWR);
  83.   if(lcd_fd < 0)
  84.   {
  85.       perror("open fb0");
  86.       return -1;
  87.   }
  88.   ts_fd = open("/dev/input/event0", O_RDONLY);
  89.   if (ts_fd == -1)
  90.   {
  91.       perror("open touch failed\n");
  92.       return -1;
  93.   }
  94.   // 内存映射
  95.   p = (int *)mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, lcd_fd, 0);
  96.   if(p == MAP_FAILED)
  97.   {
  98.       perror("mmap failed\n");
  99.       return -1;
  100.   }
  101.  
  102.   int i = 0;
  103.   while (1)
  104.   {
  105.       get_xy();
  106.       if(ts_buf.type == EV_KEY && ts_buf.code == BTN_TOUCH && ts_buf.value == 0)//松手检测
  107.       {
  108.           if(ts_x>=0 && ts_x<200)//上一张
  109.           {
  110.               i--;
  111.               if(i<0)
  112.               {
  113.                   i = 4;
  114.               }
  115.               show_bmp(pic_path[i], 0, 0, 800, 480);
  116.           }
  117.           if(ts_x>=600 && ts_x<800)//下一张
  118.           {
  119.               i++;
  120.               if(i>4)
  121.               {
  122.                   i = 0;
  123.               }
  124.               show_bmp(pic_path[i], 0, 0, 800, 480);
  125.           }
  126.            
  127.       }
  128.   }
  129.    
  130.   // 4.关闭文件
  131.   munmap(p, 800*480*4);
  132.   close(lcd_fd);
  133.   close(ts_fd);
  134.   return 0;
  135. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/791811
推荐阅读
相关标签
  

闽ICP备14008679号