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

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

 

 

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

// 作者:gooogleman

// 版权:桂林电子科技大学一系科协[email protected]

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

view source
print ?
01 PRIVATE BOOL
02 TSP_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 ,下面贴出效果图,收工!

彻底解决2440触摸屏跳点以及抖动问题_第1张图片

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

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

view source
print ?
001 /* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
002 /* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
003   
004   
005   
006 PUBLIC VOID
007 DdsiTouchPanelGetPoint(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 [email protected]
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 }

 

 

//-------------------------------------------------------------------------------------------------

你可能感兴趣的:(算法,timer,filter,insert,WinCE,2010)