// Topic:彻底解决2440触摸屏跳点问题
// 作者:gooogleman
// 版权:gooogleman嵌入式开发板联盟wogoyixikexie@gliet.gooogleman
// 平台:wince5.0 2440 5.0 BSP (飞凌FL2440/OK2440开发板 3.5 寸LCD)
// 发布日期:2010年11月18日
// 最后修改:
//技术论坛:www.gooogleman.com
// 注意事项:商业网站未经作者同意不能转载,并且不能删除文章的任何部分,否则追究责任!
//-------------------------------------------------------------------------------------------------
其实2440触摸屏跳点问题在前一个多月已经得到解决,在我解决6410 触摸屏抖动的时候,偶然发现6410 不会任何跳点,只是抖动,后来比较2440 和6410 的触摸屏驱动写法,发现6410的比较惊异,算法避免了天外飞仙跳点。
ooo,下班了,明天再写吧。
——续@2010-11-19
我仔细比较6410 触摸屏驱动和2440 驱动,发现6410 的写法比较合理一些,最大区别是DdsiTouchPanelGetPoint函数写法,下面是2440 会跳点的写法。
从上面可以看出,这个DdsiTouchPanelGetPoint里面只进行了一步采样,尽管采样次数大于1次,但是也绝对不能消除天外飞仙跳点。因为这几次采样时间太靠近了,所以采样值都会很相近,即使是多次采样(我曾经试过20 次,没有多大改善。),求平均值,效果也会很微小。这个情况就说明,要想触摸屏不跳点,就要消除错误的采样点,那么怎么做呢?上面每隔10ms 连续采样多次无效,原因是每次采样间隔时间太短,数据太密集,接近,导致仍然获得的是误差数据。假设想想,如果扩大采样时间间隔去采样,这样获得的数据就不会太接近就可以判断了吧?看看6410 的触摸屏驱动,果然是每隔10ms 采样两组数据的,并且这两组数据进行比较分析,误差过大就说明采样点是无效的,这样就把天外飞仙的现象去掉了。下面也贴出改好的2440 代码,希望大家有帮助。
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
PUBLIC VOID
DdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS * pTipStateFlags,
INT * pUncalX,
INT * pUncalY)
{
static INT x, y;
int TmpX = 0;
int TmpY = 0;
if (v_pINTregs->SUBSRCPND & (1<<IRQ_SUB_TC)) /* SYSINTR_TOUCH Interrupt Case*/
{
*pTipStateFlags = TouchSampleValidFlag;
if ( (v_pADCregs->ADCDAT0 & (1 << 15)) |
(v_pADCregs->ADCDAT1 & (1 << 15)) )
{
bTSP_DownFlag = FALSE;
DEBUGMSG(ZONE_TIPSTATE, (TEXT("up\r\n")));
v_pADCregs->ADCTSC &= 0xff;
*pUncalX = x;
*pUncalY = y;
TSP_SampleStop();
// Test
RETAILMSG(1,(TEXT("bTSP_DownFlag = FALSE...PenUP!!!\r\n")));
}
else
{
bTSP_DownFlag = TRUE;
//if (!TSP_GetXY(&x, &y))
// *pTipStateFlags = TouchSampleIgnore;
//TSP_TransXY(&x, &y);
//-----------------------add @2010.09.11-----------------------
*pTipStateFlags |= TouchSampleIgnore;
*pUncalX = x;
*pUncalY = y;
*pTipStateFlags |= TouchSampleDownFlag;
//Test
RETAILMSG(1,(TEXT("bTSP_DownFlag = TRUE...PenDown!!!\r\n")));
TSP_SampleStart();
}
v_pINTregs->SUBSRCPND = (1<<IRQ_SUB_TC);
v_pINTregs->INTSUBMSK &= ~(1<<IRQ_SUB_TC);
InterruptDone(gIntrTouch);
}
else /* SYSINTR_TOUCH_CHANGED Interrupt Case */
{
// TSP_SampleStart();
if (bTSP_DownFlag)
{
if (TSP_GetXY(&TmpX, &TmpY) == TRUE)
{
//TSP_TransXY(&TmpX, &TmpY);
if(Touch_Pen_Filtering(&TmpX, &TmpY))
{
*pTipStateFlags = TouchSampleValidFlag | TouchSampleDownFlag;
*pTipStateFlags &= ~TouchSampleIgnore;
}
else // Invalid touch pen
{
*pTipStateFlags = TouchSampleValidFlag;
*pTipStateFlags |= TouchSampleIgnore;
}
*pUncalX = x = TmpX;
*pUncalY = y = TmpY;
}
else
{
*pTipStateFlags = TouchSampleIgnore;
}
}
else
{
*pTipStateFlags = TouchSampleIgnore;
TSP_SampleStop();
RETAILMSG(1,(TEXT("bTSP_DownFlag = FALSE.PenDown!!!IRQ_Timer3 Interrupt\r\n")));
}
InterruptDone(gIntrTouchChanged);
}
// add by wogo at2009.03.23 why?
SetEvent(hEventTouchInput);
}
static BOOL
Touch_Pen_Filtering(INT *px, INT *py)
{
BOOL RetVal = TRUE;
// TRUE : Valid pen sample
// FALSE : Invalid pen sample
INT Filter_Margin;
static int count = 0;
static INT x[2], y[2];
INT TmpX, TmpY;
INT dx, dy;
if(*px <0 && *py <0)
{
count = 0;
return FALSE;
}
else
{
count++;
}
if (count > 2)
{
// apply filtering rule
count = 2;
// average between x,y[0] and *px,y
TmpX = (x[0] + *px)>>1;
TmpY = (y[0] + *py)>>1;
// difference between x,y[1] and TmpX,Y
dx = (x[1] > TmpX) ? (x[1] - TmpX) : (TmpX - x[1]);
dy = (y[1] > TmpY) ? (y[1] - TmpY) : (TmpY - y[1]);
Filter_Margin = (x[1] > x[0]) ? (x[1]-x[0]) : (x[0]-x[1]);
Filter_Margin += (y[1] > y[0]) ? (y[1]-y[0]) : (y[0]-y[1]);
Filter_Margin += TSP_FILTER_LIMIT;
if ((dx > Filter_Margin) || (dy > Filter_Margin)) {
// Invalid pen sample
*px = x[1];
*py = y[1]; // previous valid sample
RetVal = FALSE;
count = 0;
}
else
{
// Valid pen sample
x[0] = x[1]; y[0] = y[1];
x[1] = *px; y[1] = *py; // reserve pen samples
RetVal = TRUE;
}
}
else // (count > 2)
{ // till 2 samples, no filtering rule
x[0] = x[1]; y[0] = y[1];
x[1] = *px; y[1] = *py; // reserve pen samples
RetVal = FALSE; // <- TRUE jylee 2003.03.04
}
return RetVal;
}
现在测试2440 的触摸屏,我们会惊奇的发现,真的没有天外飞仙跳点了,不过又引入了一个新的问题,触摸屏抖动!以前的那种写法采样时间间隔短,数据集中,是不会抖动的,现在数据差异大,触摸屏抖动的相当的厉害了!怎么办呢?这个时候增大采样次数求平均值会有一些效果,不过还是不能完全消除抖动的!现在就要用一个简单的算法了:就是采样八个点,然后从小到大排序之后,把最大和最小值去掉,因为这两个值通常都是在受力不均的时候产生的,不是真实的值,所以丢了,再求剩余几个点的平均值,这样就可以完美的消除触摸屏抖动了,下面贴出代码,希望大家也来改进一下。
PRIVATE BOOL
TSP_GetXY(INT *px, INT *py)
{
int i,j,k,temp;
//INT xsum, ysum;
//int x, y;
int dx, dy;
int x[TSP_SAMPLE_NUM], y[TSP_SAMPLE_NUM];
//xsum = ysum = 0;
EnterCriticalSection(&g_csTouchADC);
for (i = 0; i < TSP_SAMPLE_NUM; i++)
{
v_pADCregs->ADCTSC = (0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(1<<3)|(1<<2)|(0);
v_pADCregs->ADCCON |= (1 << 0); /* Start Auto conversion */
while (v_pADCregs->ADCCON & 0x1); /* check if Enable_start is low */
while (!(v_pADCregs->ADCCON & (1 << 15))); /* Check ECFLG */
x[i] = (0x3ff & v_pADCregs->ADCDAT1);
y[i] = 0x3ff - (0x3ff & v_pADCregs->ADCDAT0);
//x[i] = D_XPDATA_MASK(v_pADCregs->ADCDAT1);
//y[i] = D_YPDATA_MASK(v_pADCregs->ADCDAT0);
//xsum += x;
//ysum += y;
}
//*px = xsum / TSP_SAMPLE_NUM;
//*py = ysum / TSP_SAMPLE_NUM;
v_pADCregs->ADCTSC = (1<<8)|(1<<7)|(1<<6)|(0<<5)|(1<< 4)|(0<<3)|(0<<2)|(3);
LeaveCriticalSection(&g_csTouchADC);
//--------------------------------------------------------------
// if mask it ,very tremble work not well
for (j = 0; j < TSP_SAMPLE_NUM -1; ++j)
{
for (k = j+1; k < TSP_SAMPLE_NUM; ++k)
{
if(x[j]>x[k])
{
temp = x[j];
x[j]=x[k];
x[k]=temp;
}
if(y[j]>y[k])
{
temp = y[j];
y[j]=y[k];
y[k]=temp;
}
}
}
//dx = (*px > x) ? (*px - x) : (x - *px);
//dy = (*py > y) ? (*py - y) : (y - *py);
*px = (x[2] + ((x[3]+x[4])<<1) + (x[3]+x[4]) + x[5]);
*py = (y[2] + ((y[3]+y[4])<<1) + (y[3]+y[4]) + y[5]);
if ((*px & 0x7) > 3)
*px = (*px>>3) + 1;
else *px = *px>>3;
if ((*py & 0x7) > 3)
*py = (*py>>3) + 1;
else *py = *py>>3;
dx = x[5] - x[2];
dy = y[5] - y[2];
return ((dx > TSP_INVALIDLIMIT || dy > TSP_INVALIDLIMIT) ? FALSE : TRUE);
}
好了,方法就是这么多了,This is it ,下面贴出效果图,收工!


wince 2440 完美解决触摸屏跳点抖动源码
http://www.gooogleman.com/forum.php?mod=viewthread&tid=507&fromuid=3
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
PUBLIC VOID
DdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS * pTipStateFlags,
INT * pUncalX,
INT * pUncalY)
{
static INT x, y;
if (v_pINTregs->SUBSRCPND & (1<<IRQ_SUB_TC)) /* SYSINTR_TOUCH Interrupt Case*/
{
*pTipStateFlags = TouchSampleValidFlag;
if ( (v_pADCregs->ADCDAT0 & (1 << 15)) |
(v_pADCregs->ADCDAT1 & (1 << 15)) )
{
bTSP_DownFlag = FALSE;
DEBUGMSG(ZONE_TIPSTATE, (TEXT("up\r\n")));
v_pADCregs->ADCTSC &= 0xff;
*pUncalX = x;
*pUncalY = y;
TSP_SampleStop();
// Test
RETAILMSG(1,(TEXT("bTSP_DownFlag = FALSE...PenUP!!!\r\n")));
}
else
{
bTSP_DownFlag = TRUE;
if (!TSP_GetXY(&x, &y))
*pTipStateFlags = TouchSampleIgnore;
TSP_TransXY(&x, &y);
*pUncalX = x;
*pUncalY = y;
*pTipStateFlags |= TouchSampleDownFlag;
//Test
RETAILMSG(1,(TEXT("bTSP_DownFlag = TRUE...PenDown!!!\r\n")));
TSP_SampleStart();
}
v_pINTregs->SUBSRCPND = (1<<IRQ_SUB_TC);
v_pINTregs->INTSUBMSK &= ~(1<<IRQ_SUB_TC);
InterruptDone(gIntrTouch);
}
else /* SYSINTR_TOUCH_CHANGED Interrupt Case */
{
// TSP_SampleStart();
if (bTSP_DownFlag)
{
INT tx, ty;
INT dx, dy;
if (!TSP_GetXY(&tx, &ty))
*pTipStateFlags = TouchSampleIgnore;
else
{
RETAILMSG(1,(TEXT("bTSP_DownFlag = TRUE.PenDown!!!IRQ_Timer3 Interrupt\r\n")));
TSP_TransXY(&tx, &ty);
// insert by mostek@dstcorp.com
#define X_ERRV 0x3bf
#define Y_ERRV 0x4ff
if ((tx == X_ERRV) && (ty == Y_ERRV))
{
tx = x;
ty = y;
}
// =================== mostek
dx = (tx > x) ? (tx - x) : (x - tx);
dy = (ty > y) ? (ty - y) : (y - ty);
if (dx > TSP_CHANGE || dy > TSP_CHANGE)
{
*pUncalX = x = tx;
*pUncalY = y = ty;
//DEBUGMSG(ZONE_TIPSTATE, (TEXT("down-c-v %x %x\r\n"), x, y));
*pTipStateFlags = TouchSampleValidFlag | TouchSampleDownFlag;
}
else
{
*pUncalX = x;
*pUncalY = y;
DEBUGMSG(ZONE_TIPSTATE, (TEXT("down-c %x %x\r\n"), x, y));
*pTipStateFlags = TouchSampleIgnore;
}
}
}
else
{
*pTipStateFlags = TouchSampleIgnore;
TSP_SampleStop();
RETAILMSG(1,(TEXT("bTSP_DownFlag = FALSE.PenDown!!!IRQ_Timer3 Interrupt\r\n")));
}
InterruptDone(gIntrTouchChanged);
}
// add by wogo at2009.03.23 why?
SetEvent(hEventTouchInput);
}

浙公网安备 33010602011771号