Linux基本硬件控制之触摸屏
我们知道键盘输入、语言识别等都是人机交互的方式,用户通过多种多样的途径对计算机进行信息输入,控制计算机完成指定任务,而输入设备中常用的就有触摸屏,对此我讲一下对触摸屏原理的浅显了解。
—>Linux常见标准函数接口见这篇<—
—>Linux常见系统IO函数接口见这篇<—
—>Linux简单硬件控制之LCD见这篇<—
我们知道键盘输入、语言识别等都是人机交互的方式,用户通过多种多样的途径对计算机进行信息输入,控制计算机完成指定任务,而输入设备中常用的就有触摸屏,对此我讲一下对触摸屏原理的浅显了解。
1.触摸屏分类及原理
1.1电阻式触摸屏原理
- 结构:通常是薄膜加玻璃的结构,薄膜和玻璃相邻面涂有 ITO(纳米铟锡金属氧化物)涂层 ,两层之间有微小隔层,如2.5微米间隔。以常见的四线电阻屏为例,电路实现包含上下叠合的两个透明层,由两层具有相同表面电阻的透明阻性材料组成。
- 原理:基于压力感应和分压器原理。当手指或其他物体触摸屏幕时,施加压力使薄膜下层的 ITO 接触到玻璃上层的 ITO 。一面导电层接通 Y 轴方向的 5V 均匀电压场,侦测层电压由零变为非零 ,控制器侦测到接通后进行 A/D 转换,将得到的电压值与 5V 相比,得出触摸点的 Y 轴坐标;同理,改变电压施加方向可得出 X 轴坐标。从分压器原理看,把触摸点与接地边之间的电阻当作分压器下面的电阻,在未偏置层上测得的电压与触摸点到接地边的距离成正比,通过测量电压确定坐标。
1.2电容式触摸屏原理
- 结构:以常见的投射式电容触摸屏为例,是四层复合玻璃屏。玻璃屏内表面和夹层涂有 ITO ,最外层是矽土玻璃保护层 ,夹层 ITO 涂层作为工作面,四个角引出四个电极,内层 ITO 为屏蔽层。
- 原理:利用人体电流感应。人体有电场,当手指触摸电容屏工作面时,由于工作面接有高频信号,手指和工作面形成耦合电容,手指吸收走一个很小的电流,这个电流从触摸屏四个角的电极流出,且流经四个电极的电流与手指到四角的距离成比例。控制器通过精密计算四个电流的比例,得出触摸点位置。以投射式电容触摸屏中的互电容屏为例,玻璃表面 ITO 制作的横向电极与纵向电极交叉处形成电容 。当手指触摸,影响触摸点附近两个电极间耦合,改变电容量。横向电极依次发出激励信号,纵向电极同时接收信号,获取整个触摸屏二维平面的电容大小,依据电容变化量数据计算触摸点坐标 。
2.驱动过程
我们知道Linux系统中用户不能直接控制硬件,因为硬件得通过寄存器进行控制,而寄存器由内核驱动程序控制,由于内存安全管理机制,用户不能跨过内核直接控制硬件,而触摸屏属于输入设备,输入设备的驱动子系统统一在input目录里,触摸屏的设备文件是/dev/input/eventn(n是触摸屏编号),触摸屏信息都存储在该文件中,由于是输入设备我们是要读取触摸屏的信息,所以一般就是打开event文件读取其中的触摸屏信息,根据触摸屏信息执行我们设定的程序。
3.触摸屏头文件
我们知道触摸屏的设备文件是dev/input/eventn后,要想进一步了解触摸屏的文件信息和定义的结构体等的话我们需要看一下触摸屏的头文件,头文件一般放在usr/include目录下,输入设备放在input目录下,在Linux终端切换目录为usr/include发现没有input目录,但是有linux目录,点进去看一下,发现有input目录,里面有两个input头文件:

先打开input.h看一下:
在input.h头文件里定义了许多结构体其中比较常用的是上图这个结构体,其中有四个变量存储的触摸屏的事件时间、事件类型、事件码、和值,input_event 结构体用于描述输入设备产生的事件,__u16 type 表示事件类型,取值为 EV_XXX 宏(如 EV_KEY、EV_ABS)以标识事件类别;__u16 code 是事件码,含义依赖 type,例如 EV_KEY 时表示按键编码,EV_ABS 时表示绝对坐标类型(如 ABS_X、ABS_Y);__s32 value 为事件值,同样依 type 而定,如 EV_KEY 中 1 表示按下、0 表示释放,EV_ABS 中存储具体坐标数值。
在另一个头文件einput-event-codes.h里定义了不同类型事件的宏如下:如EV_REL是相对坐标事件,EV_ABS是绝对坐标事件。
4.代码示例
假设我们要通过触摸屏获取用户点击触摸屏位置的坐标信息,大致思路就是打开设备文件,读取设备文件信息,由于设备文件信息存储在一个结构体里,我们要提前定义一个结构体变量来存放读出来的信息,最后就是对读取的信息进行处理,包括type,code,value,比如我们想要打印绝对坐标信息,那么就需要获取x和y坐标信息,由于LCD屏和触摸屏可能不是同等比例的需要进行缩放才是LCD的xy坐标值,最后再打印出来。
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
// 获取的坐标是等比例缩小过的
int main(int argc, char const *argv[])
{
// 1. 打开触摸屏
int ts_fd = open("/dev/input/event0", O_RDWR);
// 2. 读取输入设备的信息
struct input_event ts_event;
int cnt = 0;
int x = 0, y = 0;
while (1)
{
read(ts_fd, &ts_event, sizeof(ts_event));
// 3. 分析读取的设备信息(type + code + value)
if (ts_event.type == EV_ABS) // 说明是触摸屏
{
if (ts_event.code == ABS_X) // 说明是x轴
{
cnt++;
x = ts_event.value * 600 / 1024;
}
if (ts_event.code == ABS_Y) // 说明是Y轴
{
cnt++;
y = ts_event.value * 600 / 600;
}
if (cnt >= 2)
{
printf("x = %d\t", x); // 输出X轴坐标
printf("y = %d\n", y); // 输出Y轴坐标
cnt = 0;
}
}
}
// 4. 关闭触摸屏
close(ts_fd);
return 0;
}
更多推荐



所有评论(0)