datasheet

STM32_Touch 总结

2016-10-06来源: eefocus关键字:STM32  Touch
移植了奋斗的触摸屏程序,有一些地方还是没有搞懂,这个先把已经做好的记录下来。

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

 
C语言: Codee#18707
/*==================================================================
* Function        : Touch_CalibrationValueAssignment
* Description    : 触摸屏校准系数 赋初值
* Input Para    : None
* Output Para    : void
* Return Value  : None
==================================================================*/
void Touch_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
==================================================================*/
u8 TFT_Touch_Read_Once(void)
{    
    unsigned int a,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)return 1;//读数成功(范围限制)
    else return 0;                             //读数失败
}

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

 
C语言: Codee#18709
/*==================================================================
* Function        : Read_Tsc2046
* Description    : 获得最终的校准X,Y的坐标
* Input Para    : None
* Output Para    : void
* Return Value  : None
==================================================================*/
void Read_Tsc2046(void)
{    
    float X1,Y1;
    u16 x1,x2,y1,y2;
    u8 t,t1,count=0;
    u16 databuffer[2][10];//数据组
    u16 temp=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.
==================================================================*/
void Get_Calibration_Value(void)
{
    float        X2,Y2         ;      // 校准值临时变量,如果不提供临时变量,会导致获取第二点失败,以为校准值是全局的,一定要在最后修改
    unsigned int Xs,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,这个还是要搞明白的。

关键字:STM32  Touch

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/article_2016100630103.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32 之 外部开门狗(iwdg)
下一篇:SDIO_FATFS_MDK 调试记录

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32堆栈设置

1.堆和栈大小 定义大小在startup_stm32f2xx.sStack_Size      EQU     0x00000400                AREA    STACK, NOINIT, READWRITE, ALIGN=3Stack_Mem      
发表于 2019-04-16
STM32堆栈设置

STM32堆和栈(Heap & Stack)的资料理解

源起:在移植cjson的过程中,解析json包的时候发现动态内存分配不足而导致解析失败,为解决这一问题,而深入了解stm32的堆和栈。stm32的存储器结构。Flash,SRAM寄存器和输入输出端口被组织在同一个4GB的线性地址空间内。可访问的存储器空间被分成8个主要块,每个块为512MB。FLASH存储下载的程序。SRAM是存储运行程序中的数据。而SRAM一般分这几个部分:静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存放静态数据、全局数据和常量。栈区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率
发表于 2019-04-16
STM32堆和栈(Heap & Stack)的资料理解

STM32定义堆栈地址到ram区顶部

本设置针对stm32f103rbt6的设置,该芯片RAM大小为20kB,故RAM区地址范围为0x20000000—0x20005000,芯片信息如下图所示;第一步:设置.sct文件;;*************************************************************; *** Scatter-Loading Description Filegenerated by uVision ***; *************************************************************LR_IROM1 0x08000000 0x00020000  
发表于 2019-04-16
STM32定义堆栈地址到ram区顶部

STM32之程序如何防止堆栈溢出

近日为某个项目写了个草稿程序,即非正式程序,后来发现老是进入hardfaulthandler,原来是堆栈溢出,后仔细查看发现函数调用纵深太深,最多的时候可保持7个函数在堆栈中调用。因此有心得如下:一、函数调用不要纵深太深,即以下模式:main(){   fun1();}fun1(){  fun2();}fun2(){   fun3();}fun3(){  fun4();}fun4(){  fun5();}fun5(){  fun6();}fun6(){   fun7();}这样子main函数要调用fun1函数完成某个功能,则要一直调到
发表于 2019-04-16

stm32之堆栈

stm32中的堆栈设置keil编译完成时存储情况当编译成功时,会出现: BUILD://Program Size: Code=340 RO-data=252 RW-data=0 ZI-data=1632Code:程序代码部分RO-data: 程序定义的常量const tempRW-data:已初始化的全局变量ZI-data:未初始化的全局变量片中的:flash=Code+RO-data+RW-dataRAM=RW-data+ZI-data通过上面的BUILD可以看出,这个程序已经用了1600多的RAM,为什么会出用到这么多的RAM呢?在startup_stm32f10x_md.s文件中存在:St
发表于 2019-04-16

说说STM32的堆栈与内存

1.概念这里所说的堆栈,是针对单片机所说的“堆”与“栈”,指的是内存中一片特殊用途的区域。而不是数据结构中的堆栈(虽然其实规则一样)。这里所说的内存,是指RAM,RAM包括SRAM,DRAM等。而不是什么手机内存卡之类。这里所说的flash,指的是用作为ROM的存储器,保存代码与常量数据。而不是动画制作。。。栈的生长方向:指的是入栈方向,从高地址向低地址生长叫做向下生长,或逆向生长;反过来就叫向上生长,或正向生长。STM32的栈是向下生长。2.内存中的堆栈安排确切地说,是keil mdk根据STM32的特性,对stm32的RAM甚至flash进行部署。编译工程后,在生成的.map文件里可以看到具体的安排。双击工程界面的工程根目录
发表于 2019-04-16
说说STM32的堆栈与内存

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved