【Liux下6818开发板(ARM)】触摸屏

news2024/11/17 16:20:49
  • (꒪ꇴ꒪ ),hello我是祐言
  • 博客主页:C语言基础,Linux基础,软件配置领域博主🌍
  • 快上🚘,一起学习!
  • 送给读者的一句鸡汤🤔:
  • 集中起来的意志可以击穿顽石!
  • 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏

        在正式学习触摸屏之前,我们先来了解一下事件类型及其常见动作,虽然可能看起来一大堆,但是常用的并不多,希望耐心学完,方便后续的学习和使用。

一、事件类型


        在Linux输入子系统中,事件类型(Event Types)用于标识输入设备生成的不同类型的事件。每个事件都有一个特定的类型代码,用于表示该事件属于哪种类型。在Linux内核中,输入子系统定义了几种常见的事件类型,其中一些主要的事件类型包括:

        1. `EV_SYN`(0x00):表示事件同步。当多个事件组合在一起时,会在它们之间插入一个`EV_SYN`事件,用于同步事件的处理。

        2. `EV_KEY`(0x01):表示键盘事件。用于表示按键的按下和释放操作,每个按键都有一个特定的键码(key code)。

        3. `EV_REL`(0x02):表示相对事件。用于表示相对于设备上一次事件的变化,例如鼠标滚轮的滚动。

        4. `EV_ABS`(0x03):表示绝对事件。用于表示设备上的绝对位置,例如触摸屏的触摸点坐标。

        5. `EV_MSC`(0x04):表示杂项事件。用于表示一些特殊事件,如设备的状态改变。

        6. `EV_SW`(0x05):表示开关事件。用于表示开关状态的改变,如设备的开启和关闭状态。

        7. `EV_LED`(0x11):表示LED事件。用于控制LED灯的开关状态。

        8. `EV_SND`(0x12):表示声音事件。用于控制声音设备的状态,例如音量调节。

        9. `EV_REP`(0x14):表示重复事件。用于控制自动重复的设置,例如按键自动重复。

        10. `EV_FF`(0x15):表示力反馈事件。用于控制力反馈设备(如震动手柄)的力反馈效果。

        每个事件类型都有对应的数据结构和事件码,用于描述具体的事件信息。应用程序可以通过读取输入设备节点来获取事件信息,并根据事件类型和事件码进行相应的处理。这样,应用程序可以响应用户的输入操作,实现各种交互功能。

二、事件类型的常见动作

在Linux输入子系统中,每个事件类型都有一个对应的事件码(Event Code),用于标识该类型事件的具体内容。事件码是一个整数值,不同的事件类型有不同的事件码范围。以下是一些常见的事件类型及其对应的事件码:

        1. `EV_KEY`(键盘事件):
   - `BTN_LEFT` (0x110):左键按下或释放
   - `BTN_RIGHT` (0x111):右键按下或释放
   - `KEY_A` (0x0041):A键按下或释放
   - `KEY_ENTER` (0x001c):回车键按下或释放
   - 等等,还有许多其他键的事件码

        2. `EV_REL`(相对事件):
   - `REL_X` (0x00):X轴相对位移
   - `REL_Y` (0x01):Y轴相对位移
   - `REL_HWHEEL` (0x06):水平滚轮相对位移
   - 等等,还有其他相对位移的事件码

        3. `EV_ABS`(绝对事件):
   - `ABS_X` (0x00):X轴绝对坐标
   - `ABS_Y` (0x01):Y轴绝对坐标
   - `ABS_PRESSURE` (0x18):触摸屏压力值
   - 等等,还有其他绝对坐标的事件码

        4. `EV_MSC`(杂项事件):
   - `MSC_SERIAL` (0x00):序列号
   - `MSC_PULSELED` (0x01):脉冲LED指示灯
   - 等等,还有其他杂项事件的事件码

        5. `EV_SW`(开关事件):
   - `SW_LID` (0x00):笔记本电脑盖子状态开关
   - `SW_POWER` (0x01):电源按钮开关
   - 等等,还有其他开关事件的事件码

        这些事件码表示了不同类型的事件内容,应用程序可以根据事件类型和事件码来确定输入设备发送的具体事件,并进行相应的处理。

        注意

        上述列举的事件码只是一小部分常见的事件,实际上,Linux输入子系统支持更多事件类型和事件码,不同的硬件设备可能会有不同的事件类型和事件码。如果你需要获取特定设备的事件码,请查阅对应设备的文档或内核头文件来了解其支持的事件类型和事件码。

