上一章學習了開發板外接鍵盤并獲取鍵盤的的輸入
Linux輸入設備應用編程(鍵盤,按鍵)-CSDN博客
本章編寫觸摸屏應用程序,獲取觸摸屏的坐標信息并將其打印出來
目錄
一 觸摸屏數據分析(觸摸,點擊,松開)
1.1 硬件須知?
1.2 觸摸屏信息分析
二 觸摸屏應用編程
2.1 獲取觸摸屏的最大同時觸點
2.2? 觸摸屏單點觸點編程
一 觸摸屏數據分析(觸摸,點擊,松開)
1.1 硬件須知?
首先在測試觸摸屏之前,需要保證開發板上已經連接了LCD屏
使用命令"cat /proc/bus/input/devices",確定觸摸屏對應的設備節點(本人將指令封裝成了cat_dev),如下所示: ?

1.2 觸摸屏信息分析
執行input文件后,一個手指點擊觸摸屏后松開,終端將會打印如下信息: ?
首先第一行上報了絕對位移事件EV_ABS(type=3)中的ABS_MT_TRACKING_ID(code=57)事件,并且value值等于246,也就是ID,這個ID是一個非負數,所以表示這是一個新的觸摸點被創建,也就意味著觸摸屏上產生了一個新的觸摸點(手指按下)。
第二行上報了絕對位移事件EV_ABS(type=3)中的ABS_MT_POSITION_X(code=53)事件,其value對應的便是觸摸點的X坐標;
第三行上報了ABS_MT_POSITION_Y(code=54)事件,其value值對應的便是觸摸點Y坐標,所以由此可知該觸摸點的坐標為(890, 445)。
第四行上報了按鍵類事件EV_KEY(type=1)中的BTN_TOUCH(code=330),value值等于1,表示這是觸摸屏上最先產生的觸摸點(slot=0、也就是觸摸點0)。
第五行和第六行分別上報了絕對位移事件EV_ABS(type=3)中的ABS_X(code=0)和ABS_Y(code=1),其value分別對應的是觸摸點的X坐標和Y坐標。多點觸摸設備也會通過ABS_X、ABS_Y事件上報觸摸點的X、Y坐標,但通常只有觸摸點0支持,所以可以把多點觸摸設備當成單點觸摸設備來使用。
第七行上報了同步類事件EV_SYN(type=0)中的SYN_REPORT(code=0)事件,表示此次觸摸點的信息全部上報完畢。
第八行當手指松開時,觸摸點就會被銷毀,上報ABS_MT_TRACKING_ID事件,并將value設置為-1(ID)
第四行上報了按鍵類事件EV_KEY(type=1)中的BTN_TOUCH(code=330),value值等于0,表示觸摸屏上的觸摸點銷毀
最后一行上報同步事件(type=0、code=0),告知應用層數據完整。
二 觸摸屏應用編程
2.1 獲取觸摸屏的最大同時觸點
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>int main(int argc, char *argv[])
{struct input_absinfo info; //調用 ioctl()會將獲取到的信息寫入到struct input_absinfo對象int fd = -1;int max_slots; //最大觸摸點數/* 校驗傳參 */if (2 != argc) {fprintf(stderr, "usage: %s <input-dev>\n", argv[0]);exit(-1);}/* 打開文件 */if (0 > (fd = open(argv[1], O_RDONLY))) {perror("open error");exit(-1);}/* 獲取slot信息 */if (0 > ioctl(fd, EVIOCGABS(ABS_MT_SLOT), &info)) {perror("ioctl error");close(fd);exit(-1);}max_slots = info.maximum + 1 - info.minimum;printf("max_slots: %d\n", max_slots);/* 關閉、退出 */close(fd);exit(0);
}
?代碼寫完后,進行交叉編譯,通過scp指令將文件發送到開發板上,然后執行input_slot文件
所以從打印結果可知,我們這個屏是一個5點觸摸屏。?
2.2? 觸摸屏單點觸點編程
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>int main(int argc, char *argv[])
{int fd = -1;struct input_event in_ev;int x = 0; //觸摸點 x和 y坐標 int y = 0;int start = 3; //用于記錄 BTN_TOUCH事件的 value,1表示按下,0表示松開,-1表示移動int valid = -1; //用于記錄數據是否有效(我們關注的信息發生更新表示有效,1表示有效,0表示無效/* 校驗傳參 */if (2 != argc) {fprintf(stderr, "usage: %s <input-dev>\n", argv[0]);exit(-1);}/* 打開文件 */if (0 > (fd = open(argv[1], O_RDONLY))) {perror("open error");exit(-1);}while(1){if(sizeof(struct input_event) != read(fd,&in_ev,sizeof(struct input_event))){perror(" ");exit(-1);}switch (in_ev.type){case EV_KEY: //按鍵事件if (BTN_TOUCH == in_ev.code) //觸摸屏第一個點{ start = in_ev.value; //觸摸屏狀態valid = 1; //同步時間標志位}break;case EV_ABS: //絕對位移事件 switch (in_ev.code) { case ABS_X: //X坐標x = in_ev.value;valid = 1; break; case ABS_Y: //Y坐標 y = in_ev.value; valid = 1; break; } break; case EV_SYN: //同步事件if (SYN_REPORT == in_ev.code) {if (valid) {//判斷是否有效switch (start) {//判斷狀態case 1:printf("按下(%d, %d)\n", x, y);break;case 0:printf("松開\n");break;case -1:printf("移動(%d, %d)\n", x, y);break;}valid = 0; //重置validstart = -1; //重置start}}break;}}/* 關閉、退出 */close(fd);exit(0);
}
程序中首先校驗傳參,通過傳參的方式將觸摸屏設備文件路徑傳入到程序中,main()函數中定義了4個變量:
- 變量x表示觸摸點的X坐標;
- 變量y表示觸摸點的Y坐標;
- 變量start表示手指狀態時候按下、松開還是滑動,start=1表示手指按下、start=0表示手指松開、start=-1表示手指滑動;
- 變量valid表示數據是否有效,valid=1表示有效、valid=0表示無效;有效指的是我們檢測的信息發生了更改,譬如程序中只檢測了手指的按下、松開動作以及坐標值的變化。
接著調用open()打開觸摸屏設備文件得到文件描述符fd;在for循環之前,首先對x、y、start、valid這4個變量進行初始化操作。在for循環讀取觸摸屏上報的數據,將讀取到的數據存放在struct input_event數據結構中。在switch…case語句中對讀取到的數據進行解析,獲取BTN_TOUCH事件的value數據,判斷觸摸屏是按下還是松開狀態,獲取ABS_X和ABS_Y事件的value變量,得到觸摸點的X軸坐標和Y軸坐標。
當上報同步事件時,表示數據已經完整,接著對我們得到的數據進行分析、打印坐標信息。
將編譯得到的可執行文件拷貝到開發板,準備進行測試。
