觸摸屏驅動程序我在這篇文章有講解:[請點擊這里!](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 */
~~~