徹底解決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 代碼,希望大家有幫助。

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 的觸摸屏,我們會驚奇的發現,真的沒有天外飛仙跳點了,不過又引入了一個新的問題,觸摸屏抖動!以前的那種寫法採樣時間間隔短,數據集中,是不會抖動的,現在數據差異大,觸摸屏抖動的相當的厲害了!怎麼辦呢?這個時候增大采樣次數求平均值會有一些效果,不過還是不能完全消除抖動的!現在就要用一個簡單的算法了:就是採樣八個點,然後從小到大排序之後,把最大和最小值去掉,因爲這兩個值通常都是在受力不均的時候產生的,不是真實的值,所以丟了,再求剩餘幾個點的平均值,這樣就可以完美的消除觸摸屏抖動了,下面貼出代碼,希望大家也來改進一下。

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 ,下面貼出效果圖,收工!

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會感激你的批評和分享。

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 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章