OpenEdv-开源电子网

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

触摸屏源码里的疑问

[复制链接]

190

主题

401

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1291
金钱
1291
注册时间
2014-6-15
在线时间
144 小时
发表于 2014-7-30 21:45:32 | 显示全部楼层 |阅读模式
5金钱
原子哥,帮我解析一下下边的疑问

//////////////////////////////////////////////////////////////////////////////////  
//触摸按键扫描
//tp:0,屏幕坐标;1,物理坐标(校准等特殊场合用)
//返回值:当前触屏状态.
//0,触屏无触摸;1,触屏有触摸
u8 TP_Scan(u8 tp)
{   
if(PEN==0)//有按键按下
{
if(tp)TP_Read_XY2(&tp_dev.x,&tp_dev.y);//读取物理坐标  ==================================????? 这怎么会是读取物理坐标呢,
else if(TP_Read_XY2(&tp_dev.x,&tp_dev.y))//读取屏幕坐标
{
tp_dev.x=tp_dev.xfac*tp_dev.x+tp_dev.xoff;//将结果转换为屏幕坐标
tp_dev.y=tp_dev.yfac*tp_dev.y+tp_dev.yoff;  

if((tp_dev.sta&TP_PRES_DOWN)==0)//之前没有被按下
{  
tp_dev.sta=TP_PRES_DOWN|TP_CATH_PRES;//按键按下  
tp_dev.x0=tp_dev.x;//记录第一次按下时的坐标
tp_dev.y0=tp_dev.y;      
}   
}else
{
if(tp_dev.sta&TP_PRES_DOWN)//之前是被按下的
{
tp_dev.sta&=~(1<<7);//标记按键松开
}else//之前就没有被按下
{
tp_dev.x0=0;
tp_dev.y0=0;
tp_dev.x=0xffff;
tp_dev.y=0xffff;
}    
}
return tp_dev.sta&TP_PRES_DOWN;//返回当前的触屏状态
}  




 
//触摸屏校准代码
//得到四个校准参数
void TP_Adjust(void)
{  
u16 pos_temp[4][2];//坐标缓存值
u8  cnt=0;
u16 d1,d2;
u32 tem1,tem2;
float fac;
u16 outtime=0;
  cnt=0;
POINT_COLOR=BLUE;
BACK_COLOR =WHITE;
LCD_Clear(WHITE);//清屏   
POINT_COLOR=RED;//红色 
LCD_Clear(WHITE);//清屏   
POINT_COLOR=BLACK;
LCD_ShowString(40,40,160,100,16,(u8*)TP_REMIND_MSG_TBL);//显示提示信息
TP_Drow_Touch_Point(20,20,RED);//画点1 
tp_dev.sta=0;//消除触发信号 
tp_dev.xfac=0;//xfac用来标记是否校准过,所以校准之前必须清掉!以免错误  
while(1)//如果连续10秒钟没有按下,则自动退出
{
tp_dev.scan(1);//扫描物理坐标  ==================================================????? 这怎么会是读取物理坐标呢,
if((tp_dev.sta&0xc0)==TP_CATH_PRES)//按键按下了一次(此时按键松开了.)
{
outtime=0;
tp_dev.sta&=~(1<<6);//标记按键已经被处理过了.
    
pos_temp[cnt][0]=tp_dev.x;
pos_temp[cnt][1]=tp_dev.y;
cnt++;  
switch(cnt)
{   
case 1:  
TP_Drow_Touch_Point(20,20,WHITE); //清除点1 
TP_Drow_Touch_Point(lcddev.width-20,20,RED); //画点2
break;
case 2:
  TP_Drow_Touch_Point(lcddev.width-20,20,WHITE); //清除点2
TP_Drow_Touch_Point(20,lcddev.height-20,RED); //画点3
break;
case 3:
  TP_Drow_Touch_Point(20,lcddev.height-20,WHITE); //清除点3
  TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,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;
      TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE); //清除点4
    TP_Drow_Touch_Point(20,20,RED); //画点1
  TP_Adj_Info_Show(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//显示数据   
  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;
      TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE); //清除点4
    TP_Drow_Touch_Point(20,20,RED); //画点1
  TP_Adj_Info_Show(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//显示数据   
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;
      TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE); //清除点4
    TP_Drow_Touch_Point(20,20,RED); //画点1
  TP_Adj_Info_Show(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//显示数据   
continue;
}//正确了
//计算结果
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  
if(abs(tp_dev.xfac)>2||abs(tp_dev.yfac)>2)//触屏和预设的相反了.
{
cnt=0;
      TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE); //清除点4
    TP_Drow_Touch_Point(20,20,RED); //画点1
LCD_ShowString(40,26,lcddev.width,lcddev.height,16,"TP Need readjust!");
tp_dev.touchtype=!tp_dev.touchtype;//修改触屏类型.
if(tp_dev.touchtype)//X,Y方向与屏幕相反
{
CMD_RDX=0X90;
CMD_RDY=0XD0;  
}else   //X,Y方向与屏幕相同
{
CMD_RDX=0XD0;
CMD_RDY=0X90;  
}    
continue;
}
POINT_COLOR=BLUE;
LCD_Clear(WHITE);//清屏
LCD_ShowString(35,110,lcddev.width,lcddev.height,16,"Touch Screen Adjust OK!");//校正完成
delay_ms(1000);
TP_Save_Adjdata();  
  LCD_Clear(WHITE);//清屏   
return;//校正完成  
}
}
delay_ms(10);
outtime++;
if(outtime>1000)
{
TP_Get_Adjdata();
break;

  }
}  



如上是触摸屏实验的源码,注意“===============????? 这怎么会是读取物理坐标呢,”的地方   读到的怎么可能是物理坐标呢,物理坐标是一个屏幕的固有特性,是一直的,读到的只可能是某一点的电压值,   


最佳答案

查看完整内容[请看2#楼]

此处: 物理坐标=XPT2046,读取到的触摸屏原始数据. 也就是没有经过校准的坐标数据. x,y范围,就是0~4095. 不是一个固定的值.
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-7-30 21:45:33 | 显示全部楼层
此处:
物理坐标=XPT2046,读取到的触摸屏原始数据.

也就是没有经过校准的坐标数据.
x,y范围,就是0~4095.
不是一个固定的值.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-4 16:15

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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