彻底解决2440/2410触摸屏跳点以及抖动问题

来源:互联网 发布:北微传感器 淘宝 编辑:程序博客网 时间:2024/03/29 16:16
 

一位CSDN牛人的详尽触摸屏校正方法

多个LCD下修改DISPLAY与TOUCHP驱动的经验

首先说明,我所做的是基于s3c2410的wince平台。
更换LCD之后一般需要修改DISPLAY与TOUCHP驱动。建议大家把公共一些宏提取出来,独立写个头文件使用。需要参考的文件除了2个驱动对应的c/cpp文件还有s2410.h。cfw.c里面也有关于LCD的问题。如果你有对他做了修改,那么自己需要注意了。我之前自己的包就是。

 

我提取的部分信息:
... ... ...
#define LCD_TYPE  TFT640_480
#if ( LCD_TYPE == TFT640_480 )
  #define SRC_WIDTH           (640)
  #define SRC_HEIGHT          (480)
  #define MemSize             (0xA0000)
  #define LCD_XSIZE_TFT       (SRC_WIDTH)    
  #define LCD_YSIZE_TFT       (SRC_HEIGHT)
  //触摸区域修改下面的值
  #define TOUCH_MAX_X 1080
  #define TOUCH_MIN_X 10
  #define TOUCH_MAX_Y 980
  #define TOUCH_MIN_Y 30

  #define TOUCH_X SRC_WIDTH          
  #define TOUCH_Y SRC_HEIGHT

  //屏幕显示时隙设置 参考LCD厂商给出的资料 
  #define VBPD                ((20) & 0xff)
  #define VFPD                ((2)  & 0xff)
  #define VSPW                ((1)  & 0x3f)

  #define HBPD                ((121) & 0x7f)
  #define HFPD                ((15)  & 0xff)
  #define HSPW                ((13)  & 0xff)

  //#define ADC_DELAY_TIME 5000   看你具体情况我独立放开来,因为有好几种液晶。
#elif (...)
... ... ...
#endif
... ... ...
以后不管什么LCD需要处理,直接修改LCD_TYPE就行了。如果你跟我一样,同种大小也有几种不同厂商提供的LCD,那么你还需要定义一个宏来区分厂商的,写好以后需要换就修改1-2个宏的值就可以了,同时提取出来的宏再原来的文件中记得注释掉,免得重定义。不要去覆盖好几个地方。当然这样或许不完美,还存在触摸需要校正的问题。下面再说说我的做法。

1.首先拿到LCD,烧完让他跑起来。
2.用wince自带的校正程序校正。然后用PB或者EVC的工具连接wince的注册表。找到下面对应的值。
[HKEY_LOCAL_MACHINE/HARDWARE/DEVICEMAP/TOUCH]
"CalibrationData"="这里每人的值都不一样"
在$(_FLATRELEASEDIR)目录下的platform.reg里面找到“[HKEY_LOCAL_MACHINE/HARDWARE/DEVICEMAP/TOUCH]”
修改"CalibrationData"的值为找到的。然后make一下。重新写进去测试。
这个时候特别需要测试的是屏蔽的边缘的触摸效果,如果正常,那么恭喜你,可以了。如果边缘有问题,进行下一步3。
3.修改触摸区域。
  #define TOUCH_MAX_X 
  #define TOUCH_MIN_X 
  #define TOUCH_MAX_Y 
  #define TOUCH_MIN_Y 
调整这个区域(一般我见到的情况是边缘没反映或者点击后效果靠中心,所以把区域放到就行)。然后转1再进行测试。(个人出现过边缘无反应后解决,故与将校准放一起)

一般几步就OK了。
最后记得把CalibrationData的值保存起来放到platform.reg里面,以后如果更换LCD,那么直接修改platform.reg文件,把对应的值放出来,其他的注释调编译一下就可以了。根本不需要再校正。

以上转自:http://blog.csdn.net/gooogleman/article/details/3191875

 

// Topic:彻底解决2440触摸屏跳点问题

//作者:gooogleman

//版权:桂林电子科技大学一系科协wogoyixikexie@gliet.gooogleman

//平台:wince5.0 2440 5.0 BSP(飞凌FL2440开发板)

//发布日期: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 代码,希望大家有帮助。

