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

触摸屏驱动程序我在这篇文章有讲解:请点击这里!   有些朋会很奇怪,你这个驱动程序不是jz2440的,内核用的版本也不一样,我想说的是你都开始做项目了,如果连这个小问题都不能解决的,我劝你还是赶快回去从头开始学习。还是那句老话,我只提供思路和框架,万变不离其中这个道理你应该明白吧。如果你一味的去追求别人全部跟你做好了,你只是copy上去,编译成功。你学到多少呢?扯远了。

如果你驱动移植成功了,可以点击这里用tslib来测试,校验,查看打印坐标位置,我们后面用的到,测试触摸屏按下和松开两点的举例时候会用的到,所以这个tslib必须测试吧,编译的时候还会用到tslib库。tslib测试请点击这里!

下面就开始上代码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!
");  
return -1;  
}  
  
if (ts_config(g_tTSDev)) {    /* 目前我也不知道是干嘛用的 ,猜测是做一些初始化工作,或者配置之类的*/  
DBG_PRINTF("ts_config error!
");  
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
", 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 */
文章导航