新闻中心

STM32_Touch 总结

作者: 时间:2016-12-03 来源:网络 收藏
移植了奋斗的触摸屏程序,有一些地方还是没有搞懂,这个先把已经做好的记录下来。

首先是触摸屏校准值,这个在后面有专门的校准函数,但是上电采用已经有的校准值进行操作。

本文引用地址://m.amcfsurvey.com/article/201612/325144.htm
C语言:Codee#18707
/*==================================================================
* Function : Touch_CalibrationValueAssignment
* Description : 触摸屏校准系数 赋初值
* Input Para : None
* Output Para : void
* Return Value : None
==================================================================*/
voidTouch_CalibrationValueAssignment(void)
{
T_Adjust_X2=14.475;T_Adjust_Y2=10.7625;// 校准初始值
T_Adjust_Xs=3759;T_Adjust_Ys=3823;
// T_Adjust_Xe=2086;T_Adjust_Ye=2138; // 本例子不是必须的,需要看电阻式触摸屏的算法控制
}

然后是读取Xpt2046的触摸屏值,使用的是stm32的硬件SPI进行读取

C语言:Codee#18708
/*==================================================================
* Function : TFT_Touch_Read_Once
* Description : TFT液晶触摸屏 读取一次X,Y值,读到的X,Y坐标值必须都大于100,读数限制在100~3800之间.
* Input Para : None
* Output Para : void
* Return Value : 成功返回1,不成功返回0
==================================================================*/
u8TFT_Touch_Read_Once(void)
{
unsignedinta,b;
TCS_SET(0);
Delay_Ms(1);// delay_us(5);
SPI1_SendByte(CMD_RDY);
Delay_Ms(1);//delay_us(5);
a=SPI1_ReadByte(0);
a=a<<8;
a|=SPI1_ReadByte(0);
Delay_Ms(1);//delay_us(5);
TCS_SET(1);
a>>=3;
T_1s_Y=a;// 获得Y轴一次测量值
//-------------------------------
Delay_Ms(1);//delay_us(15);
TCS_SET(0);
Delay_Ms(1);//delay_us(5);
SPI1_SendByte(CMD_RDX);
Delay_Ms(1);//delay_us(5);
b=SPI1_ReadByte(0);
b=b<<8;
b|=SPI1_ReadByte(0);
Delay_Ms(1);//delay_us(5);
b>>=3;
T_1s_X=b;// 获得X轴一次测量值

TCS_SET(1);
if(b>100&&a>100&&b<4000&&a<4000)return1;//读数成功(范围限制)
elsereturn0;//读数失败
}

然后是多次读取,并且把读取到的值和TFT的比例进行匹配,在代码里可以看到,先是读取了10次并排列好,在误差范围允许的情况下取平均值作为读取的数值,最后根据校准值把读取值修正成和TFT匹配的坐标值。

