触摸 屏

一、linux系统IO应用实例。 -> 触摸屏。
1、触摸屏设备叫什么名字?
在linux下,一切都是文件,连触摸屏也是一个文件。
触摸屏设备名字:/dev/input/event0

2、熟悉了解触摸屏两个专业术语。
1)事件。  -> event0
当一些外接控制设备(鼠标、键盘,wifi,触摸屏,按键)接入到嵌入式平台(GEC6818)时,这些外接设备的状态发生了改变(鼠标的左键被按下了,键盘的R键被按下,有人连接上wifi了,触摸屏被滑动了一下,按键被按下了)时,这个动作就称之为事件。

2)输入子系统。  -> input
当事件发生的时候,就是由输入子系统来计算这些事件中产生的值。

3、如果我们想把触摸屏的坐标读取出来,思路是如何的呢?
1)访问触摸屏设备文件。
   fd = open("/dev/input/event0");

2)直接读取即可。
   read(fd);

3)分析读取出来的数据是什么类型的?
   int ? char ? char []? *?

4)根据获取到的坐标做进一步的判断就可以。
   if(坐标满足某一个条件)
   {
    
   }

5)关闭文件
   close(fd);

   例题: 尝试将数据读取到一个数组中。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc,char *argv[])
{
    //1. 访问触摸屏设备
    int fd;
    fd = open("/dev/input/event0",O_RDONLY);
    if(fd < 0)
    {
        printf("open ts error!\n");
    }
    
    //2. 读取触摸屏设备的数据
    char buf[100] = {0};
    while(1)
    {
        read(fd,buf,sizeof(buf));
        printf("from file:%s\n",buf);
    }
    
    //3. 关闭文件。
    close(fd);
    
    return 0;
}
结果:
打印乱码。

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

1、如何来描述一个事件? -> 需要很多值  -> 结构体。
该结构体已经定义好了,是被封装在一个头文件,头文件的路径在: /usr/include/linux/input.h

/*
 * The event structure itself
   //事件结构体
 */

struct input_event {    -> 专门用于描述一个事件。
    struct timeval time;   -> 事件发生的时间。
    __u16 type;            -> 事件的类型  (输入子系统会用这个值来描述刚才发生事件的硬件设备)
    __u16 code;            -> 事件的编码  -> 对事件进一步的描述   左键/右键  A键/R键  x轴/y轴
    __s32 value;           -> 事件的值
};

struct timeval {
        long    tv_sec;         /* 秒 */
        long    tv_usec;        /* 微秒 */
};

   例子2: 现在我们知道读取出来的,就是一个结构体。
       我们现在就把结构体里面的成员打印出来看看,究竟等于多少?

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <linux/input.h>

int main(int argc,char *argv[])
{
    //1. 访问触摸屏设备
    int fd;
    fd = open("/dev/input/event0",O_RDONLY);
    if(fd < 0)
    {
        printf("open ts error!\n");
    }
    
    //2. 读取触摸屏设备的数据
    struct input_event buf;
    while(1)
    {
        read(fd,&buf,sizeof(buf));
        printf("buf.type = %d\n",buf.type);
        printf("buf.code = %d\n",buf.code);
        printf("buf.value = %d\n",buf.value);    
    }
    
    //3. 关闭文件。
    close(fd);
    
    return 0;
}

结果:
[root@GEC6818 /]#./ts
buf.type = 3   -> 触摸屏位移
buf.code = 0   -> 触摸屏的x轴
buf.value = 274-> 点击的坐标的x轴坐标

buf.type = 3   -> 触摸屏位移
buf.code = 1   -> 触摸屏的y轴
buf.value = 384-> 点击的坐标的y轴坐标

buf.type = 1   -> 按键
buf.code = 330 -> 触摸屏压力
buf.value = 1  -> 按下

buf.type = 0
buf.code = 0
buf.value = 0

buf.type = 1   -> 按键
buf.code = 330 -> 触摸屏压力
buf.value = 0  -> 松开

buf.type = 0
buf.code = 0
buf.value = 0

结果的值也是被封装在一个头文件中:#include "input-event-codes.h"
1)事件的类型有哪些?
/*
 * Event types
 */

