STM32_Touch 總結(jié)
首先是觸摸屏校準(zhǔn)值,這個(gè)在后面有專門的校準(zhǔn)函數(shù),但是上電采用已經(jīng)有的校準(zhǔn)值進(jìn)行操作。
本文引用地址:http://m.butianyuan.cn/article/201612/325144.htmC語言:Codee#18707
/*==================================================================
* Function : Touch_CalibrationValueAssignment
* Description : 觸摸屏校準(zhǔn)系數(shù) 賦初值
* Input Para : None
* Output Para : void
* Return Value : None
==================================================================*/
voidTouch_CalibrationValueAssignment(void)
{
T_Adjust_X2=14.475;T_Adjust_Y2=10.7625;// 校準(zhǔn)初始值
T_Adjust_Xs=3759;T_Adjust_Ys=3823;
// T_Adjust_Xe=2086;T_Adjust_Ye=2138; // 本例子不是必須的,需要看電阻式觸摸屏的算法控制
}
* Function : Touch_CalibrationValueAssignment
* Description : 觸摸屏校準(zhǔn)系數(shù) 賦初值
* Input Para : None
* Output Para : void
* Return Value : None
==================================================================*/
voidTouch_CalibrationValueAssignment(void)
{
T_Adjust_X2=14.475;T_Adjust_Y2=10.7625;// 校準(zhǔn)初始值
T_Adjust_Xs=3759;T_Adjust_Ys=3823;
// T_Adjust_Xe=2086;T_Adjust_Ye=2138; // 本例子不是必須的,需要看電阻式觸摸屏的算法控制
}
然后是讀取Xpt2046的觸摸屏值,使用的是stm32的硬件SPI進(jìn)行讀取
C語言:Codee#18708
/*==================================================================
* Function : TFT_Touch_Read_Once
* Description : TFT液晶觸摸屏 讀取一次X,Y值,讀到的X,Y坐標(biāo)值必須都大于100,讀數(shù)限制在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軸一次測(cè)量值
//-------------------------------
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軸一次測(cè)量值
TCS_SET(1);
if(b>100&&a>100&&b<4000&&a<4000)return1;//讀數(shù)成功(范圍限制)
elsereturn0;//讀數(shù)失敗
}
* Function : TFT_Touch_Read_Once
* Description : TFT液晶觸摸屏 讀取一次X,Y值,讀到的X,Y坐標(biāo)值必須都大于100,讀數(shù)限制在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軸一次測(cè)量值
//-------------------------------
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軸一次測(cè)量值
TCS_SET(1);
if(b>100&&a>100&&b<4000&&a<4000)return1;//讀數(shù)成功(范圍限制)
elsereturn0;//讀數(shù)失敗
}
然后是多次讀取,并且把讀取到的值和TFT的比例進(jìn)行匹配,在代碼里可以看到,先是讀取了10次并排列好,在誤差范圍允許的情況下取平均值作為讀取的數(shù)值,最后根據(jù)校準(zhǔn)值把讀取值修正成和TFT匹配的坐標(biāo)值。
C語言:Codee#18709
/*==================================================================
* Function : Read_Tsc2046
* Description : 獲得最終的校準(zhǔn)X,Y的坐標(biāo)
* 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];//數(shù)據(jù)組
u16temp=0;
do//循環(huán)讀數(shù)10次
{
if(TFT_Touch_Read_Once())//讀數(shù)成功
{
databuffer[0][count]=T_1s_X;
databuffer[1][count]=T_1s_Y;
count++;
}
t=PEN;
}while(!t&&count<10);// 保證按鍵必須按下并且要連續(xù)采樣10次
if(count==10)//一定要讀到10次數(shù)據(jù),否則丟棄
{
do//將數(shù)據(jù)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//將數(shù)據(jù)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;//如果抖動(dòng)值不超過范圍則取兩個(gè)中間值來求均值
Y1=(databuffer[1][3]+databuffer[1][4])/2;
if(X1<=4096&&Y1<=4096)//個(gè)人的屏根據(jù)初始參數(shù)修改. 正常
{
if(TFT_Get_Calibration_EN)// 把讀取的數(shù)據(jù)直接使用,在校準(zhǔn)TFT時(shí)候用
{
T_Fixed_X=X1;
T_Fixed_Y=Y1;
}
else// 把讀取的數(shù)據(jù)轉(zhuǎn)換成和TFT的坐標(biāo)比例相同的坐標(biāo)點(diǎn)(即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;
}
}
}
}
}
* Function : Read_Tsc2046
* Description : 獲得最終的校準(zhǔn)X,Y的坐標(biāo)
* 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];//數(shù)據(jù)組
u16temp=0;
do//循環(huán)讀數(shù)10次
{
if(TFT_Touch_Read_Once())//讀數(shù)成功
{
databuffer[0][count]=T_1s_X;
databuffer[1][count]=T_1s_Y;
count++;
}
t=PEN;
}while(!t&&count<10);// 保證按鍵必須按下并且要連續(xù)采樣10次
if(count==10)//一定要讀到10次數(shù)據(jù),否則丟棄
{
do//將數(shù)據(jù)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//將數(shù)據(jù)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;//如果抖動(dòng)值不超過范圍則取兩個(gè)中間值來求均值
Y1=(databuffer[1][3]+databuffer[1][4])/2;
if(X1<=4096&&Y1<=4096)//個(gè)人的屏根據(jù)初始參數(shù)修改. 正常
{
if(TFT_Get_Calibration_EN)// 把讀取的數(shù)據(jù)直接使用,在校準(zhǔn)TFT時(shí)候用
{
T_Fixed_X=X1;
T_Fixed_Y=Y1;
}
else// 把讀取的數(shù)據(jù)轉(zhuǎn)換成和TFT的坐標(biāo)比例相同的坐標(biāo)點(diǎn)(即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;
}
}
}
}
}
最后是觸摸校準(zhǔn)的代碼
C語言:Codee#18710
/*==================================================================
* Function : Get_Calibration_Value
* Description : 獲取校準(zhǔn)值,通過觸摸重新找到校準(zhǔn)值
* Input Para : None
* Output Para : void
* Return Value : None
#####本代碼只是獲取校準(zhǔn)值,并沒有將校準(zhǔn)值使用,后續(xù)程序可以上電從EEPROM里讀取校準(zhǔn)值,然后在本函數(shù)里獲取新值后刷新EEPEOM.
==================================================================*/
voidGet_Calibration_Value(void)
{
floatX2,Y2 ;// 校準(zhǔn)值臨時(shí)變量,如果不提供臨時(shí)變量,會(huì)導(dǎo)致獲取第二點(diǎn)失敗,以為校準(zhǔn)值是全局的,一定要在最后修改
unsignedintXs,Ys,Xe,Ye;
TFT_Get_Calibration_EN=1;// 進(jìn)入觸摸屏校準(zhǔn)狀態(tài)
//===================================================== 捕捉第一點(diǎn),屏幕左上角原點(diǎn)(0,0)點(diǎn)
Clear_WindowWithColor(WHITE);// 清屏
TFT_WriteMixedString(H5,ZL5,RED,0,RED,"請(qǐng)按下第一點(diǎn)");
Display_RectangleWithColor(0,10,0,2,RED);// 畫十字線
Display_RectangleWithColor(0,2,0,10,RED);
while(1)// 進(jìn)入識(shí)別第一點(diǎn)
{
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;}
}
}
//====================================================== 捕捉第二點(diǎn),屏幕中心點(diǎn)(120,160)點(diǎn)
Clear_WindowWithColor(WHITE);// 清屏
TFT_WriteMixedString(H5,ZL5,RED,0,RED,"請(qǐng)按下第二點(diǎn)");
Display_RectangleWithColor(110,130,159,161,RED);// 畫十字線
Display_RectangleWithColor(119,121,150,170,RED);
while(1)
{
if(Touch_EN)
{
Delay_Ms(260);// 這個(gè)延時(shí)要比上一個(gè)要長,防止按一次,把兩次都識(shí)別了
if(PEN==0)
{
Read_Tsc2046();
Xe=T_Fixed_X;
Ye=T_Fixed_Y;
Clear_TouchPoint();
break;
}
else
{Touch_EN=0;}
}
}
//====================================================== 通過兩點(diǎn)組建方程求得校準(zhǔn)值
X2=Xs-Xe;X2=X2/120;
Y2=Ys-Ye;Y2=Y2/160;
//====================================================== 最后賦值全局變量,改變校準(zhǔn)值
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;// 退出觸摸屏校準(zhǔn)狀態(tài)
TFT_WriteMixedString(H15,ZL4,BLUE,1,YELLOW,"TFT-Touch 校準(zhǔn)完畢");
}
* Function : Get_Calibration_Value
* Description : 獲取校準(zhǔn)值,通過觸摸重新找到校準(zhǔn)值
* Input Para : None
* Output Para : void
* Return Value : None
#####本代碼只是獲取校準(zhǔn)值,并沒有將校準(zhǔn)值使用,后續(xù)程序可以上電從EEPROM里讀取校準(zhǔn)值,然后在本函數(shù)里獲取新值后刷新EEPEOM.
==================================================================*/
voidGet_Calibration_Value(void)
{
floatX2,Y2 ;// 校準(zhǔn)值臨時(shí)變量,如果不提供臨時(shí)變量,會(huì)導(dǎo)致獲取第二點(diǎn)失敗,以為校準(zhǔn)值是全局的,一定要在最后修改
unsignedintXs,Ys,Xe,Ye;
TFT_Get_Calibration_EN=1;// 進(jìn)入觸摸屏校準(zhǔn)狀態(tài)
//===================================================== 捕捉第一點(diǎn),屏幕左上角原點(diǎn)(0,0)點(diǎn)
Clear_WindowWithColor(WHITE);// 清屏
TFT_WriteMixedString(H5,ZL5,RED,0,RED,"請(qǐng)按下第一點(diǎn)");
Display_RectangleWithColor(0,10,0,2,RED);// 畫十字線
Display_RectangleWithColor(0,2,0,10,RED);
while(1)// 進(jìn)入識(shí)別第一點(diǎn)
{
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;}
}
}
//====================================================== 捕捉第二點(diǎn),屏幕中心點(diǎn)(120,160)點(diǎn)
Clear_WindowWithColor(WHITE);// 清屏
TFT_WriteMixedString(H5,ZL5,RED,0,RED,"請(qǐng)按下第二點(diǎn)");
Display_RectangleWithColor(110,130,159,161,RED);// 畫十字線
Display_RectangleWithColor(119,121,150,170,RED);
while(1)
{
if(Touch_EN)
{
Delay_Ms(260);// 這個(gè)延時(shí)要比上一個(gè)要長,防止按一次,把兩次都識(shí)別了
if(PEN==0)
{
Read_Tsc2046();
Xe=T_Fixed_X;
Ye=T_Fixed_Y;
Clear_TouchPoint();
break;
}
else
{Touch_EN=0;}
}
}
//====================================================== 通過兩點(diǎn)組建方程求得校準(zhǔn)值
X2=Xs-Xe;X2=X2/120;
Y2=Ys-Ye;Y2=Y2/160;
//====================================================== 最后賦值全局變量,改變校準(zhǔn)值
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;// 退出觸摸屏校準(zhǔn)狀態(tài)
TFT_WriteMixedString(H15,ZL4,BLUE,1,YELLOW,"TFT-Touch 校準(zhǔn)完畢");
}
這里有兩個(gè)問題沒有搞清楚:
1,讀取值 ,校準(zhǔn)值 ,匹配值 的計(jì)算關(guān)系;
2,校準(zhǔn)值 的計(jì)算方程,原理看datasheet到是明白些,具體計(jì)算不是很清楚。
后面還打算自己做4.3寸和7寸的TFT,這個(gè)還是要搞明白的。
評(píng)論