新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32_Touch 總結

        STM32_Touch 總結

        作者: 時間:2016-12-03 來源:網絡 收藏
        移植了奮斗的觸摸屏程序,有一些地方還是沒有搞懂,這個先把已經做好的記錄下來。

        首先是觸摸屏校準值,這個在后面有專門的校準函數,但是上電采用已經有的校準值進行操作。

        本文引用地址:http://www.104case.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

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 高陵县| 高淳县| 天峨县| 建德市| 汉寿县| 博爱县| 都江堰市| 新民市| 自治县| 宕昌县| 南涧| 游戏| 垣曲县| 调兵山市| 广宁县| 紫金县| 梅州市| 枣阳市| 鄢陵县| 大城县| 台南市| 通江县| 南漳县| 锦州市| 阿勒泰市| 佛山市| 土默特左旗| 台安县| 兴宁市| 东城区| 庆云县| 普定县| 新绛县| 上犹县| 潼关县| 卓尼县| 乌鲁木齐市| 遂昌县| 乐至县| 龙里县| 雅安市|