#define EV_SYN            0x00   -> 异步通信。
#define EV_KEY            0x01   -> 按键事件  (一般指的就是这类设备:键盘/压力/按键)
#define EV_REL            0x02   -> 相对位移  (一般指的就是鼠标)
#define EV_ABS            0x03   -> 绝对位移  (一般指的就是触摸屏)

2)事件的编码由哪些?
EV_KEY -> 对应的code有哪些?
#define BTN_TOUCH        0x14a(等价于十进制的330)


EV_ABS -> 对应的code有哪些?
#define ABS_X            0x00  -> 代表触摸屏的x轴
#define ABS_Y            0x01  -> 代表触摸屏的y轴

    例子3: 点击屏幕松开手,就打印一句话。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <linux/input.h>

int main(int argc,char *argv[])
{
    //1. 访问触摸屏设备
    int fd;
    fd = open("/dev/input/event0",O_RDONLY);
    if(fd < 0)
    {
        printf("open ts error!\n");
    }
    
    //2. 读取触摸屏设备的数据
    struct input_event buf;
    while(1)
    {
        read(fd,&buf,sizeof(buf)); //发生了很多个事件
        //但是只有松手的事件才是我想要的。
        if(buf.type == 1 && buf.code == 330 && buf.value == 0)
        {
            printf("your hand leave lcd!\n");
        }    
    }
    
    //3. 关闭文件。
    close(fd);
    
    return 0;
}


    练习1: 写一个程序,实现当你的手在屏幕上滑动时,就不断打印当前坐标出来,顺便看看原点在哪里?
             x   y
       (100,200)

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <linux/input.h>

int main(int argc,char *argv[])
{
    //1. 访问触摸屏设备
    int fd;
    fd = open("/dev/input/event0",O_RDONLY);
    if(fd < 0)
    {
        printf("open ts error!\n");
    }
    
    //2. 读取触摸屏设备的数据
    struct input_event buf;
    int x,y;
    while(1)
    {
        read(fd,&buf,sizeof(buf)); //发生了很多个事件
        if(buf.type == 3 && buf.code == 0)
        {
            x = buf.value;
        }
        
        if(buf.type == 3 && buf.code == 1)
        {
            y = buf.value;
        }
        
        printf("(%d,%d)\n",x,y);
    }
    
    close(fd);
    return 0;
}

    练习2: 写一个程序,实现点击屏幕的左边松开,就打印一次"left"。
                  点击屏幕的右边松开,就打印一次"right"。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <linux/input.h>
#include <strings.h>

int main(int argc,char *argv[])
{
    int fd,x;
    struct input_event buf;

    /* 1. 访问触摸屏设备 */
    fd = open("/dev/input/event0",O_RDONLY);
    if(fd < 0)
        printf("open event0 error!\n");
    
    /*2. 不断读取触摸屏数据 */
    while(1)
    {
        bzero(&buf,sizeof(buf)); //每次读取之前,都保证缓冲区是清空的状态。
        read(fd,&buf,sizeof(buf));
        
        //3. 获取手触摸到的坐标
        if(buf.type == EV_ABS && buf.code == ABS_X)
            x = buf.value;
        
        //4. 判断你什么时候松手。
        if(buf.type == EV_KEY && buf.code == BTN_TOUCH && buf.value == 0)
        {
            //5. 判断下你刚刚松手的位置在哪里
            if(x < 500) //左边
            {
                printf("left!\n");
            }
            
            if(x > 500) //右边
            {
                printf("right!\n");
            }
            
            if(x == 500)
            {
                break;
            }
        }
    }
    
    //6. 关闭文件
    close(fd);
    
    return 0;
}


===================================
补充理解输入子系统的现实例子。
type:
吃饭 -> 0
睡觉 -> 1

code:
早餐 -> 0
午餐 -> 1
晚餐 -> 2

午觉 -> 0
晚觉 -> 1

value;
饱 -> 0
饿 -> 1
睡得着 -> 2
睡不着 -> 3


    struct input_event{   -> 代表输入子系统分析出来: 你刚刚睡午觉没睡着
    .type = 1
    .code = 0
    .value = 3
    } 


 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值