笔记:
书本《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; } }