OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 11405|回复: 11

触摸屏校准代码疑问?

[复制链接]

10

主题

86

帖子

2

精华

中级会员

Rank: 3Rank: 3

积分
491
金钱
491
注册时间
2012-2-11
在线时间
8 小时
发表于 2013-1-10 12:00:23 | 显示全部楼层 |阅读模式

如题,先看原子哥程序:

 /***********************************************************
* 函数名称:Touch_Adjust
* 函数功能:触摸屏校准代码( 得到四个校准参数 )
*           入口参数:无      出口参数:0/1
***********************************************************/

void Touch_Adjust(void)
{        
 signed short pos_temp[4][2];//坐标缓存值
 u8  cnt=0; 
 u16 d1,d2;
 u32 tem1,tem2;
 float fac;    
 cnt=0;    
 LCD_Clear(WHITE);//清屏   
 Drow_Touch_Point(20,20,RED);//画点1
 en_Point.Key_Sta=Key_Up;//消除触发信号
 en_Point.xfac=0;//xfac用来标记是否校准过,所以校准之前必须清掉!以免错误 
 while(1)
 {
  if(Pen_Point.Key_Sta==Key_Down)//按键按下了
  {
   if(TOUCH_ReadTPOnce())//得到单次按键值
   {            
    pos_temp[cnt][0]=Pen_Point.X;
    pos_temp[cnt][1]=Pen_Point.Y;
    cnt++;
   }   
   switch(cnt)
   {     
    case 1:
     LCD_Clear(WHITE);//清屏
     Drow_Touch_Point(220,20,RED);//画点2
     break;
    case 2:
     LCD_Clear(WHITE);//清屏
     Drow_Touch_Point(20,300,RED);//画点3
     break;
    case 3:
     LCD_Clear(WHITE);//清屏
     Drow_Touch_Point(220,300,RED);//画点4
     break;
    case 4:  //全部四个点已经得到
           //对边相等
     tem1=abs(pos_temp[0][0]-pos_temp[1][0]);//x1-x2
     tem2=abs(pos_temp[0][1]-pos_temp[1][1]);//y1-y2
     tem1*=tem1;
     tem2*=tem2;
     d1=sqrt(tem1+tem2);//开平方得到1,2的距离
     
     tem1=abs(pos_temp[2][0]-pos_temp[3][0]);//x3-x4
     tem2=abs(pos_temp[2][1]-pos_temp[3][1]);//y3-y4
     tem1*=tem1;
     tem2*=tem2;
     d2=sqrt(tem1+tem2);//得到3,4的距离
     fac=(float)d1/d2;
     if(fac<0.95||fac>1.05||d1==0||d2==0)//不合格
     {
      cnt=0;
      LCD_Clear(WHITE);//清屏
      Drow_Touch_Point(20,20,RED);
      ADJ_INFO_SHOW("ver fac is:",RED);  
      LCD_ShowNum(40+24,40,pos_temp[0][0],4,0,RED);  //显示数值
      LCD_ShowNum(40+24+80,40,pos_temp[0][1],4,0,RED); //显示数值
      LCD_ShowNum(40+24,60,pos_temp[1][0],4,0,RED);  //显示数值
      LCD_ShowNum(40+24+80,60,pos_temp[1][1],4,0,RED); //显示数值
      LCD_ShowNum(40+24,80,pos_temp[2][0],4,0,RED);  //显示数值
      LCD_ShowNum(40+24+80,80,pos_temp[2][1],4,0,RED); //显示数值
      LCD_ShowNum(40+24,100,pos_temp[3][0],4,0,RED);  //显示数值
      LCD_ShowNum(40+24+80,100,pos_temp[3][1],4,0,RED); //显示数值
      //扩大100倍显示
      LCD_ShowNum(40,140,fac*100,3,0,RED);//显示数值,该数值必须在95~105范围之内.
      continue;
     }
     tem1=abs(pos_temp[0][0]-pos_temp[2][0]);//x1-x3
     tem2=abs(pos_temp[0][1]-pos_temp[2][1]);//y1-y3
     tem1*=tem1;
     tem2*=tem2;
     d1=sqrt(tem1+tem2);//得到1,3的距离
     
     tem1=abs(pos_temp[1][0]-pos_temp[3][0]);//x2-x4
     tem2=abs(pos_temp[1][1]-pos_temp[3][1]);//y2-y4
     tem1*=tem1;
     tem2*=tem2;
     d2=sqrt(tem1+tem2);//得到2,4的距离
     fac=(float)d1/d2;
     if(fac<0.95||fac>1.05)//不合格
     {
      cnt=0;
      LCD_Clear(WHITE);//清屏
      Drow_Touch_Point(20,20,RED);
      ADJ_INFO_SHOW("hor fac is:",RED);  
      LCD_ShowNum(40+24,40,pos_temp[0][0],4,0,RED);  //显示数值
      LCD_ShowNum(40+24+80,40,pos_temp[0][1],4,0,RED); //显示数值
      LCD_ShowNum(40+24,60,pos_temp[1][0],4,0,RED);  //显示数值
      LCD_ShowNum(40+24+80,60,pos_temp[1][1],4,0,RED); //显示数值
      LCD_ShowNum(40+24,80,pos_temp[2][0],4,0,RED);  //显示数值
      LCD_ShowNum(40+24+80,80,pos_temp[2][1],4,0,RED); //显示数值
      LCD_ShowNum(40+24,100,pos_temp[3][0],4,0,RED);  //显示数值
      LCD_ShowNum(40+24+80,100,pos_temp[3][1],4,0,RED); //显示数值
      //扩大100倍显示
      LCD_ShowNum(40,140,fac*100,3,0,RED);//显示数值,该数值必须在95~105范围之内.
       continue;
     }//正确了
          
     //对角线相等
     tem1=abs(pos_temp[1][0]-pos_temp[2][0]);//x1-x3
     tem2=abs(pos_temp[1][1]-pos_temp[2][1]);//y1-y3
     tem1*=tem1;
     tem2*=tem2;
     d1=sqrt(tem1+tem2);//得到1,4的距离
 
     tem1=abs(pos_temp[0][0]-pos_temp[3][0]);//x2-x4
     tem2=abs(pos_temp[0][1]-pos_temp[3][1]);//y2-y4
     tem1*=tem1;
     tem2*=tem2;
     d2=sqrt(tem1+tem2);//得到2,3的距离
     fac=(float)d1/d2;
     if(fac<0.95||fac>1.05)//不合格
     {
      cnt=0;
      LCD_Clear(WHITE);//清屏
      Drow_Touch_Point(20,20,RED);
      ADJ_INFO_SHOW("dia fac is:",RED);  
      LCD_ShowNum(40+24,40,pos_temp[0][0],4,0,RED);  //显示数值
      LCD_ShowNum(40+24+80,40,pos_temp[0][1],4,0,RED); //显示数值
      LCD_ShowNum(40+24,60,pos_temp[1][0],4,0,RED);  //显示数值
      LCD_ShowNum(40+24+80,60,pos_temp[1][1],4,0,RED); //显示数值
      LCD_ShowNum(40+24,80,pos_temp[2][0],4,0,RED);  //显示数值
      LCD_ShowNum(40+24+80,80,pos_temp[2][1],4,0,RED); //显示数值
      LCD_ShowNum(40+24,100,pos_temp[3][0],4,0,RED);  //显示数值
      LCD_ShowNum(40+24+80,100,pos_temp[3][1],4,0,RED); //显示数值
      //扩大100倍显示
      LCD_ShowNum(40,140,fac*100,3,0,RED);//显示数值,该数值必须在95~105范围之内.
      continue;
     }//正确了
     //计算结果
     en_Point.xfac=(float)200/(pos_temp[1][0]-pos_temp[0][0]);//得到xfac  
     en_Point.xoff=(240-Pen_Point.xfac*(pos_temp[1][0]+pos_temp[0][0]))/2;//得到xoff
       
     en_Point.yfac=(float)280/(pos_temp[2][1]-pos_temp[0][1]);//得到yfac
     en_Point.yoff=(320-Pen_Point.yfac*(pos_temp[2][1]+pos_temp[0][1]))/2;//得到yoff 

     if(abs(Pen_Point.xfac)>2||abs(Pen_Point.yfac)>2)//触屏和预设的相反了.
     {
      cnt=0;
      LCD_Clear(WHITE);//清屏
      Drow_Touch_Point(20,20,RED);
      LCD_ShowString(35,110,"TP Need readjust!",0,RED);
      en_Point.touchtype=!Pen_Point.touchtype;//修改触屏类型.
      if(Pen_Point.touchtype)//X,Y方向与屏幕相反
      {
       CMD_RDX=0X90;
       CMD_RDY=0XD0; 
      }else       //X,Y方向与屏幕相同
      {
       CMD_RDX=0XD0;
       CMD_RDY=0X90; 
      }
      Delay_nms(500);
      continue;
     }
     LCD_Clear(WHITE);//清屏
     LCD_ShowString(35,110,"Touch Screen Adjust OK!",0,BLUE);//校正完成
     Delay_nms(500);
     LCD_Clear(WHITE);//清屏  
     return;//校正完成    
   }
  }
 }
}      

   if(fac<0.95||fac>1.05||d1==0||d2==0)//不合格 

   if(abs(Pen_Point.xfac)>2||abs(Pen_Point.yfac)>2)//触屏和预设的相反了.


这两句对于菜鸟的我真的不太理解:

一、fac为什么要在0.95和1.05之间;
二、Pen_Point.xfac 为什么大于2就认为触屏和预设相反了;

论坛找遍了也没找到解释,麻烦原子哥和各位知道的朋友在百忙中给小弟解解惑,

多努力一点点,少遗憾一点点!!!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-1-10 12:53:04 | 显示全部楼层
1,
         //对边相等
tem1=abs(pos_temp[0][0]-pos_temp[1][0]);//x1-x2
tem2=abs(pos_temp[0][1]-pos_temp[1][1]);//y1-y2
tem1*=tem1;
tem2*=tem2;
d1=sqrt(tem1+tem2);//得到1,2的距离

tem1=abs(pos_temp[2][0]-pos_temp[3][0]);//x3-x4
tem2=abs(pos_temp[2][1]-pos_temp[3][1]);//y3-y4
tem1*=tem1;
tem2*=tem2;
d2=sqrt(tem1+tem2);//得到3,4的距离
fac=(float)d1/d2;
if(fac<0.95||fac>1.05||d1==0||d2==0)//不合格
看这个最开始:判断对边是否相等,最好的状态,当然是对边相等了(矩形),这里允许一点误差,所以设置了这个值。
2,正常情况下,Pen_Point.xfac或Pen_Point.xfac是远远小于1且大于0的,只有当X,Y坐标获取反了的时候,才可能出现fac>1,甚至远远大于1(还有可能是负数)。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

10

主题

86

帖子

2

精华

中级会员

Rank: 3Rank: 3

积分
491
金钱
491
注册时间
2012-2-11
在线时间
8 小时
 楼主| 发表于 2013-1-10 14:37:15 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
原来是这样哦,呵呵!谢谢原子哥哦
多努力一点点,少遗憾一点点!!!
回复 支持 反对

使用道具 举报

0

主题

15

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2012-9-20
在线时间
0 小时
发表于 2013-2-28 14:56:11 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
原子哥··在触摸屏校准的时候    我故意没点正确位置 
  可是出现的坐标却是  X1:3406   Y1:1948
                                 X2:3416    Y2:1907
   X3,Y3,X4,Y4  也是很大的数字 ,不知道这是什么原因额  ?屏幕的范围也才是240x320的吧? 为什么会出现这样的状况呢?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-2-28 15:57:30 | 显示全部楼层
这是物理坐标,也就是XPT2046读到的ADC值。和实际屏幕的坐标,还需要做一个变换。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
27
金钱
27
注册时间
2014-5-8
在线时间
0 小时
发表于 2014-6-24 23:09:01 | 显示全部楼层
//默认为touchtype=0的数据.
u8 CMD_RDX=0XD0;
u8 CMD_RDY=0X90;
0XD0,0X90命令我在ili9341 datasheet里找不到。在那里能够找到这个读取X,Y坐标的寄存器地址
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-6-24 23:20:25 | 显示全部楼层
回复【6楼】古月有道:
---------------------------------
这是触摸屏芯片的指令,是XPT2046的指令,你搞错对象了
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

6

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2014-4-18
在线时间
5 小时
发表于 2015-6-15 15:37:17 | 显示全部楼层
//计算结果
     tp_dev.xfac=(float)(lcddev.width-40)/(pos_temp[1][0]-pos_temp[0][0]);         //得到xfac  
     tp_dev.xoff=(lcddev.width-tp_dev.xfac*(pos_temp[1][0]+pos_temp[0][0]))/2;//得到xoff
  
     tp_dev.yfac=(float)(lcddev.height-40)/(pos_temp[2][1]-pos_temp[0][1]);        //得到yfac
     tp_dev.yoff=(lcddev.height-tp_dev.yfac*(pos_temp[2][1]+pos_temp[0][1]))/2;//得到yoff  

     LCDx=xfac*Px+xoff;
     LCDy=yfac*Py+yoff;

请问下,原子哥!
上面的这四个参数Pen_Point.xfac     en_Point.xoff       en_Point.yfac      en_Point.yoff
为什么要这样来计算,能不能解释下?
回复 支持 反对

使用道具 举报

86

主题

984

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1850
金钱
1850
注册时间
2013-4-15
在线时间
163 小时
发表于 2015-7-31 16:38:53 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
原子哥,你对于他第2条的解释是不是可以这么理解啊:“触摸屏的X方向是LCD的Y方向,触摸屏的Y方向是LCD的X方向”?
合肥-文盲
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-7-31 23:06:06 | 显示全部楼层
回复【9楼】合肥-文盲:
---------------------------------
可以
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

16

主题

173

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2441
金钱
2441
注册时间
2014-11-5
在线时间
348 小时
发表于 2015-9-8 18:09:29 | 显示全部楼层
回复【8楼】Acksman:
---------------------------------
xfac(斜率)    /*数学公式 k = (y1-y2)/(x1-x2)  tan */
xoff(相当于b)        /*数学公式 y = kx+b  即b=y-kx*/
回复 支持 反对

使用道具 举报

20

主题

71

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
438
金钱
438
注册时间
2020-3-24
在线时间
162 小时
发表于 2020-5-26 11:49:31 | 显示全部楼层
正点原子 发表于 2013-1-10 12:53
1,
        &nbsp;&nbsp;&nbsp;&nbsp;                &nbsp;&nbsp;&nbsp;&nbsp;//对边相等
                                        tem1=abs(pos_temp[0][0]-pos_t ...

原子哥,我校准得到的fac的值为0,最后得到的四个值都是4095,液晶屏是2.8寸的,这是怎么回事?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-28 13:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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