爰得太累的说说:ucos下10.4寸触摸屏的2440驱动算法与实现

来源:百度文库 编辑:偶看新闻 时间:2024/05/08 07:38:27

关于这个ucos搞了一个月了,最近3周左右的时间都耗在这个触摸屏的效准上,真是郁闷死洒家了,小弟数学不是很好,今天突然想起了一个测试算法,于是拿来实验,效果不错,先分享一下。网上关于触摸屏的资料很多,其中巨大部分多是小屏的,其算法也多为2点,3点效验,我都测试过,误差较大。关于五点效验的算法很少,我朋友说,触摸屏效验就是个线性函数的问题,但是我参看资料搞了一周多也没弄明白,搁浅了几天,上周末突然到一份资料里面提到的k = y / x 来确定是五点钟的那个区域的意思。但是这篇文字提供的关于系数的计算公式有点错误,在另外一篇英文文档里面提供了,详细的效验算法的分析,提供了正确的公式,结合两篇文字,浑浑噩噩,郁闷好几天的我,总算是搞清楚了。现提供部分源码如下,各位多指点一下。

Touch目录下的 GUI_TOUCH_DriverAnalog.c文件,添加修改如下

void myAD2XY( int *adx , int *ady ){
 f_dat = (float)(*ady - admy)/(float)(*adx - admx);
 if(f_dat>0){
  if( *adx>admx && admk[2] >=f_dat) dat1 = 1;
  else if( *adx>admx && admk[2] < f_dat ) dat1 =2;//2
  else if( *adx=f_dat ) dat1 =0;
  else if( *adx  else{ dat1 =0; }//*adx =0;*ady =0; }
 }else{
  if( *adx>admx && admk[1] >=f_dat) dat1 = 0;
  else if( *adx>admx && admk[1] < f_dat ) dat1 =1;//1
  else if( *adx=f_dat ) dat1 =3;
  else if( *adx  else{ dat1 =0; }//*adx =0;*ady =0; }
 }
 *adx = (int)(Factors[dat1][0].a*(*adx)+Factors[dat1][0].b*(*ady)+Factors[dat1][0].c);
 *ady = (int)(Factors[dat1][1].a*(*adx)+Factors[dat1][1].b*(*ady)+Factors[dat1][1].c);
}
void  GUI_TOUCH_Exec(void) {
  #ifndef WIN32
  static U32 i, saveAdcdly = 0;
  U32  point_adcx=0 , point_adcy=0 ;
  static int cs =0;
 static int  xPhys, yPhys ,x=0,y=0;
/*  if (xyMinMax[GUI_COORD_X].Min < xyMinMax[GUI_COORD_X].Max) {
    xMin = xyMinMax[GUI_COORD_X].Min;
    xMax = xyMinMax[GUI_COORD_X].Max;
  } else {
    xMax = xyMinMax[GUI_COORD_X].Min;
    xMin = xyMinMax[GUI_COORD_X].Max;
  }
  if (xyMinMax[GUI_COORD_Y].Min < xyMinMax[GUI_COORD_Y].Max) {
    yMin = xyMinMax[GUI_COORD_Y].Min;
    yMax = xyMinMax[GUI_COORD_Y].Max;
  } else {
    yMax = xyMinMax[GUI_COORD_Y].Min;
    yMin = xyMinMax[GUI_COORD_Y].Max;
  }
*/
  rINTSUBMSK|=(BIT_SUB_ADC|BIT_SUB_TC); // Mask sub interrupt (ADC and TC)
    if(rADCTSC&0x100)//rADCDAT0&0x8000)
    {
  rADCTSC&=0xff; // Set stylus down interrupt bit
  GUI_TOUCH_StoreState(-1,-1); 
    }else{
  rADCTSC = rADCTSC|(1<<3)|(1<<2);         //Pull-up disable, Seq. X,Y postion measure.
  saveAdcdly=rADCDLY;
  rADCDLY=40000;                 //Normal conversion mode delay about (1/50M)*40000=0.8ms
   for( i=0 ; i<8 ; i++){
   rADCCON|=0x1;                   //start ADC
   while(rADCCON & 0x1);  //check if Enable_start is low
   while(!(rADCCON & 0x8000));        //check if EC(End of Conversion) flag is high, This line is necessary~!!
           while(!(rSRCPND & (BIT_ADC)));  //check if ADC is finished with interrupt bit

   point_adcx = point_adcx + (rADCDAT0&0x3ff);
   point_adcy = point_adcy + (rADCDAT1&0x3ff);
  }
  xPhys =  point_adcx>>3;
  yPhys =  point_adcy>>3;
 #if !GUI_TOUCH_SWAP_XY  //Is X/Y swapped ?
       x = xPhys;
       y = yPhys;
      #else
       x = yPhys;
       y = xPhys;
      #endif
 for( i=0;i<50000;i++ );
 if ((x GUI_TOUCH_AD_RIGHT)  | (y GUI_TOUCH_AD_BOTTOM)) {
  //  if ((x xMax)  | (y yMax)) {
      GUI_TOUCH_StoreState(-1,-1);
    } else {
    if( cs<5 ){
    cs++;
     }else{
    //   x = AD2X(x);
    //   y = AD2Y(y);
       myAD2XY( &x ,&y );
     }
      GUI_TOUCH_StoreState(x,y);
    } 
 rADCDLY=saveAdcdly;
    rADCTSC=0xd3;  //Wfait,XP_PU,XP_Dis,XM_Dis,YP_Dis,YM_En   
 }

    rSUBSRCPND|=BIT_SUB_TC;
    rINTSUBMSK=~(BIT_SUB_TC); // Unmask sub interrupt (TC)    
    ClearPending(BIT_ADC); 

  #endif // WIN32
}

void GUI_myTOUCH_Calibrate(int *Logx, int *Logy, int *xPhys, int *yPhys){
 int move , mnext;
 admx = xPhys[4];
 admy = yPhys[4];
 
 for( move =0 ; move<4; move++ ){
  if( move == 3 ) mnext =0;
  else mnext = move +1;

  dat2 = yPhys[move] - yPhys[4];
  dat1 = xPhys[move] - xPhys[4];
  admk[move] = ((float)dat2/(float)dat1);
//  mk = admk[move] = (yPhys[move] - yPhys[4])/(xPhys[move] - xPhys[4]);
  
/*  dat = ((xPhys[move]-xPhys[4])*(yPhys[mnext]-yPhys[4]))-((xPhys[mnext]-xPhys[4])*(yPhys[move]-yPhys[4]));
 */
   dat1 =  xPhys[move]-xPhys[4];
  dat2 = yPhys[mnext]-yPhys[4];
  dat1 = dat1*dat2;
  dat3 = xPhys[mnext]-xPhys[4];
  dat2 = yPhys[move]-yPhys[4];
  dat3 = dat3*dat2;
  f_dat = (float)dat1-(float)dat3;
 
/* mk = Factors[move][0].a  = \
   (((Logx[move]-Logx[4])*(yPhys[mnext]-yPhys[4]))-((Logx[mnext]-Logx[4])*(yPhys[move]-yPhys[4])))/dat;
*/  dat1 = Logx[move]-Logx[4];
  dat2 = yPhys[mnext]-yPhys[4];
  dat1 = dat1*dat2;
  dat3 = Logx[mnext]-Logx[4];
  dat2 = yPhys[move]-yPhys[4];
  dat3 = dat2*dat3;
  dat1 = dat1-dat3;
  Factors[move][0].a = (float)dat1/f_dat;
 
/* mk = Factors[move][0].b = \
   ((Logx[mnext]-Logx[4])*(xPhys[move]-xPhys[4])-(Logx[move]-Logx[4])*(xPhys[mnext]-xPhys[4]))/dat;
*/  dat1 = Logx[mnext]-Logx[4];
  dat2 = xPhys[move]-xPhys[4];
  dat1 = dat1*dat2;
  dat3 = Logx[move]-Logx[4];
  dat2 = xPhys[mnext]-xPhys[4];
  dat3 = dat2*dat3;
  dat1 = dat1-dat3;
  Factors[move][0].b = (float)dat1/f_dat;
 
/* mk = Factors[move][0].c = (Logx[move]*(xPhys[mnext]*yPhys[4]-xPhys[4]*yPhys[mnext])\
        +Logx[mnext]*(xPhys[move]*yPhys[4]-xPhys[4]*yPhys[move])\
        +Logx[4]*(xPhys[move]*yPhys[mnext]-xPhys[mnext]*yPhys[move]))/dat;
*/  dat1 = xPhys[mnext]*yPhys[4]-xPhys[4]*yPhys[mnext];
  dat1 = Logx[move]*dat1;
  dat2 = xPhys[move]*yPhys[4]-xPhys[4]*yPhys[move];
  dat2 = dat2*Logx[mnext];
  dat3 = xPhys[move]*yPhys[mnext]-xPhys[mnext]*yPhys[move];
  dat3 = dat3*Logx[4];
  dat1 = dat1-dat2+dat3;
  Factors[move][0].c = (float)dat1/f_dat;
 
/* mk = Factors[move][1].a  = \
   ((Logy[move]-Logy[4])*(yPhys[mnext]-yPhys[4])-(Logy[mnext]-Logy[4])*(yPhys[move]-yPhys[4]))/dat;
*/  dat1 = Logy[move]-Logy[4];
  dat2 = yPhys[mnext]-yPhys[4];
  dat1 = dat1*dat2;
  dat3 = Logy[mnext]-Logy[4];
  dat2 = yPhys[move]-yPhys[4];
  dat3 = dat2*dat3;
  dat1 = dat1-dat3;
  Factors[move][1].a = (float)dat1/f_dat;
 
/* mk = Factors[move][1].b = \
  ((xPhys[move]-xPhys[4])*(Logy[mnext]-Logy[4])-(xPhys[mnext]-xPhys[4])*(Logy[move]-Logy[4]))/dat;
*/  dat1 = xPhys[move]-xPhys[4];
  dat2 = Logy[mnext]-Logy[4];
  dat1 = dat1*dat2;
  dat3 = xPhys[mnext]-xPhys[4];
  dat2 = Logy[move]-Logy[4];
  dat3 = dat3*dat2;
  dat1 = dat1-dat3;
  Factors[move][1].b = (float)dat1/f_dat;
 
/* mk = Factors[move][1].c  = (Logy[move]*(xPhys[mnext]*yPhys[4]-xPhys[4]*yPhys[mnext])\
     +Logy[mnext]*(xPhys[move]*yPhys[4]-xPhys[4]*yPhys[move])\
     +Logy[4]*(xPhys[move]*yPhys[mnext]-xPhys[mnext]*yPhys[move]))/dat;
*/  dat1 = xPhys[mnext]*yPhys[4]-xPhys[4]*yPhys[mnext];
  dat1 = Logy[move]*dat1;
  dat2 = xPhys[move]*yPhys[4]-xPhys[4]*yPhys[move];
  dat2 = Logy[mnext]*dat2;
  dat3 = xPhys[move]*yPhys[mnext]-xPhys[mnext]*yPhys[move];
  dat3 = Logy[4]*dat3;
  dat1 = dat1-dat2+dat3;
  Factors[move][1].c = (float)dat1/f_dat;  
   
 }
}

GUIDemo目录下GUIDEMO_Touch.c文件,修改如下:

extern void GUI_myTOUCH_Calibrate(int *Logx, int *Logy, int *xPhys, int *yPhys);

void _ExecCalibration(void) {
  int ax_Phys[5],ay_Phys[5];
  int move;
/* calculate log. Positions */
  int ax[5] = { 50, LCD_XSIZE-50, LCD_XSIZE-50, 50, (LCD_XSIZE/2)-10};
  int ay[5] = { 50, 50, LCD_YSIZE-50, LCD_YSIZE-50, (LCD_YSIZE/2)-10};

//  int ax[5] = { 120, LCD_XSIZE-120, LCD_XSIZE-120, 120, 400};
//  int ay[5] = { 20, 20, LCD_YSIZE-20, LCD_YSIZE-20, 300};

//  GUI_TOUCH_SetDefaultCalibration();
/* _Calibrate upper left */
 for( move =0 ; move<5; move++){
  GUI_SetBkColor(GUI_RED); 
  GUI_Clear();
  GUI_SetColor(GUI_WHITE);  GUI_FillCircle(ax[move], ay[move], 10);
  GUI_SetColor(GUI_RED);    GUI_FillCircle(ax[move], ay[move], 5);
  GUI_SetColor(GUI_WHITE);
  do {
   GUI_TOUCH_tState State;
   GUI_TOUCH_GetState(&State);
   if (State.Pressed) {
   ax_Phys[move] = State.x;//GUI_TOUCH_GetxPhys();
   ay_Phys[move] = State.y;//GUI_TOUCH_GetyPhys();
   break;
   }
      GUI_Delay (100);
    } while (1); 
  GUI_Delay (50);
/*  release */
  GUI_TOUCH_StoreState(-1,-1); 
 }

 GUI_myTOUCH_Calibrate(ax,ay,ax_Phys,ay_Phys);
    GUI_Delay(100);
    GUI_DispStringAt  ("Please touch display to continue...",50,20);
    GUI_TOUCH_StoreState(-1,-1); 

    do {
      GUI_TOUCH_tState State;
      GUI_TOUCH_GetState(&State);
      if (State.Pressed)
        break;
      GUI_Delay (10);
    } while (1);
}
这样就ok了,