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

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

001/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
002  
003  
004  
005PUBLIC VOID
006DdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS * pTipStateFlags,
007                       INT  * pUncalX,
008                       INT  * pUncalY)
009{
010    static INT x, y;
011    int TmpX = 0;
012    int TmpY = 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  
110static BOOL
111Touch_Pen_Filtering(INT *px, INT *py)
112{
113    BOOL RetVal = TRUE;
114    // TRUE  : Valid pen sample
115    // FALSE : Invalid pen sample
116    INT Filter_Margin;
117    static int count = 0;
118    static INT x[2], y[2];
119    INT TmpX, TmpY;
120    INT dx, dy;
121  
122    if(*px <0 && *py <0)
123    {
124        count = 0;
125        return FALSE;
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    return RetVal;
174  
175}

 

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

01PRIVATE BOOL
02TSP_GetXY(INT *px, INT *py)
03{
04    int i,j,k,temp;
05    //INT xsum, ysum;
06    //int x, y;
07    int dx, dy;
08    int x[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会感激你的批评和分享。

001/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
002/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
003  
004  
005  
006PUBLIC VOID
007DdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS * pTipStateFlags,
008                       INT  * pUncalX,
009                       INT  * pUncalY)
010{
011    static INT x, 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}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值