END12345678 发表于 2009-8-2 17:50:36

关于触摸屏校正算法,大家支支招,最近买了个触摸屏,想做个校正

关于触摸屏校正算法,大家支支招,最近买了个触摸屏,想做个校正。
自己做的程序不够精准,谢谢

ivws 发表于 2009-8-2 17:52:41

关注中。。。。

END12345678 发表于 2009-8-2 17:58:47

似乎wince内核中自带有校正算法,
我现在是直接用单片机来控制触摸屏,

END12345678 发表于 2009-8-2 18:44:32

沉的好快啊

junmadianzi 发表于 2009-8-2 19:39:11

我看到的做法是,左上角一点,右下角一点,测试后提问是否重设

bad_fpga 发表于 2009-8-2 19:52:24

以前不知在哪下载的,没试过,你看看行不行
触摸屏校准原理ourdev_466645.rar(文件大小:92K) (原文件名:触摸屏校准原理.rar)

avrtyx 发表于 2009-8-3 10:55:08

这里有程序 http://www.poweravr.com/bbs/viewthread.php?tid=231   LCD和触摸屏间的误差角度非常小 就可以用这个算法

xyq4513 发表于 2009-8-3 12:49:19

Mark

xixiangfeng 发表于 2010-8-28 23:47:44

高手解释一下这个算法流程...
#include <string.h>
#include "ads7843drv.h"
#include "stm32f10x_lib.h"

//====================================================================================

typedef          struct POINT
          {
          unsigned short x;
          unsigned short y;
          }coordinate;


typedef struct Matrix {
                                             
                     long double    An,
                                 Bn,   
                                 Cn,   
                                 Dn,   
                                 En,   
                                 Fn,   
                                 Divider ;
                     } matrix ;

void Delayus( int k)
{
    int j;
    for(j=k;j > 0;j--);   
}
//====================================================================================
void TP_Init(void)
{
   // IODIR1 = 0x00;
//IODIR1 = IODIR1 | MASK_CS | MASK_DCLK | MASK_DIN;
          GPIO_InitTypeDef GPIO_InitStructure;
      GPIO_InitStructure.GPIO_Pin =GPIO_Pin_4 | GPIO_Pin_5|GPIO_Pin_7;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;               //推挽输出
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
          GPIO_Init(GPIOA, &GPIO_InitStructure);
      GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0 | GPIO_Pin_1;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
      GPIO_Init(GPIOB, &GPIO_InitStructure);

}
//====================================================================================
static void WR_CMD (unsigned char cmd)
{
    unsigned char buf;
    unsigned char i;
    TP_CS(1);
    TP_DIN(0);
    TP_DCLK(0);
    TP_CS(0);
    for(i=0;i<8;i++)
    {
      buf=(cmd>>(7-i))&0x1;
      TP_DIN(buf);
      Delayus(5);
      TP_DCLK(1);
      Delayus(5);
      TP_DCLK(0);
    }
}
//====================================================================================
static unsigned short RD_AD(void)
{
    unsigned short buf=0,temp;
    unsigned char i;
    TP_DIN(0);
    TP_DCLK(1);
    for(i=0;i<12;i++)
    {
      Delayus(5);
      TP_DCLK(0);         
      Delayus(5);   
      temp= (TP_DOUT) ? 1:0;
      buf|=(temp<<(11-i));
      
      Delayus(5);
      TP_DCLK(1);
    }
    TP_CS(1);
    buf&=0x0fff;
    return(buf);
}
//====================================================================================
int Read_X(void)
{
    int i;
    WR_CMD(CHX);
   // while(TP_BUSY);
    Delayus(5);
    i=RD_AD();
    return i;   
}
//====================================================================================
int Read_Y(void)
{
    int i;
    WR_CMD(CHY);
    //while(TP_BUSY);
    Delayus(5);
    i=RD_AD();
    return i;   
}
//====================================================================================
void TP_GetAdXY(int *x,int *y)
{
    int adx,ady;
    adx=Read_X();
    ady=Read_Y();
    *x=adx;
    *y=ady;
}

void TP_DrawPoint(u8 x,u16 y)
{
      if(x>220&&y<12)
      {
                Lcd_Clear(0xffff);
      }else
      {
                DrawPixel(x,y,0xf800);//中心点
                DrawPixel(x+1,y,0xf800);
                DrawPixel(x,y+1,0xf800);
                DrawPixel(x+1,y+1,0xf800);      
      }                        
}
extern int TP_X,TP_Y;
#defineVALUE 3//差值
coordinate *Read_Ads7846(void)
{
    coordinateScreen ;
    int m0,m1,m2;
      u8 count=0;
      u16 databuffer={{0},{0}};//数据组
      u16 temp;      
    do                                          //循环读数9次
      {                  
            TP_GetAdXY(TP_X,TP_Y);
                        databuffer=TP_X;//X
                        databuffer=TP_Y;
                        count++;
      }
      while(count<9);
      if(count==9)//一定要读到9次数据,否则丢弃
      {
         temp=(databuffer+databuffer+databuffer)/3;
         temp=(databuffer+databuffer+databuffer)/3;
         temp=(databuffer+databuffer+databuffer)/3;
         m0=temp-temp;
         m1=temp-temp;
         m2=temp-temp;

         m0=m0>0?m0-m0);
         m1=m1>0?m1-m1);
         m2=m2>0?m2-m2);
         if(m0>VALUE&&m1>VALUE&&m2>VALUE) return 0;
         if(m0<m1){if(m2<m0) Screen.x=(temp+temp)/2;
                     else Screen.x=(temp+temp)/2;      }
         else if(m2<m1) Screen.x=(temp+temp)/2;
                     else Screen.x=(temp+temp)/2;



   temp=(databuffer+databuffer+databuffer)/3;
         temp=(databuffer+databuffer+databuffer)/3;
         temp=(databuffer+databuffer+databuffer)/3;
         m0=temp-temp;
         m1=temp-temp;
         m2=temp-temp;

         m0=m0>0?m0-m0);
         m1=m1>0?m1-m1);
         m2=m2>0?m2-m2);
         if(m0>VALUE&&m1>VALUE&&m2>VALUE) return 0;

         if(m0<m1){if(m2<m0) Screen.y=(temp+temp)/2;
                     else Screen.y=(temp+temp)/2;      }
         else if(m2<m1) Screen.y=(temp+temp)/2;
                     else Screen.y=(temp+temp)/2;
                  return &Screen;
                }
      return 0;
}
         

          //只有在LCD和触摸屏间的误差角度非常小时,才能运用上面公式
          //3个采样点必须不太靠近触摸屏边缘,他们的间隔必须足够大->
               

          //液晶屏上的采样点