view source
print?
001/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
002  
003  
004  
005PUBLIC VOID
006DdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS * pTipStateFlags,
007                       INT * pUncalX,
008                       INT * pUncalY)
009{
010    staticINTx, y;
011    intTmpX = 0;
012    intTmpY = 0;
013  
014    if(v_pINTregs->SUBSRCPND & (1<<IRQ_SUB_TC))      /* SYSINTR_TOUCH Interrupt Case*/
015    {
016        *pTipStateFlags = TouchSampleValidFlag;
017  
018        if( (v_pADCregs->ADCDAT0 & (1 << 15)) |
019             (v_pADCregs->ADCDAT1 & (1 << 15)) )
020        {
021            bTSP_DownFlag = FALSE;
022  
023            DEBUGMSG(ZONE_TIPSTATE, (TEXT("up/r/n")));
024  
025            v_pADCregs->ADCTSC &= 0xff;
026  
027            *pUncalX = x;
028            *pUncalY = y;
029  
030            TSP_SampleStop();
031            // Test
032              
033            RETAILMSG(1,(TEXT("bTSP_DownFlag = FALSE...PenUP!!!/r/n")));
034        }
035        else 
036        {
037            bTSP_DownFlag = TRUE;
038  
039            //if (!TSP_GetXY(&x, &y)) 
040            //  *pTipStateFlags = TouchSampleIgnore;
041  
042            //TSP_TransXY(&x, &y);
043  
044            //-----------------------add @2010.09.11-----------------------
045            *pTipStateFlags |= TouchSampleIgnore;
046  
047            *pUncalX = x;
048            *pUncalY = y;
049  
050            *pTipStateFlags |= TouchSampleDownFlag;
051  
052            //Test          
053            RETAILMSG(1,(TEXT("bTSP_DownFlag = TRUE...PenDown!!!/r/n")));
054  
055            TSP_SampleStart();
056        }
057  
058        v_pINTregs->SUBSRCPND  =  (1<<IRQ_SUB_TC);
059        v_pINTregs->INTSUBMSK &= ~(1<<IRQ_SUB_TC);
060  
061        InterruptDone(gIntrTouch);
062    }
063    else       /* SYSINTR_TOUCH_CHANGED Interrupt Case     */
064    {
065//      TSP_SampleStart();
066          
067        if(bTSP_DownFlag)
068        {
069            if(TSP_GetXY(&TmpX, &TmpY) == TRUE)
070            {
071                //TSP_TransXY(&TmpX, &TmpY);
072  
073                if(Touch_Pen_Filtering(&TmpX, &TmpY))
074                {
075                    *pTipStateFlags = TouchSampleValidFlag | TouchSampleDownFlag;
076                    *pTipStateFlags &= ~TouchSampleIgnore;
077                }
078                else       // Invalid touch pen
079                {
080                    *pTipStateFlags = TouchSampleValidFlag;
081                    *pTipStateFlags |= TouchSampleIgnore;
082                }
083  
084                *pUncalX = x = TmpX;
085                *pUncalY = y = TmpY;
086            }
087            else
088            {
089                *pTipStateFlags = TouchSampleIgnore;
090            }
091        }
092        else
093        {
094            *pTipStateFlags = TouchSampleIgnore;
095  
096            TSP_SampleStop();
097              
098            RETAILMSG(1,(TEXT("bTSP_DownFlag = FALSE.PenDown!!!IRQ_Timer3 Interrupt/r/n")));
099        }
100  
101        InterruptDone(gIntrTouchChanged);
102    }
103  
104    // add by wogo at2009.03.23 why?
105    SetEvent(hEventTouchInput);
106}
107  
108  
109  
110staticBOOL
111Touch_Pen_Filtering(INT*px,INT*py)
112{
113    BOOLRetVal = TRUE;
114    // TRUE  : Valid pen sample
115    // FALSE : Invalid pen sample
116    INTFilter_Margin;
117    staticintcount = 0;
118    staticINTx[2], y[2];
119    INTTmpX, TmpY;
120    INTdx, dy;
121  
122    if(*px <0 && *py <0)
123    {
124        count = 0;
125        returnFALSE;
126    }
127    else
128    {
129        count++;
130    }
131  
132    if(count > 2)
133    {
134        // apply filtering rule
135        count = 2;
136  
137        // average between x,y[0] and *px,y
138        TmpX = (x[0] + *px)>>1;
139        TmpY = (y[0] + *py)>>1;
140  
141        // difference between x,y[1] and TmpX,Y
142        dx = (x[1] > TmpX) ? (x[1] - TmpX) : (TmpX - x[1]);
143        dy = (y[1] > TmpY) ? (y[1] - TmpY) : (TmpY - y[1]);
144  
145        Filter_Margin = (x[1] > x[0]) ? (x[1]-x[0]) : (x[0]-x[1]);
146        Filter_Margin += (y[1] > y[0]) ? (y[1]-y[0]) : (y[0]-y[1]);
147        Filter_Margin += TSP_FILTER_LIMIT;
148  
149        if((dx > Filter_Margin) || (dy > Filter_Margin)) {
150            // Invalid pen sample
151            *px = x[1];
152            *py = y[1];// previous valid sample
153            RetVal = FALSE;
154            count = 0;
155        }
156        else
157        {
158            // Valid pen sample
159            x[0] = x[1]; y[0] = y[1];
160            x[1] = *px; y[1] = *py;// reserve pen samples
161  
162            RetVal = TRUE;
163        }
164    }
165    else// (count > 2)
166    { // till 2 samples, no filtering rule
167        x[0] = x[1]; y[0] = y[1];
168        x[1] = *px; y[1] = *py;// reserve pen samples
169  
170        RetVal = FALSE;   // <- TRUE jylee 2003.03.04
171    }
172  
173    returnRetVal;
174  
175}

 

  现在测试2440 的触摸屏,我们会惊奇的发现,真的没有天外飞仙跳点了,不过又引入了一个新的问题,触摸屏抖动!以前的那种写法采样时间间隔短,数据集中,是不会抖动的,现在数据差异大,触摸屏抖动的相当的厉害了!怎么办呢?这个时候增大采样次数求平均值会有一些效果,不过还是不能完全消除抖动的!现在就要用一个简单的算法了:就是采样八个点,然后从小到大排序之后,把最大和最小值去掉,因为这两个值通常都是在受力不均的时候产生的,不是真实的值,所以丢了,再求剩余几个点的平均值,这样就可以完美的消除触摸屏抖动了,下面贴出代码,希望大家也来改进一下。

