笔记:
书本《4.4触控屏应用接口》,了解开发板的触摸屏操作。
蜂鸣器、LCD显示屏
——》信息输出设备
触控屏:(一切皆文件)
——》信息输入设备(检测设备)
——》测试触摸屏:cat /dev/input/event0
如果出现乱码,出现了原始数据,说明正常,
打开open、读取read、关闭close
============= 1.触摸屏原始数据解析 ===================
输入子系统头文件:
/usr/include/linux/input.h
输入子系统编码文件:
/usr/include/linux/input-event-codes.h
输入子系统信息结构体:
struct input_event {
struct timeval time; // 事件发生时间戳(一般不使用)
__u16 type; // 事件类型
__u16 code; // 事件编码
__s32 value; // 事件数值
};
Type:
#define EV_SYN 0x00 分割标志(一类事件结束后会产生)
#define EV_KEY 0x01 按键事件(触摸屏点击事件)
#define EV_ABS 0x03 绝对位移(触摸屏坐标事件)
Code:
#define BTN_TOUCH 0x14a 触摸屏点击编码
#define ABS_X 0x00 触摸屏X轴编码
#define ABS_Y 0x01 触摸屏Y轴编码
备注:
1.黑色底板屏幕,触摸屏坐标范围是(0~1024, 0~600)
代码:
1.demo1_触摸屏输入.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h> // 输入子系统头文件
int main()
{
// 1.打开
int ts_fd = open("/dev/input/event0", O_RDONLY);
if(ts_fd == -1)
{
perror("open ts failed");
return -1;
}
// 2.读取(产生阻塞,等待用户点击)
struct input_event ts_buf;
while(1)
{
read(ts_fd, &ts_buf, sizeof(ts_buf));
printf("type:0x%x code:0x%x value:%d\n", ts_buf.type, ts_buf.code, ts_buf.value);
}
// 3.关闭
close(ts_fd);
return 0;
}
2.demo2_坐标打印.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h> // 输入子系统头文件
int ts_fd; // 触摸屏文件描述符全局变量
// 获取当前点击坐标
void get_xy(int *x, int *y);
int main()
{
// 1.打开触摸屏文件
ts_fd = open("/dev/input/event0", O_RDONLY);
if(ts_fd == -1)
{
perror("open ts failed");
return -1;
}
// 2.读取坐标(产生阻塞,等待用户点击)
int pos_x, pos_y;
while(1)
{
// 黑色底板屏幕,触摸屏坐标范围是(0~1024, 0~600),可通过计算进行缩小
get_xy(&pos_x, &pos_y);
printf("(%d, %d)\n", pos_x, pos_y);
}
// 3.关闭触摸屏
close(ts_fd);
return 0;
}
// 获取当前点击坐标
void get_xy(int *x, int *y)
{
int x_ready=0, y_ready=0;
struct input_event ts_buf;
while(1)
{
read(ts_fd, &ts_buf, sizeof(ts_buf));
// printf("type:0x%x code:0x%x value:%d\n", ts_buf.type, ts_buf.code, ts_buf.value);
// if(ts_buf.type==0x3 && ts_buf.code==0x0)
if(ts_buf.type==EV_ABS && ts_buf.code==ABS_X)
{
*x = ts_buf.value;
x_ready = 1;
y_ready = 0; // 确保x坐标获取在前
}
else if(ts_buf.type==EV_ABS && ts_buf.code==ABS_Y)
{
*y = ts_buf.value;
y_ready = 1;
}
if(x_ready==1 && y_ready==1)
break;
}
}
项目1
head.h
#ifndef __HEAD_H
#define __HEAD_H
// 头文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <linux/input.h> // 输入子系统头文件
// 打开LCD设备并初始化显存
extern int open_lcd(void);
// 关闭LCD设备
extern void close_lcd(void);
// 显示色块
extern void show_color(int x_start, int y_start, int w, int h, int color);
// 打开触摸屏文件
extern int open_ts(void);
// 关闭触摸屏
extern void close_ts(void);
// 获取当前点击坐标
extern void get_xy(int *x, int *y);
#endif
lcd.c
#include "head.h"
static int *FB; // 显存首地址(内部链接类型)
static int lcd_fd; // LCD文件描述符
// 打开LCD设备并初始化显存
int open_lcd(void)
{
// 1. 打开冰箱门 ——》打开屏幕设备文件
lcd_fd = open("/dev/fb0", O_RDWR);
if(lcd_fd == -1)
{
perror("open lcd failed");
return -1;
}
// 显存映射(int *类型表示操作对象是像素点)
FB = mmap( NULL, // 填NULL表示显存地址由系统自动分配
800*480*4, // 整块屏幕的显存大小
PROT_READ|PROT_WRITE, // 显存保护权限:可读可写
MAP_SHARED, // 多进程共享设置
lcd_fd, // LCD文件描述符
0); // 0表示不偏移
if(FB == MAP_FAILED)
{
perror("mmap failed");
return -2;
}
return 0;
}
// 关闭LCD设备
void close_lcd(void)
{
close(lcd_fd);
}
// 显示色块
void show_color(int x_start, int y_start, int w, int h, int color)
{
int x, y;
for(y=y_start; y<y_start+h; y++)
for(x=x_start; x<x_start+w; x++)
*(FB+x+800*y) = color;
}
main.c
#include "head.h"
int main()
{
open_lcd(); // 打开并初始化LCD
open_ts(); // 打开触摸屏
// 全屏刷白
show_color(0, 0, 800, 480, 0xFFFFFF);
int pos_x, pos_y;
while(1)
{
get_xy(&pos_x, &pos_y);
printf("(%d,%d)\n", pos_x, pos_y);
if(pos_x>=0 && pos_x<400)
show_color(0, 0, 800, 480, 0xFFFFFF);
else if(pos_x>=400 && pos_x<=800)
show_color(0, 0, 800, 480, 0xFF0000);
}
close_ts(); // 关闭触摸屏
close_lcd(); // 关闭LCD
return 0;
}
ts.c
#include "head.h"
static int ts_fd; // 触摸屏文件描述符全局变量
// 打开触摸屏文件
int open_ts(void)
{
ts_fd = open("/dev/input/event0", O_RDONLY);
if(ts_fd == -1)
{
perror("open ts failed");
return -1;
}
return 0;
}
// 关闭触摸屏
void close_ts(void)
{
close(ts_fd);
}
// 获取当前点击坐标
void get_xy(int *x, int *y)
{
int x_ready=0, y_ready=0;
struct input_event ts_buf;
while(1)
{
read(ts_fd, &ts_buf, sizeof(ts_buf));
// printf("type:0x%x code:0x%x value:%d\n", ts_buf.type, ts_buf.code, ts_buf.value);
// if(ts_buf.type==0x3 && ts_buf.code==0x0)
if(ts_buf.type==EV_ABS && ts_buf.code==ABS_X)
{
*x = ts_buf.value;
x_ready = 1;
y_ready = 0; // 确保x坐标获取在前
}
else if(ts_buf.type==EV_ABS && ts_buf.code==ABS_Y)
{
*y = ts_buf.value;
y_ready = 1;
}
if(x_ready==1 && y_ready==1)
break;
}
}