coordinate ScreenSample =      {
                                          { 712, 911 },
                                                                                        { 3234, 898 },
                                          { 2318, 3058 }
                              } ;

         //LCD上 对应的点
coordinate DisplaySample =   {
                                          { 45, 45 },
                                                                                        { 45, 270},
                                          { 190,190}
                                    } ;
/*
定义2个变量
matrix matrix ;
coordinatedisplay ;

setCalibrationMatrix( &DisplaySample,&ScreenSample,&matrix ) ;//送入值得到参数         
getDisplayPoint(&display, Read_Ads7846(), &matrix ) ;
display.x display.y就是所的到的数字    */


unsigned char setCalibrationMatrix( coordinate * displayPtr,
                        coordinate * screenPtr,
                        matrix * matrixPtr)
{

    unsigned charretValue = 0 ;


   
    matrixPtr->Divider = ((screenPtr.x - screenPtr.x) * (screenPtr.y - screenPtr.y)) -
                         ((screenPtr.x - screenPtr.x) * (screenPtr.y - screenPtr.y)) ;

    if( matrixPtr->Divider == 0 )
    {
      retValue = 1;
    }
    else
    {
      matrixPtr->An = ((displayPtr.x - displayPtr.x) * (screenPtr.y - screenPtr.y)) -
                        ((displayPtr.x - displayPtr.x) * (screenPtr.y - screenPtr.y)) ;

      matrixPtr->Bn = ((screenPtr.x - screenPtr.x) * (displayPtr.x - displayPtr.x)) -
                        ((displayPtr.x - displayPtr.x) * (screenPtr.x - screenPtr.x)) ;

      matrixPtr->Cn = (screenPtr.x * displayPtr.x - screenPtr.x * displayPtr.x) * screenPtr.y +
                        (screenPtr.x * displayPtr.x - screenPtr.x * displayPtr.x) * screenPtr.y +
                        (screenPtr.x * displayPtr.x - screenPtr.x * displayPtr.x) * screenPtr.y ;

      matrixPtr->Dn = ((displayPtr.y - displayPtr.y) * (screenPtr.y - screenPtr.y)) -
                        ((displayPtr.y - displayPtr.y) * (screenPtr.y - screenPtr.y)) ;
   
      matrixPtr->En = ((screenPtr.x - screenPtr.x) * (displayPtr.y - displayPtr.y)) -
                        ((displayPtr.y - displayPtr.y) * (screenPtr.x - screenPtr.x)) ;

      matrixPtr->Fn = (screenPtr.x * displayPtr.y - screenPtr.x * displayPtr.y) * screenPtr.y +
                        (screenPtr.x * displayPtr.y - screenPtr.x * displayPtr.y) * screenPtr.y +
                        (screenPtr.x * displayPtr.y - screenPtr.x * displayPtr.y) * screenPtr.y ;
    }

    return( retValue ) ;
}

unsigned char getDisplayPoint(coordinate * displayPtr,
                     coordinate * screenPtr,
                     matrix * matrixPtr )
{
    unsigned charretValue =0 ;


    if( matrixPtr->Divider != 0 )
    {

      displayPtr->x = ( (matrixPtr->An * screenPtr->x) +
                        (matrixPtr->Bn * screenPtr->y) +
                           matrixPtr->Cn
                        ) / matrixPtr->Divider ;

      displayPtr->y = ( (matrixPtr->Dn * screenPtr->x) +
                        (matrixPtr->En * screenPtr->y) +
                           matrixPtr->Fn
                        ) / matrixPtr->Divider ;
    }
    else
    {
      retValue = 1;
    }

    return( retValue ) ;

} /* end of getDisplayPoint() */

rtems 发表于 2010-8-29 00:09:05

参考tslib吧。

wanglituan 发表于 2010-8-29 00:48:04

ioro55555 发表于 2010-12-23 11:27:26

我是用Ax+By+C和Dx+Ey+F,三点组成一个六元一次方程组,解矩阵算的,很准。

liusoldier 发表于 2010-12-23 12:27:10

这个有例程的,坛子里就有。在那个16080屏的讨论贴里。

xieguangye 发表于 2010-12-24 15:36:46

MARK

peavey 发表于 2011-1-15 23:13:40

记号

ringan865 发表于 2011-1-16 14:11:47

mark

joni 发表于 2011-1-16 14:15:07

mark

bg9cr 发表于 2013-11-22 09:04:07

学不会呀,需要恶补!!!
页: [1]
查看完整版本: 关于触摸屏校正算法,大家支支招,最近买了个触摸屏,想做个校正