view source
print?
01PRIVATE BOOL
02TSP_GetXY(INT*px,INT*py)
03{
04    inti,j,k,temp;
05    //INT xsum, ysum;
06    //int x, y;
07    intdx, dy;
08    intx[TSP_SAMPLE_NUM], y[TSP_SAMPLE_NUM];
09  
10    //xsum = ysum = 0;
11    EnterCriticalSection(&g_csTouchADC);
12    for(i = 0; i < TSP_SAMPLE_NUM; i++)
13    {
14        v_pADCregs->ADCTSC = (0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(1<<3)|(1<<2)|(0);         
15        v_pADCregs->ADCCON |= (1 << 0);               /* Start Auto conversion                */
16  
17        while(v_pADCregs->ADCCON & 0x1);               /* check if Enable_start is low         */
18        while(!(v_pADCregs->ADCCON & (1 << 15)));    /* Check ECFLG                          */
19  
20        x[i] = (0x3ff & v_pADCregs->ADCDAT1);
21        y[i] = 0x3ff - (0x3ff & v_pADCregs->ADCDAT0);
22  
23        //x[i] = D_XPDATA_MASK(v_pADCregs->ADCDAT1);
24        //y[i] = D_YPDATA_MASK(v_pADCregs->ADCDAT0);
25        //xsum += x;
26        //ysum += y;
27    }
28      
29    //*px = xsum / TSP_SAMPLE_NUM;
30    //*py = ysum / TSP_SAMPLE_NUM;
31  
32    v_pADCregs->ADCTSC = (1<<8)|(1<<7)|(1<<6)|(0<<5)|(1<< 4)|(0<<3)|(0<<2)|(3);    
33  
34      
35    LeaveCriticalSection(&g_csTouchADC);
36  
37    //--------------------------------------------------------------
38    // if mask it ,very tremble work not well
39    for(j = 0; j < TSP_SAMPLE_NUM -1; ++j)
40    {
41        for(k = j+1; k < TSP_SAMPLE_NUM; ++k)
42        {
43            if(x[j]>x[k])
44            {
45                temp = x[j];
46                x[j]=x[k];
47                x[k]=temp;
48            }
49  
50            if(y[j]>y[k])
51            {
52                temp = y[j];
53                y[j]=y[k];
54                y[k]=temp;
55            }
56        }
57    }
58  
59    //dx = (*px > x) ? (*px - x) : (x - *px);
60    //dy = (*py > y) ? (*py - y) : (y - *py);
61      
62    *px = (x[2] + ((x[3]+x[4])<<1) + (x[3]+x[4]) + x[5]);
63    *py = (y[2] + ((y[3]+y[4])<<1) + (y[3]+y[4]) + y[5]);
64      
65    if((*px & 0x7) > 3) 
66        *px = (*px>>3) + 1;
67    else*px = *px>>3;
68      
69    if((*py & 0x7) > 3) 
70        *py = (*py>>3) + 1;
71    else*py = *py>>3;
72  
73    dx = x[5] - x[2];
74    dy = y[5] - y[2];
75  
76    return((dx > TSP_INVALIDLIMIT || dy > TSP_INVALIDLIMIT) ? FALSE : TRUE);
77}

 

  好了,方法就是这么多了,This is it ,下面贴出效果图,收工!

wince 2440 完美解决触摸屏跳点抖动源码
http://www.gooogleman.com/forum.php?mod=viewthread&tid=507&fromuid=3

转载请标明:作者gooogleman(gooogleman邮箱:wogoyixikexie@gmail.com)桂林电子科技大学一系科协(博客http://blog.csdn.net/gooogleman、http://www.cnblogs.com/gooogleman/、http://www.gooogleman.com)如有错误,或者你有更加好的方法请在博客文章后留言指出,gooogleman会感激你的批评和分享。

view source
print?
001/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
002/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
003  
004  
005  
006PUBLIC VOID
007DdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS * pTipStateFlags,
008                       INT * pUncalX,
009                       INT * pUncalY)
010{
011    staticINTx, y;
012  
013    if(v_pINTregs->SUBSRCPND & (1<<IRQ_SUB_TC))      /* SYSINTR_TOUCH Interrupt Case*/
014    {
015        *pTipStateFlags = TouchSampleValidFlag;
016  
017        if( (v_pADCregs->ADCDAT0 & (1 << 15)) |
018             (v_pADCregs->ADCDAT1 & (1 << 15)) )
019        {
020            bTSP_DownFlag = FALSE;
021  
022            DEBUGMSG(ZONE_TIPSTATE, (TEXT("up/r/n")));
023  
024            v_pADCregs->ADCTSC &= 0xff;
025  
026            *pUncalX = x;
027            *pUncalY = y;
028  
029            TSP_SampleStop();
030            // Test
031              
032            RETAILMSG(1,(TEXT("bTSP_DownFlag = FALSE...PenUP!!!/r/n")));
033        }
034        else 
035        {
036            bTSP_DownFlag = TRUE;
037  
038            if(!TSP_GetXY(&x, &y)) 
039                *pTipStateFlags = TouchSampleIgnore;
040  
041            TSP_TransXY(&x, &y);
042  
043            *pUncalX = x;
044            *pUncalY = y;
045  
046            *pTipStateFlags |= TouchSampleDownFlag;
047  
048            //Test          
049            RETAILMSG(1,(TEXT("bTSP_DownFlag = TRUE...PenDown!!!/r/n")));
050  
051            TSP_SampleStart();
052        }
053  
054        v_pINTregs->SUBSRCPND  =  (1<<IRQ_SUB_TC);
055        v_pINTregs->INTSUBMSK &= ~(1<<IRQ_SUB_TC);
056  
057        InterruptDone(gIntrTouch);
058    }
059    else       /* SYSINTR_TOUCH_CHANGED Interrupt Case     */
060    {
061//      TSP_SampleStart();
062          
063        if(bTSP_DownFlag)
064        {
065            INT tx, ty;
066            INT dx, dy;
067  
068            if(!TSP_GetXY(&tx, &ty)) 
069                *pTipStateFlags = TouchSampleIgnore;
070            else 
071            {
072                  
073                RETAILMSG(1,(TEXT("bTSP_DownFlag = TRUE.PenDown!!!IRQ_Timer3 Interrupt/r/n")));
074                TSP_TransXY(&tx, &ty);
075// insert by mostek@dstcorp.com
076#define X_ERRV  0x3bf
077#define Y_ERRV  0x4ff
078  
079                if((tx == X_ERRV) && (ty == Y_ERRV))
080                {
081                    tx = x;
082                    ty = y;
083                
084// =================== mostek
085                dx = (tx > x) ? (tx - x) : (x - tx);
086                dy = (ty > y) ? (ty - y) : (y - ty);
087  
088                if(dx > TSP_CHANGE || dy > TSP_CHANGE)
089                {
090                    *pUncalX = x = tx;
091                    *pUncalY = y = ty;
092  
093                    //DEBUGMSG(ZONE_TIPSTATE, (TEXT("down-c-v %x %x/r/n"), x, y));
094                    *pTipStateFlags = TouchSampleValidFlag | TouchSampleDownFlag;
095                }
096                else
097                {
098                    *pUncalX = x;
099                    *pUncalY = y;
100  
101                    DEBUGMSG(ZONE_TIPSTATE, (TEXT("down-c %x %x/r/n"), x, y));
102  
103                    *pTipStateFlags = TouchSampleIgnore;
104                }
105            }
106        }
107        else
108        {
109            *pTipStateFlags = TouchSampleIgnore;
110  
111            TSP_SampleStop();
112              
113            RETAILMSG(1,(TEXT("bTSP_DownFlag = FALSE.PenDown!!!IRQ_Timer3 Interrupt/r/n")));
114        }
115  
116        InterruptDone(gIntrTouchChanged);
117    }
118  
119    // add by wogo at2009.03.23 why?
120    SetEvent(hEventTouchInput);
121}
个人在处理去抖过程中参考网上,将阀值FILTER_LIMIT 相应减小,即剔除差值过大采样点,同时采样次数,多次求值等是关键,同时可能是硬件本身问题,在实验过程中,更换新的触摸层,触摸效果明显变好。
本文出自:http://blog.csdn.net/gooogleman/article/details/6036531
原创粉丝点击