- (꒪ꇴ꒪ ),hello我是祐言
- 博客主页:C语言基础,Linux基础,软件配置领域博主🌍
- 快上🚘,一起学习!
- 送给读者的一句鸡汤🤔:
- 集中起来的意志可以击穿顽石!
- 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏
在正式学习触摸屏之前,我们先来了解一下事件类型及其常见动作,虽然可能看起来一大堆,但是常用的并不多,希望耐心学完,方便后续的学习和使用。
一、事件类型
在Linux输入子系统中,事件类型(Event Types)用于标识输入设备生成的不同类型的事件。每个事件都有一个特定的类型代码,用于表示该事件属于哪种类型。在Linux内核中,输入子系统定义了几种常见的事件类型,其中一些主要的事件类型包括:
-
`EV_SYN`(0x00):表示事件同步。当多个事件组合在一起时,会在它们之间插入一个`EV_SYN`事件,用于同步事件的处理。
-
`EV_KEY`(0x01):表示键盘事件。用于表示按键的按下和释放操作,每个按键都有一个特定的键码(key code)。
-
`EV_REL`(0x02):表示相对事件。用于表示相对于设备上一次事件的变化,例如鼠标滚轮的滚动。
4. `EV_ABS`(0x03):表示绝对事件。用于表示设备上的绝对位置,例如触摸屏的触摸点坐标。
5. `EV_MSC`(0x04):表示杂项事件。用于表示一些特殊事件,如设备的状态改变。
- `EV_SW`(0x05):表示开关事件。用于表示开关状态的改变,如设备的开启和关闭状态。
7. `EV_LED`(0x11):表示LED事件。用于控制LED灯的开关状态。
-
`EV_SND`(0x12):表示声音事件。用于控制声音设备的状态,例如音量调节。
-
`EV_REP`(0x14):表示重复事件。用于控制自动重复的设置,例如按键自动重复。
-
`EV_FF`(0x15):表示力反馈事件。用于控制力反馈设备(如震动手柄)的力反馈效果。
每个事件类型都有对应的数据结构和事件码 ,用于描述具体的事件信息。应用程序可以通过读取输入设备节点来获取事件信息,并根据事件类型和事件码进行相应的处理。这样,应用程序可以响应用户的输入操作,实现各种交互功能。
二、事件类型的常见动作
在Linux输入子系统中,每个事件类型都有一个对应的事件码(Event Code),用于标识该类型事件的具体内容。事件码是一个整数值,不同的事件类型有不同的事件码范围。以下是一些常见的事件类型及其对应的事件码:
- `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):触摸屏压力值
- 等等,还有其他绝对坐标的事件码**
- `EV_MSC`(杂项事件):
-
`MSC_SERIAL` (0x00):序列号
-
`MSC_PULSELED` (0x01):脉冲LED指示灯
-
等等,还有其他杂项事件的事件码
- `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开发板使用触摸屏的总结如下:
-
触摸屏硬件:6818开发板通常配备了触摸屏硬件,这是一种输入设备,可以通过手指或触控笔进行操作。触摸屏硬件通常与主板通过接口连接,例如串口或USB。
-
Linux输入子系统:在Linux系统中,触摸屏被视为一个输入设备,并由Linux输入子系统进行管理和处理。输入子系统负责接收触摸屏的输入事件,并将其转换为用户空间的事件供应用程序使用。
-
触摸屏设备文件:在Linux系统中,触摸屏设备会以字符设备的形式出现在**
/dev/input/
** 目录下,通常命名为**eventX
**,其中X为数字。用户可以通过打开这个设备文件,并读取其中的输入事件来获取触摸屏的坐标信息。 -
获取触摸坐标:通过打开触摸屏设备文件,并读取其中的输入事件,可以获取触摸屏的坐标信息。触摸坐标通常以绝对坐标形式提供,即X轴和Y轴的具体数值。
-
处理触摸事件:在应用程序中,可以使用循环结构读取触摸屏设备文件,并解析读取到的输入事件,从中获取触摸坐标信息。然后根据触摸坐标信息进行相应的处理,比如根据坐标位置判断点击的区域,进行交互或控制操作。
-
应用场景:触摸屏在嵌入式系统中广泛应用,特别适合具有交互界面的应用场景,如嵌入式终端、信息展示设备、智能家居控制面板、工业自动化设备等。通过触摸屏,用户可以直接在屏幕上进行交互操作,增加了设备的便捷性和用户体验。
总的来说,对于6818开发板来说,使用触摸屏可以实现更加直观、方便的交互操作,为嵌入式系统提供了更加友好的用户界面。通过Linux输入子系统的支持,开发人员可以轻松获取触摸屏的输入信息,并根据具体应用场景实现不同的交互功能。
更多C语言和Linux系统相关文章,关注专栏:
📢写在最后
- 今天的分享就到这啦~
- 觉得博主写的还不错的烦劳
一键三连喔
~ - 🎉感谢关注🎉