搜索
bottom↓
回复: 17

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

[复制链接]

出0入0汤圆

发表于 2009-8-2 17:50:36 | 显示全部楼层 |阅读模式
关于触摸屏校正算法,大家支支招,最近买了个触摸屏,想做个校正。
自己做的程序不够精准,谢谢

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2009-8-2 17:52:41 | 显示全部楼层
关注中。。。。

出0入0汤圆

 楼主| 发表于 2009-8-2 17:58:47 | 显示全部楼层
似乎wince内核中自带有校正算法,
我现在是直接用单片机来控制触摸屏,

出0入0汤圆

 楼主| 发表于 2009-8-2 18:44:32 | 显示全部楼层
沉的好快啊

出0入0汤圆

发表于 2009-8-2 19:39:11 | 显示全部楼层
我看到的做法是,左上角一点,右下角一点,测试后提问是否重设

出0入0汤圆

发表于 2009-8-2 19:52:24 | 显示全部楼层
以前不知在哪下载的,没试过,你看看行不行
触摸屏校准原理ourdev_466645.rar(文件大小:92K) (原文件名:触摸屏校准原理.rar)

出0入0汤圆

发表于 2009-8-3 10:55:08 | 显示全部楼层
这里有程序 http://www.poweravr.com/bbs/viewthread.php?tid=231   LCD和触摸屏间的误差角度非常小 就可以用这个算法

出0入0汤圆

发表于 2009-8-3 12:49:19 | 显示全部楼层
Mark

出0入0汤圆

发表于 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[1],TP_Y[1];
#define  VALUE 3  //差值
coordinate *Read_Ads7846(void)
{
    coordinate  Screen ;
    int m0,m1,m2;
        u8 count=0;
        u16 databuffer[2][9]={{0},{0}};//数据组
        u16 temp[3];      
    do                                          //循环读数9次
        {                  
            TP_GetAdXY(TP_X,TP_Y);  
                        databuffer[0][count]=TP_X[0];  //X
                        databuffer[1][count]=TP_Y[0];
                        count++;  
        }
        while(count<9);  
        if(count==9)//一定要读到9次数据,否则丢弃
        {  
         temp[0]=(databuffer[0][0]+databuffer[0][1]+databuffer[0][2])/3;
         temp[1]=(databuffer[0][3]+databuffer[0][4]+databuffer[0][5])/3;
         temp[2]=(databuffer[0][6]+databuffer[0][7]+databuffer[0][8])/3;
         m0=temp[0]-temp[1];
         m1=temp[1]-temp[2];
         m2=temp[2]-temp[0];

         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[0]+temp[2])/2;
                     else Screen.x=(temp[0]+temp[1])/2;        }
         else if(m2<m1) Screen.x=(temp[0]+temp[2])/2;
                     else Screen.x=(temp[1]+temp[2])/2;



     temp[0]=(databuffer[1][0]+databuffer[1][1]+databuffer[1][2])/3;
         temp[1]=(databuffer[1][3]+databuffer[1][4]+databuffer[1][5])/3;
         temp[2]=(databuffer[1][6]+databuffer[1][7]+databuffer[1][8])/3;
         m0=temp[0]-temp[1];
         m1=temp[1]-temp[2];
         m2=temp[2]-temp[0];

         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[0]+temp[2])/2;
                     else Screen.y=(temp[0]+temp[1])/2;        }
         else if(m2<m1) Screen.y=(temp[0]+temp[2])/2;
                     else Screen.y=(temp[1]+temp[2])/2;
                  return &Screen;
                }  
        return 0;
}
         

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

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

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

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


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

    unsigned char  retValue = 0 ;


   
    matrixPtr->Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -
                         ((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;

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

        matrixPtr->Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) -
                        ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ;

        matrixPtr->Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y +
                        (screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y +
                        (screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ;

        matrixPtr->Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) -
                        ((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ;
   
        matrixPtr->En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) -
                        ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ;

        matrixPtr->Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y +
                        (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y +
                        (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ;
    }

    return( retValue ) ;
}

unsigned char getDisplayPoint(coordinate * displayPtr,
                     coordinate * screenPtr,
                     matrix * matrixPtr )
{
    unsigned char  retValue =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() */

出0入0汤圆

发表于 2010-8-29 00:09:05 | 显示全部楼层
参考tslib吧。

出0入0汤圆

发表于 2010-8-29 00:48:04 | 显示全部楼层

出0入0汤圆

发表于 2010-12-23 11:27:26 | 显示全部楼层
我是用Ax+By+C和Dx+Ey+F,三点组成一个六元一次方程组,解矩阵算的,很准。

出0入0汤圆

发表于 2010-12-23 12:27:10 | 显示全部楼层
这个有例程的,坛子里就有。在那个16080屏的讨论贴里。

出0入0汤圆

发表于 2010-12-24 15:36:46 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-1-15 23:13:40 | 显示全部楼层
记号

出0入0汤圆

发表于 2011-1-16 14:11:47 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-16 14:15:07 | 显示全部楼层
mark

出0入0汤圆

发表于 2013-11-22 09:04:07 | 显示全部楼层
学不会呀,需要恶补!!!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 22:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表