C语言:Codee#18709
/*==================================================================
* Function : Read_Tsc2046
* Description : 获得最终的校准X,Y的坐标
* Input Para : None
* Output Para : void
* Return Value : None
==================================================================*/
voidRead_Tsc2046(void)
{
floatX1,Y1;
u16x1,x2,y1,y2;
u8t,t1,count=0;
u16databuffer[2][10];//数据组
u16temp=0;
do//循环读数10次
{
if(TFT_Touch_Read_Once())//读数成功
{
databuffer[0][count]=T_1s_X;
databuffer[1][count]=T_1s_Y;
count++;
}
t=PEN;
}while(!t&&count<10);// 保证按键必须按下并且要连续采样10次
if(count==10)//一定要读到10次数据,否则丢弃
{
do//将数据X升序排列
{
t1=0;
for(t=0;t {
if(databuffer[0][t]>databuffer[0][t+1])//升序排列
{
temp=databuffer[0][t+1];
databuffer[0][t+1]=databuffer[0][t];
databuffer[0][t]=temp;
t1=1;
}
}
}while(t1);
do//将数据Y升序排列
{
t1=0;
for(t=0;t {
if(databuffer[1][t]>databuffer[1][t+1])//升序排列
{
temp=databuffer[1][t+1];
databuffer[1][t+1]=databuffer[1][t];
databuffer[1][t]=temp;
t1=1;
}
}
}while(t1);
x1=databuffer[0][3];x2=databuffer[0][4];
y1=databuffer[1][3];y2=databuffer[1][4];
if(((x1>x2)&&(x1>x2+30))||((x2>x1)&&(x2>x1+30))||((y1>y2)&&(y1>y2+30))||((y2>y1)&&(y2>y1+30)));
else
{
X1=(databuffer[0][3]+databuffer[0][4])/2;//如果 抖动值不超过范围则取两个中间值来求均值
Y1=(databuffer[1][3]+databuffer[1][4])/2;

if(X1<=4096&&Y1<=4096)//个人的屏根据初始参数修改. 正常
{
if(TFT_Get_Calibration_EN)// 把读取的数据直接使用,在校准TFT时候用
{
T_Fixed_X=X1;
T_Fixed_Y=Y1;
}
else// 把读取的数据转换成和TFT的坐标比例相同的坐标点(即240*320),方便使用.
{
if(X1>=T_Adjust_Xs)
{X1=0;}
else
{X1=T_Adjust_Xs-X1;}
//if(Y1>=Ys)Y1-=Ys;
//else Y1=0;
if(Y1<=T_Adjust_Ys)
{Y1=T_Adjust_Ys-Y1;}
else
{Y1=0;}
//X2=Xs-Xe; X2=X2/240;
//Y2=Ye-Ys; Y2=Y2/320;
T_Fixed_X=X1/T_Adjust_X2;
T_Fixed_Y=Y1/T_Adjust_Y2;
}
}
}
}
}

最后是触摸校准的代码

C语言:Codee#18710
/*==================================================================
* Function : Get_Calibration_Value
* Description : 获取校准值,通过触摸重新找到校准值
* Input Para : None
* Output Para : void
* Return Value : None
#####本代码只是获取校准值,并没有将校准值使用,后续程序可以上电从EEPROM里读取校准值,然后在本函数里获取新值后刷新EEPEOM.
==================================================================*/
voidGet_Calibration_Value(void)
{
floatX2,Y2 ;// 校准值临时变量,如果不提供临时变量,会导致获取第二点失败,以为校准值是全局的,一定要在最后修改
unsignedintXs,Ys,Xe,Ye;

TFT_Get_Calibration_EN=1;// 进入触摸屏校准状态

//===================================================== 捕捉第一点,屏幕左上角原点(0,0)点
Clear_WindowWithColor(WHITE);// 清屏
TFT_WriteMixedString(H5,ZL5,RED,0,RED,"请按下第一点");

Display_RectangleWithColor(0,10,0,2,RED);// 画十字线
Display_RectangleWithColor(0,2,0,10,RED);

while(1)// 进入识别第一点
{
if(Touch_EN)// 有键按下
{
Delay_Ms(50);
if(PEN==0)
{
Read_Tsc2046();
Xs=T_Fixed_X;
Ys=T_Fixed_Y;
Clear_TouchPoint();
break;
}
else
{Touch_EN=0;}
}
}

//====================================================== 捕捉第二点,屏幕中心点(120,160)点
Clear_WindowWithColor(WHITE);// 清屏
TFT_WriteMixedString(H5,ZL5,RED,0,RED,"请按下第二点");

Display_RectangleWithColor(110,130,159,161,RED);// 画十字线
Display_RectangleWithColor(119,121,150,170,RED);

while(1)
{
if(Touch_EN)
{
Delay_Ms(260);// 这个延时要比上一个要长,防止按一次,把两次都识别了
if(PEN==0)
{
Read_Tsc2046();
Xe=T_Fixed_X;
Ye=T_Fixed_Y;
Clear_TouchPoint();
break;
}
else
{Touch_EN=0;}
}
}

//====================================================== 通过两点组建方程求得校准值
X2=Xs-Xe;X2=X2/120;
Y2=Ys-Ye;Y2=Y2/160;

//====================================================== 最后赋值 全局变量,改变校准值
T_Adjust_X2=X2;T_Adjust_Y2=Y2;
T_Adjust_Xs=Xs;T_Adjust_Ys=Ys;
T_Adjust_Xe=Xe;T_Adjust_Ye=Ye;

TFT_Get_Calibration_EN=0;// 退出触摸屏校准状态

TFT_WriteMixedString(H15,ZL4,BLUE,1,YELLOW,"TFT-Touch 校准完毕");
}


这里有两个问题没有搞清楚:

1,读取值 ,校准值 ,匹配值 的计算关系;

2,校准值 的计算方程,原理看datasheet到是明白些,具体计算不是很清楚。

后面还打算自己做4.3寸和7寸的TFT,这个还是要搞明白的。



关键词:STM32Touc

评论


技术专区

关闭