• 【原创】彻底解决2440触摸屏跳点以及抖动问题


     

    // 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);
    }
    
    
    

    //-------------------------------------------------------------------------------------------------
  • 相关阅读:
    移动终端app测试点总结
    Appium+Java(一) Windows环境搭建篇
    BeanShell用法汇总(部分摘抄至网络)【转】
    JVM的GC实现详解
    JVM的GC理论详解
    JVM的栈内存
    JVM的基本结构
    JVM的生命周期
    JVM的启动流程
    JVM的粗略简述
  • 原文地址:https://www.cnblogs.com/gooogleman/p/1881017.html
Copyright © 2020-2023  润新知