数码相框项目之触摸屏模块

最后更新于:2022-04-01 16:27:19

触摸屏驱动程序我在这篇文章有讲解:[请点击这里!](http://blog.csdn.net/qq_21792169/article/details/48750695)   有些朋会很奇怪,你这个驱动程序不是jz2440的,内核用的版本也不一样,我想说的是你都开始做项目了,如果连这个小问题都不能解决的,我劝你还是赶快回去从头开始学习。还是那句老话,我只提供思路和框架,万变不离其中这个道理你应该明白吧。如果你一味的去追求别人全部跟你做好了,你只是copy上去,编译成功。你学到多少呢?扯远了。 如果你驱动移植成功了,可以点击这里用tslib来测试,校验,查看打印坐标位置,我们后面用的到,测试触摸屏按下和松开两点的举例时候会用的到,所以这个tslib必须测试吧,编译的时候还会用到tslib库。[tslib测试请点击这里!](http://blog.csdn.net/qq_21792169/article/details/50408577) 下面就开始上代码touchScreen.c文件如下: ~~~ #include <config.h> #include <input_manager.h> #include <stdlib.h>  #include <tslib.h>    /* tslib里面的头文件,在次强调一定要安装tslib */ #include <draw.h>    /* 参考tslib里的ts_print.c */   /* 可以打印两点的距离 */ static struct tsdev *g_tTSDev; static int giXres; static int giYres; static T_InputOpr  g_tTouchScreenOpr;   /* 定义T_InputOpr类型的结构体,这个结构体定义在input_manager.h中 */ /* 注意: 由于要用到LCD的分辨率, 此函数要在SelectAndInitDisplay之后调用 */ static int TouchScreenDevInit(void)   /* 初始化TouchScreen */ { char *pcTSName = NULL; if ((pcTSName = getenv("TSLIB_TSDEVICE")) != NULL )   /* 获取环境变量,在测试tslib时候指定的 */ { g_tTSDev = ts_open(pcTSName, 1); } else { g_tTSDev = ts_open("/dev/event0", 1);  /* 没有指定环境变量就打开/dev/event0 */ } if (!g_tTSDev) {   DBG_PRINTF("ts_open error!\n"); return -1; } if (ts_config(g_tTSDev)) {    /* 目前我也不知道是干嘛用的 ,猜测是做一些初始化工作,或者配置之类的*/ DBG_PRINTF("ts_config error!\n"); return -1; } if (GetDispResolution(&giXres, &giYres))   /* 获得lcd的分辨率 */ { return -1; } g_tTouchScreenOpr.iFd = ts_fd(g_tTSDev); /* 获得这个文件的句柄,后面调用select函数监测 */ return 0; } static int TouchScreenDevExit(void) { return 0; } static int isOutOf500ms(struct timeval *ptPreTime, struct timeval *ptNowTime)  /* 延时500ms,防止触摸屏不停的操作 */ { int iPreMs; int iNowMs; iPreMs = ptPreTime->tv_sec * 1000 + ptPreTime->tv_usec / 1000; iNowMs = ptNowTime->tv_sec * 1000 + ptNowTime->tv_usec / 1000; return (iNowMs > iPreMs + 500); } static int TouchScreenGetInputEvent(PT_InputEvent ptInputEvent) /* 从触摸屏获取数据 */ { struct ts_sample tSamp; int iRet; static struct timeval tPreTime; iRet = ts_read(g_tTSDev, &tSamp, 1);  /* 把读取到的值存放在tSamp这个结构体中 */ if (iRet < 0) { return -1; } /* 处理数据 */ if (isOutOf500ms(&tPreTime, &tSamp.tv)) { /* 如果此次触摸事件发生的时间, 距上次事件超过了500ms */ tPreTime = tSamp.tv; ptInputEvent->tTime = tSamp.tv; ptInputEvent->iType = INPUT_TYPE_TOUCHSCREEN;  /* 触摸屏类型,不是串口终端或者按键, */ if (tSamp.y < giYres/3) { ptInputEvent->iVal = INPUT_VALUE_UP;  /* 向上翻页 */ } else if (tSamp.y > 2*giYres/3) { ptInputEvent->iVal = INPUT_VALUE_DOWN;  /* 想下翻页 */ } else { ptInputEvent->iVal = INPUT_VALUE_UNKNOWN;  /* 点击中间部分就是没反应 */ } return 0; } else { return -1; } return 0; } static T_InputOpr g_tTouchScreenOpr = { /* 给这个类型的结构 赋值,定义在头文件中定义*/ .name          = "touchscreen", .DeviceInit    = TouchScreenDevInit, .DeviceExit    = TouchScreenDevExit, .GetInputEvent = TouchScreenGetInputEvent, }; int TouchScreenInit(void)  /* 和上篇的lcd是一样的 */ { return RegisterInputOpr(&g_tTouchScreenOpr); } input_manager.c文件如下:/* 不详细讲解了,和lcd框架是一模一样 */ #include <config.h> #include <input_manager.h> #include <string.h> #include <sys/select.h> static PT_InputOpr g_ptInputOprHead; static fd_set g_tRFds; static int g_iMaxFd = -1; int RegisterInputOpr(PT_InputOpr ptInputOpr) { PT_InputOpr ptTmp; if (!g_ptInputOprHead) { g_ptInputOprHead   = ptInputOpr; ptInputOpr->ptNext = NULL; } else { ptTmp = g_ptInputOprHead; while (ptTmp->ptNext) { ptTmp = ptTmp->ptNext; } ptTmp->ptNext = ptInputOpr; ptInputOpr->ptNext = NULL; } return 0; } void ShowInputOpr(void)  /* 显示链表中有哪些成员 */ { int i = 0; PT_InputOpr ptTmp = g_ptInputOprHead; while (ptTmp) { printf("%02d %s\n", i++, ptTmp->name); ptTmp = ptTmp->ptNext; } } int AllInputDevicesInit(void)   /* 调用链表中结构体里面的初始化函数 */ { PT_InputOpr ptTmp = g_ptInputOprHead; int iError = -1; FD_ZERO(&g_tRFds); while (ptTmp) { if (0 == ptTmp->DeviceInit()) { FD_SET(ptTmp->iFd, &g_tRFds);   /* 这里还是为了select函数做的一些初始化操作 */ if (g_iMaxFd < ptTmp->iFd) g_iMaxFd = ptTmp->iFd; iError = 0; } ptTmp = ptTmp->ptNext; } g_iMaxFd++; return iError; } int GetInputEvent(PT_InputEvent ptInputEvent) { /* 用select函数监测stdin,touchscreen,   有数据时再调用它们的GetInputEvent或获得具体事件 */ PT_InputOpr ptTmp = g_ptInputOprHead; fd_set tRFds; int iRet; tRFds = g_tRFds; iRet = select(g_iMaxFd, &tRFds, NULL, NULL, NULL);  /* 没数据读的时候就阻塞 */ if (iRet > 0) { while (ptTmp) { if (FD_ISSET(ptTmp->iFd, &tRFds)) { if(0 == ptTmp->GetInputEvent(ptInputEvent))  /* 在链表中区找tTmp->iFd这个ID的结构体中的出读取函数 */ { return 0; } } ptTmp = ptTmp->ptNext; } } return -1; } int InputInit(void)  /* 初始化。仅仅是放进链表中 */ { int iError; iError = StdinInit(); iError |= TouchScreenInit(); return iError; } input_manager.h文件如下: #ifndef _INPUT_MANAGER_H #define _INPUT_MANAGER_H #include <sys/time.h> #define INPUT_TYPE_STDIN        0 #define INPUT_TYPE_TOUCHSCREEN  1 #define INPUT_VALUE_UP          0    #define INPUT_VALUE_DOWN        1 #define INPUT_VALUE_EXIT        2 #define INPUT_VALUE_UNKNOWN     -1 typedef struct InputEvent { struct timeval tTime; int iType;  /* stdin, touchsceen */ int iVal;   /*  */ }T_InputEvent, *PT_InputEvent; typedef struct InputOpr { char *name; int iFd; int (*DeviceInit)(void); int (*DeviceExit)(void); int (*GetInputEvent)(PT_InputEvent ptInputEvent); struct InputOpr *ptNext; }T_InputOpr, *PT_InputOpr; int InputInit(void); int RegisterInputOpr(PT_InputOpr ptInputOpr); void ShowInputOpr(void); int AllInputDevicesInit(void); int GetInputEvent(PT_InputEvent ptInputEvent); int StdinInit(void); int TouchScreenInit(void); #endif /* _INPUT_MANAGER_H */ ~~~
';