基于GEC6818的触摸屏

这篇具有很好参考价值的文章主要介绍了基于GEC6818的触摸屏。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 输入子系统

连接操作系统的输入设备,可不止一种,也许是一个标准PS/2键盘,也许是一个USB鼠标,或者是一块触摸屏,甚至是一个游戏机摇杆,Linux在处理这些纷繁各异的输入设备的时候,采用的办法还是找中间层来屏蔽各种细节,请看下图:

基于GEC6818的触摸屏

在Linux的内核中,对输入设备的使用,实际上运用了3大块来管理,他们分别是所谓的输入设备驱动层、输入子系统核心层,以及事件触发层。他们各自的工作分别是:

  1. 输入设备驱动层:
    每一种设备都有其特定的驱动程序,他们被妥当地装载到操作系统的设备模型框架内,封装硬件所提供的功能,向上提供规定的接口。

  2. 核心层:
    此处将收集由设备驱动层发来的数据,整合之后触发某一事件。

  3. 事件触发层:
    这一层是我们需要关注的,我们可以通过在用户空间读取相应设备的节点文件来获知某设备的某一个动作。

以触摸屏为例,当手指在屏幕上滑动的时候,数据流大致是这样的:驱动层中的触摸屏驱动会源源不断地产生触摸屏相关数据,并向上递送给内核输入子系统,输入子系统进一步将这些信息规整为统一的结构体,并借助事件触发层发往对应的设备节点,至此,应用程序即可从这些设备节点读取相关信息。

值得注意的是,底层驱动产生的设备数据与上层应用读取设备数据是两个完全异步的过程,彼此之间是没有耦合和约束的,例如:当底层驱动产生的触摸屏坐标信息比应用层读取的速度要快时,应用程序将会丢失一部分坐标信息。

2. 输入信息结构体

在最靠近应用程序的事件触发层上,内核所获知的各类输入事件,比如键盘被按了一下,触摸屏被滑了一下等,都将被统一封装在一个叫做 input_even 的输入信息结构体当中,这个结构体定义如下:

vincent@ubuntu:/usr/include/linux/$ cat input.h -n
     1    #ifndef _INPUT_H
     2    #define _INPUT_H
     3    
     ...
     ...
    20    
    21    struct input_event {
    22        struct timeval time;
    23        __u16 type;
    24        __u16 code;
    25        __s32 value;
    26    };
    27    
    ...

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

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

2. type 输入事件的类型。比如:

事件类型(type) 说明
EV_SYN 事件间的分割标志,有些事件可能会在时间和空间上产生延续,比如持续按住一个按键
为了更好地管理这些持续的事件,EV_SYN用以将他们分割成一个个的小的数据包。
EV_KEY 用以描述键盘,按键或者类似键盘的设备的状态变化。
EV_REL 相对位移,比如鼠标的移动,滚轮的转动等。
EV_ABS 绝对位移,比如触摸屏上的坐标值。
EV_MSC 不能匹配现有的类型,这相当于当前暂不识别的事件
比如在Linux系统中按下键盘中针对Windows系统的“一键杀毒”按键,将会产生该事件。
EV_LED 用于控制设备上的LED灯的开关,比如按下键盘的大写锁定键
会同时产生 ”EV_KEY” 和 ”EV_LED” 两个事件。
… … … …

3. code 

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

事件类型(type) 事件代码(code) 说明
EV_KEY BTN_TOUCH 触摸屏发生了按压、松开事件
EV_KEY KEY_LEFT 键盘的左箭头发生了按压、松开事件
EV_KEY KEY_RIGHT 键盘的右箭头发生了按压、松开事件
EV_ABS ABS_X 触摸屏发生了x轴坐标事件
EV_ABS ABS_Y 触摸屏发生了y轴坐标事件
EV_REL ABS_Y 触摸屏发生了y轴坐标事件
EV_ABS ABS_Y 触摸屏发生了y轴坐标事件
… … … … … …

 4. value

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

事件类型(type) 事件代码(code) 发生值(value) 说明
EV_KEY BTN_TOUCH 大于0 手指按压了触摸屏
EV_KEY BTN_TOUCH 0 手指松开了触摸屏
EV_KEY KEY_LEFT 大于0 左箭头被按下
EV_KEY KEY_LEFT 0 左箭头被松开
EV_ABS ABS_X 213 触摸屏产生了一个233的 x 轴坐标
EV_ABS ABS_Y 448 触摸屏产生了一个448的 y 轴坐标
… … … … … … … …

 3. 触作摸屏操作

对于触摸屏而言,该设备会产生三种数据:

  • X轴坐标值
  • Y轴坐标值
  • P压力值

理论上来说,从手指放上屏幕开始,到滑动一段距离,离开屏幕结束,会产生如下所示的一系列数据:

(X Y P1) SYN (X Y) SYN (X Y) SYN (X Y) ... ... (X Y) SYN (X Y P2)

有如下地方需要注意:

  • 在刚开始的第一个坐标值和最后一个坐标值中,都连带会读到压力值P
  • P1是手指刚落下时,产生压力值大于0的数据
  • P2是手指离开时,产生压力值等于0的数据
  • 应用层并不能保证能严格交替读取 (X,Y) 坐标值,它们会由于异步等原因出现断续,比如 (X X X X Y)
  • 若手指滑动的方向刚好垂直与坐标轴,会导致其中一个维度的坐标值不变,那么也可能会导致只出现一个维度坐标值的情形,例如:
... (X) SYN (X) SYN (X Y) SYN (Y) ... ... (X Y) SYN ...

这种情况下需要借助系统自动产生的 SYN 事件来整理出成对的坐标值。文章来源地址https://www.toymoban.com/news/detail-451943.html

4、触摸屏相关函数代码

//触摸屏划屏函数

#include <stdio.h>  //usr/include/stdio.h
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/*输入子系统头文件*/
#include <linux/input.h>   //usr/include/linux/input.h

int main(int argc,char **argv)
{
	/*打开触摸屏*/
	int fd;
	fd = open("/dev/input/event0",O_RDWR);
	if(fd < 0)
	{
		perror("open ts fail");
		return -1;
	}
	
	/*操作触摸屏*/
	//定义一个存储触摸屏信息的结构体
	struct input_event ts;
	
	int x1=0,y1=0; //按下去的坐标值
	int x2=0,y2=0; //松手后的坐标值

	while(1)//循环读取数据
	{		
		/*抓取按下去的坐标值*/
		while(1)
		{	
			//在这个地方read这条语句是阻塞(根本原因此处的fd带有阻塞属性)
			read(fd,&ts,sizeof(struct input_event));
			if(ts.type == EV_ABS && ts.code==ABS_X) //x轴的坐标值
			{
				//printf("x=%d ",ts.value); //蓝色触摸屏的坐标值
				x1 = ts.value;
				//printf("x=%d ",(int)(ts.value*0.78)); //蓝色触摸屏的坐标值 1024 方法一
				//printf("x=%d ",ts.value*800/1024); //方法二
			}
			if(ts.type == EV_ABS && ts.code==ABS_Y) //y轴的坐标值
			{
				//printf("y=%d\n",ts.value);//蓝色触摸屏的坐标值
				y1 = ts.value;
				//printf("x=%d ",(int)(ts.value*0.8));//黑色触摸屏的坐标值 600 方法一
				//printf("y=%d\n",ts.value*480/600); //方法二
			}
			
			//当按下去的那一刻,跳出循环;只抓取按下去的坐标值
			if(ts.type == EV_KEY && ts.code==BTN_TOUCH && ts.value == 1)//
			{
				printf("按下去:x1=%d y1=%d\n",x1,y1);
				break;
			}
		}	

		/*抓取松手后的坐标值*/
		while(1)
		{	
			//在这个地方read这条语句是阻塞(根本原因此处的fd带有阻塞属性)
			read(fd,&ts,sizeof(struct input_event));
			if(ts.type == EV_ABS && ts.code==ABS_X) //x轴的坐标值
			{
				//printf("x=%d ",ts.value); //蓝色触摸屏的坐标值
				x2 = ts.value;
				//printf("x=%d ",(int)(ts.value*0.78)); //蓝色触摸屏的坐标值 1024 方法一
				//printf("x=%d ",ts.value*800/1024); //方法二
			}
			if(ts.type == EV_ABS && ts.code==ABS_Y) //y轴的坐标值
			{
				//printf("y=%d\n",ts.value);//蓝色触摸屏的坐标值
				y2 = ts.value;
				//printf("x=%d ",(int)(ts.value*0.8));//黑色触摸屏的坐标值 600 方法一
				//printf("y=%d\n",ts.value*480/600); //方法二
			}
			
			//当按下去的那一刻,跳出循环,只抓取松手后的坐标值
			if(ts.type == EV_KEY && ts.code==BTN_TOUCH && ts.value == 0)//
			{
				printf("松手:x2=%d y2=%d\n",x2,y2);
				break;
			} 
		}	
		
		if(x2-x1 > 50) //50差值决定你滑动的灵敏度
			printf("right\n");
		if(x2-x1 < -50) 
			printf("left\n");	
		if(y2-y1 > 50) 
			printf("down\n");
		if(y2-y1 < -50)
			printf("up\n");		
	}	
	/*关闭触摸屏*/
	close(fd);
	
	return 0;
}

//触摸屏单击函数
#include <stdio.h>  //usr/include/stdio.h
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/*输入子系统头文件*/
#include <linux/input.h>   //usr/include/linux/input.h

int main(int argc,char **argv)
{
	/*打开触摸屏*/
	int fd;
	fd = open("/dev/input/event0",O_RDWR);
	if(fd < 0)
	{
		perror("open ts fail");
		return -1;
	}
	
	/*操作触摸屏*/
	//定义一个存储触摸屏信息的结构体
	struct input_event ts;
	
	//读取触摸屏的设备文件
	while(1)
	{	
		//在这个地方read这条语句是阻塞(根本原因此处的fd带有阻塞属性)
		read(fd,&ts,sizeof(struct input_event));
		if(ts.type == EV_ABS && ts.code==ABS_X) //x轴的坐标值
		{
			//printf("x=%d ",ts.value); //蓝色触摸屏的坐标值
			//printf("x=%d ",(int)(ts.value*0.78)); //蓝色触摸屏的坐标值 1024 方法一
			printf("x=%d ",ts.value*800/1024); //方法二
		}
		if(ts.type == EV_ABS && ts.code==ABS_Y) //y轴的坐标值
		{
			//printf("y=%d\n",ts.value);//蓝色触摸屏的坐标值
			//printf("x=%d ",(int)(ts.value*0.8));//黑色触摸屏的坐标值 600 方法一
			printf("y=%d\n",ts.value*480/600); //方法二
		}
	}	
	
	/*关闭触摸屏*/
	close(fd);
	
	return 0;
}

到了这里,关于基于GEC6818的触摸屏的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux 多点电容触摸屏实验

    1、多点触摸(MT)协议详解 电容触摸屏驱动其实就是以下几种 linux 驱动框架的组合: ①、IIC 设备驱动,因为电容触摸 IC 基本都是 IIC 接口的,因此大框架就是 IIC 设备驱动。 ②、通过中断引脚(INT)向 linux 内核上报触摸信息,因此需要用到 linux 中断驱动框架。坐标的上报在中断

    2024年02月06日
    浏览(57)
  • ESP32开发---驱动触摸屏

    采用 I2C 驱动触摸屏。 I2C 多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。 它有两条线,一条是 SCL (串行时钟总线),另外一条是SDA(串行数据线),这两条数据需要接上拉电阻,总线空闲的时候SCL和SDA处于高电

    2024年02月08日
    浏览(57)
  • Linux 触摸屏 (IIC驱动详解)

    本文使用触摸屏iic驱动,驱动编写中要使用 总线,设备,驱动 分层的思想,IIC总线,触摸屏驱动,触摸屏设备,   一般 SOC 的 I2C 总线驱动都是由半导体厂商编写的,比如 I.MX6U 的 I2C 适配器驱动 NXP 已经编写好了,这个不需要用户去编写。因此 I2C 总线驱动对我们这些 SOC 使

    2023年04月11日
    浏览(57)
  • 电容触摸屏驱动(Linux驱动开发篇)

    电容屏只需要手指轻触即可,而电阻屏是需要手指 给予一定的压力才有反应,而且电容屏不需要校准。 如果要做人机交互设备的开发,多点电容触摸屏基本是不可能绕过去的。 正点原子ATK-7016 这款屏幕 其实是由 TFT LCD+触摸屏组合起来的。底下是 LCD 面板,上面是触摸面板,

    2024年02月05日
    浏览(69)
  • WPF --- 触摸屏下的两个问题

    本片文章分享一下之前遇到的WPF应用在触摸屏下使用时的两个问题。 具体场景就是一个配置界面, ScrollViewer 中包含一个 StackPanel 然后纵向堆叠,已滚动的方式查看,然后包含多个 TextBlock 、 TextBox 以及 DataGrid ,期间遇到了两个问题: WPF在触摸屏下,如果有滚动条( ScrollVie

    2024年03月09日
    浏览(58)
  • 威纶通触摸屏报错问题汇总

    一旦出现这样提示以后,不管是离线模拟还是在线模拟都无法顺利往下执行,那么,怎么来解决这个问题呢?解决这个问题,通常分以下三类情况: 情况一 常规的解决方法 四个步骤,逐步进行,步骤一解决不了再进行步骤二这样类推。 1、 软件编辑-系统参数设置-HMI属性-端

    2024年02月05日
    浏览(53)
  • 单片机与触摸屏的通信实现方法

    单片机与触摸屏的通信是在嵌入式系统中常见的任务之一。通过合适的通信协议和接口,我们可以实现单片机与触摸屏之间的数据传输和交互。下面将详细介绍一种常用的实现方法,并提供相应的源代码示例。 硬件连接 首先,我们需要将触摸屏与单片机正确地连接起来。触

    2024年03月12日
    浏览(50)
  • 【威纶通触摸屏 按键保护(元件安全设置)】

    提示:在触摸屏的设计中,需要对系统按键设置保护,防止误操作和非法操作,需要特定的用户权限才可以操作。 提示:这里使用的威纶通触摸屏软件及版本如下: 1.窗口布局如下,本页面展示设备运行时长,在设备保养或更换主要零部件后,按下重置按钮重新设备计算运行

    2024年02月05日
    浏览(64)
  • 物联网工业触摸屏与防火墙的安全协作

    随着物联网技术的快速发展,物联网HMI不仅需要提供 SCADA级功能库和控件库(点击查看物联网HMI功能库和控件库的详细介绍) ,还需要具备强大的安全性能。虹科物联网HMI内置防火墙功能,识别和阻止未经授权的访问,保护设备的安全交互。本文将重点介绍 虹科物联网HMI防

    2024年02月10日
    浏览(43)
  • LCD图片显示、触摸屏、音乐播放、缩放图片和播放视频

    (1)原理 LCD屏幕是由一个个像素组成的,横向像素个数和纵向像素个数是LCD的一个重要指标,称为像素分辨率,当前举例开发板的分辨率是 800X480 LCD显示从屏幕左上角的像素开始,直到右下角一帧结束 像素位数指的是存储一个像素数据所需要的空间长度,当前举例LCD的像素

    2023年04月09日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包