三、获取触摸屏的分辨率

  struct input_absinfo用于描述输入设备(包括触摸屏)的绝对坐标信息。

        以下是struct input_absinfo的定义:

struct input_absinfo {
    __s32 value;
    __s32 minimum;
    __s32 maximum;
    __s32 fuzz;
    __s32 flat;
    __s32 resolution;
};
  • value: 当前的坐标值。

  • minimum: 坐标的最小值。

  • maximum: 坐标的最大值。

  • fuzz: 坐标的模糊值。表示坐标值的一小部分可能是无效的,因为硬件的精度有限。

  • flat: 坐标的平坦度。表示坐标值在相邻时间段内的变化较小时被认为是无效的。

  • resolution: 坐标的分辨率。表示坐标值的精确度,通常以单位/毫米(units/mm)为单位。

        获取输入设备的绝对事件信息(例如触摸屏的坐标范围和分辨率):

#include <stdio.h>
#include <linux/input.h>
​
int main() {
    int fd = open("/dev/input/eventX", O_RDONLY);
    if (fd < 0) {
        perror("Error opening device");
        return 1;
    }
​
    struct input_absinfo absinfo_x, absinfo_y;
    if (ioctl(fd, EVIOCGABS(ABS_X), &absinfo_x) == -1 ||
        ioctl(fd, EVIOCGABS(ABS_Y), &absinfo_y) == -1) {
        perror("Error getting absolute axis info");
        close(fd);
        return 1;
    }
​
    printf("X axis: min=%d, max=%d\n", absinfo_x.minimum, absinfo_x.maximum);
    printf("Y axis: min=%d, max=%d\n", absinfo_y.minimum, absinfo_y.maximum);
​
    close(fd);
    return 0;
}

        请注意,上述示例代码中的/dev/input/eventX需要替换为正确的输入设备节点路径X是对应的事件号。这些示例代码只是基本用法,实际使用中可能需要添加错误处理和其他功能。同时,需要以合适的权限运行这些代码,通常需要root或者有相应访问权限的用户。

        这里的X指的就是设备文件名,在上一篇文章中这里有说明:

 【玩转Linux】Linux输入子系统简介_祐言QAQ的博客-CSDN博客

四、触摸屏示例代码

        当我们知道了如何开启触摸屏文件以及如何获取触摸屏的分辨率后,我们就可以使用它了,下面是一个简单的示例,在这个例子中我们使用了Linux输入子系统处理触摸屏输入的程序。

        它通过打开触摸屏设备文件/dev/input/event0,读取触摸事件,并解析事件来获取触摸屏的坐标位置。然后根据触摸坐标位置判断点击的区域,并进行相应的处理。

        代码主要包括以下几个部分:

        1.get_xy函数

        该函数用于从触摸屏设备中读取输入事件,并解析出X和Y轴的坐标值。在这里,通过read函数读取输入事件,判断事件类型是否是绝对事件(触摸事件),并根据事件类型设置对应的坐标值。

       2. main函数

        主函数中先打开触摸屏设备文件,并通过一个无限循环不断读取触摸事件。然后使用get_xy函数获取坐标值,并根据坐标值判断点击的区域。根据区域的判断结果,打印出相应的信息,比如"相册"、"音乐"、"视频"或"游戏"。
 

        图示是这样:

         代码:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/input.h>

#define TOUCH_DEV "/dev/input/event0" // 触摸屏设备文件路径


void get_xy(int touch_fd,int *x,int *y)
{

    struct input_event buf;
    *x = -1;
	*y = -1;

    while (1)
    {
        // 读取触摸事件
		int ret = read(touch_fd, &buf, sizeof(buf));
        if (ret == -1){
			perror("read fail");
			exit(errno);
		}
        // 判断事件类型是否是触摸事件
        if (buf.type == EV_ABS)
        {
            // 根据事件类型设置对应的坐标值
            if (buf.code == ABS_X){
                *x = (buf.value * 800) / 1024;
			}	
            if (buf.code == ABS_Y){
                *y = (buf.value * 800) / 1024;
			}
        }

        if (!(*x > 0 && *x < 800 && *y > 0 && *y < 480)){
			continue;
		}	
		
		if(*x>-1 && *y>-1){
			break; // 得到坐标后退出
		}	
    }
	
}


int main(int argc, char *argv[])
{
	int x,y;
	// 打开触摸屏
    int touch_fd = open(TOUCH_DEV, O_RDONLY);
    if (touch_fd < 0){
        perror("打开触摸屏失败");
        exit(errno);
    }
	
	
	while(1)
	{
		// 拿到一组完整的坐标就返回
		get_xy(touch_fd, &x, &y);
		
		// 使用返回的坐标,判断点击的哪块区域
		if( x>0 && x<400 && y>0 && y<240 )	//左上角那块区域
			printf("相册\n");
		else if(x>400 && x<800 && y>0 && y<240)		//右上角的那块区域
			printf("音乐\n");
		else if(x>400 && x<800 && y>240 && y<480)	//右下角的那块区域
			printf("视频\n");
		else if(x>0 && x<400 && y>240 && y<480)	//左下角的那块区域	
			printf("游戏\n");
	}
	
	
	
	// 关闭触摸屏
	close(touch_fd);
	
    return 0;
}

        总体来说,这段代码实现了一个简单的触摸屏交互功能,根据用户的点击位置来显示相应的区域信息。这个例子展示了Linux输入子系统的基本用法,可以在具体的应用中根据需要进行扩展和优化。下面是演示效果:

五、总结

        对于6818开发板使用触摸屏的总结如下:

  1. 触摸屏硬件:6818开发板通常配备了触摸屏硬件,这是一种输入设备,可以通过手指或触控笔进行操作。触摸屏硬件通常与主板通过接口连接,例如串口或USB。

  2. Linux输入子系统:在Linux系统中,触摸屏被视为一个输入设备,并由Linux输入子系统进行管理和处理。输入子系统负责接收触摸屏的输入事件,并将其转换为用户空间的事件供应用程序使用。

  3. 触摸屏设备文件:在Linux系统中,触摸屏设备会以字符设备的形式出现在/dev/input/目录下,通常命名为eventX,其中X为数字。用户可以通过打开这个设备文件,并读取其中的输入事件来获取触摸屏的坐标信息。

  4. 获取触摸坐标:通过打开触摸屏设备文件,并读取其中的输入事件,可以获取触摸屏的坐标信息。触摸坐标通常以绝对坐标形式提供,即X轴和Y轴的具体数值。

  5. 处理触摸事件:在应用程序中,可以使用循环结构读取触摸屏设备文件,并解析读取到的输入事件,从中获取触摸坐标信息。然后根据触摸坐标信息进行相应的处理,比如根据坐标位置判断点击的区域,进行交互或控制操作。

  6. 应用场景:触摸屏在嵌入式系统中广泛应用,特别适合具有交互界面的应用场景,如嵌入式终端、信息展示设备、智能家居控制面板、工业自动化设备等。通过触摸屏,用户可以直接在屏幕上进行交互操作,增加了设备的便捷性和用户体验。

        总的来说,对于6818开发板来说,使用触摸屏可以实现更加直观、方便的交互操作,为嵌入式系统提供了更加友好的用户界面。通过Linux输入子系统的支持,开发人员可以轻松获取触摸屏的输入信息,并根据具体应用场景实现不同的交互功能。

 

        更多C语言Linux系统相关文章,关注专栏:

   手撕C语言

            玩转linux

📢写在最后

  • 今天的分享就到这啦~
  • 觉得博主写的还不错的烦劳 一键三连喔~
  • 🎉感谢关注🎉

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/816716.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

怎么通过通过 p 名称空间配置 bean以及怎么去引用/注入其它 bean 对象--ref和怎么去引用/注入内部 bean 对象-内部 bean 对象

&#x1f600;前言 本章是spring基于XML 配置bean系类中第2篇讲解怎么通过通过 p 名称空间配置 bean以及怎么去引用/注入其它 bean 对象–ref和怎么去引用/注入内部 bean 对象 &#x1f3e0;个人主页&#xff1a;尘觉主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0…

小白三步即可设置企业在线帮助中心?

设置企业在线帮助中心是提升客户服务质量和用户体验的重要举措。以下将介绍三个简单的步骤&#xff0c;帮助企业建立一个高效的在线帮助中心。 第一步&#xff1a;规划与设计 在设置企业在线帮助中心之前&#xff0c;需要进行一定的规划和设计工作&#xff0c;确保帮助中心能够…

MPAndroidChart学习及问题处理

1.添加依赖 项目目录->app->build.gradle dependencies {implementation com.github.PhilJay:MPAndroidChart:v3.0.3 }项目目录->app->setting.gradle dependencyResolutionManagement {repositories {maven { url https://jitpack.io }} }高版本的gradle添加依…

解决路由缓存问题

产生原因 路由只有参数发生变化时 会复用组件实例 解决 1.选择key 简单粗暴 2.选择beforeRouteUpdate钩子函数

【javaSE】 面向对象程序三大特性之继承

目录 为什么需要继承 继承的概念 继承的语法 注意事项 父类成员访问 子类中访问父类的成员变量 子类和父类不存在同名成员变量 子类和父类成员变量同名 访问原则 子类中访问父类的成员方法 成员方法名字不同 总结&#xff1a; 成员方法名字相同 总结&#xff1a; …

spider-flow可视化爬虫界面从入门到放弃

目录 下载编译部署官网地址编译部署启动 简单使用输出文件方式可以正常执行的任务 自定义任务获取小说名 总结 下载编译部署 官网地址 修改端口、数据库、存放地址、执行文件等配置&#xff08;前后端不分离&#xff0c;配置文件端口即页面登录端口&#xff09; spider-flow-w…

Vite+Vue3 开发UI组件库并发布到npm

一直对开源UI组件库比较感兴趣&#xff0c;摸索着开发了一套&#xff0c;虽然还只是开始&#xff0c;但是从搭建到发布这套流程基本弄明白了&#xff0c;现在分享给大家&#xff0c;希望对同样感兴趣的同学有所帮助。 目前我的这套名为hasaki-ui的组件库仅有两个组件&#xff0…

Meta AI研究团队新AI模型: Llama 2 大语言模型

Llama是Facebook Research团队开发的基础语言模型集&#xff0c;旨在提供广泛的语言理解能力。它基于转换器架构&#xff0c;参数范围从7B到65B。通过使用Llama模型&#xff0c;研究人员和开发人员可以构建更先进的自然语言处理系统。您可以在GitHub上找到相关的代码和资源&…

JIT 与 C#热更

JIT与AOT 一般程序运行有两种方式&#xff0c;静态编译与动态编译。 AOT: Ahead Of Time,预先&#xff08;静态&#xff09;编译 静态编译的程序&#xff0c;需要在执行之前全部翻译为机器码&#xff0c;运行前会使得程序安装时间相对较长&#xff0c;但程序运行的时候&#…

TDengine时区设置

一般来说&#xff0c;时序数据就是带有时间序列属性的数据。在处理时序数据时&#xff0c;TDengine有着自己独特的方式。但是如果没有正确理解TDengine在写入和查询上的行为&#xff0c;极可能会因为配置了错误的时区&#xff08;timezone&#xff09;&#xff0c;而导致写入和…

《怎样顺利通过答辩:论文答辩的策略与技巧》

最近在阅读《怎样顺利通过答辩这本书》&#xff0c;记录一下阅读获取的关键信息和心得。 目录 第一章 答辩是什么 在答辩前你需要做到以下几件事情&#xff0c;核查清单如下&#xff1a; 答辩根据考生及其研究的质量&#xff0c;服务于不同的目的&#xff1a; 通常意义上的…

面向对象编程三大特征

1、基本介绍 面向对象编程有三大特征&#xff1a;封装、继承和多态。 1.1封装介绍 1.2封装的理解和好处 1.3封装的实现步骤 (三步) 2、面向对象编程-继承 2.1为什么需要继承 2.2继承基本介绍和示意图 继承可以解决代码复用,让我们的编程更加靠近人类思维.当多个类存在相同的…

rtabmap 主从机 rviz 订阅 /rtabmap/mapData 时报错

在实体小车上跑rtabmap算法&#xff0c;在rviz上订阅 /rtabmap/mapData 话题时不显示建图信息并且报错&#xff1a; [ERROR] [xxxxxxxx]: Client [/rviz] wants topic /rtabmap/mapData to have datatype/md5sum [rtabmap/mapData/xxxxxxxxxxxxx], but our version has [rtabm…

【腾讯云 Cloud Studio 实战训练营】Redisgo_task 分布式锁实现

文章目录 前言问题场景腾讯云 Cloud Studio Redisgo_task长短类型分布式场景介绍Redisgo_task实现原理SetNx(valueexpire)原子性子协程Done()时间点子协程中的Ticker Redisgo_task唯一外部依赖Redisgo_task Lock结构Redisgo_task架构健壮性设计Redisgo_task可扩展性Redisgo_tas…

ALLEGRO之FlowPlan

本文主要讲述了ALLEGRO的FlowPlan菜单。 &#xff08;1&#xff09;Auto Bundle&#xff1a;暂不清楚&#xff1b; &#xff08;2&#xff09;Create Bundle&#xff1a;暂不清楚&#xff1b; &#xff08;3&#xff09;Delete Bundle&#xff1a;暂不清楚&#xff1b; &…

earth靶机详解

earth靶机复盘 靶场下载地址&#xff1a;https://download.vulnhub.com/theplanets/Earth.ova 这个靶场还是非常有意思的&#xff0c;值得去打一下。 我们对拿到的ip进行一个单独全面的扫描&#xff0c;发现有两个DNS解析。 就把这两条解析添加到hosts文件中去&#xff0c;要…

IO进程线程第三天(7.31)time,localtime,文件io函数:open,umask,close,write,read,lseek,stat,

用read函数完成图片文件拷贝 #include<stdio.h> #include<head.h> int main(int argc, const char *argv[]) {//umask(0);//将文件权限掩码改为0&#xff0c;使得其他用户可写int fd open("/home/ubuntu/图片/2.jpg",O_RDONLY,0777);//打开图片if(fd&l…

无线蓝牙耳机有什么推荐?怎么选择适合自己的耳机?七款蓝牙耳机分享

随着信息技术的不断发展&#xff0c;蓝牙耳机的不断发展也是必然的&#xff0c;可以说蓝牙耳机在大部分人们的生活中是不可缺少的一部分。那么我们该怎么去挑选出适合我们自己的需求的“蓝”朋友呢&#xff1f; 第一款&#xff1a;南卡小音舱lite2蓝牙耳机 推荐指数&#xff…

Android 之 AudioManager ( 音频管理器 )

本节引言&#xff1a; 在多媒体的第一节&#xff0c;我们用SoundPool写了个Duang的示例&#xff0c;小猪点击一个按钮后&#xff0c;突然发出"Duang"的 一声&#xff0c;而且当时的声音很大&#xff0c;吓死宝宝了 &#xff0c;好在不是上班时间&#xff0c;上班时间…