打印

【连载】STM32开发指南--第三十一章 触摸屏实验

[复制链接]
3815|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
正点原子|  楼主 | 2013-3-19 22:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
第三十一章 触摸屏实验

       本章,我们将介绍如何使用STM32来驱动触摸屏,ALIENTEK战舰STM32开发板本身并没有触摸屏控制器,但是它支持触摸屏,可以通过外接带触摸屏的LCD模块(比如ALIENTEK TFTLCD模块),来实现触摸屏控制。在本章中,我们将向大家介绍STM32控制ALIENTKE TFTLCD模块,使用软件模拟SPI来实现对TFTLCD模块的触摸屏控制,最终实现一个手写板的功能。本章分为如下几个部分:
31.1 触摸屏简介
31.2 硬件设计
31.3 软件设计
31.4 下载验证

31.1 触摸屏简介   
我们一般液晶所用的触摸屏,最多的就是电阻式触摸屏了(多点触摸属于电容式触摸屏,比如几乎所有智能机都支持多点触摸,它们所用的屏就是电容式的触摸屏),ALIENTEK TFTLCD自带的触摸屏属于电阻式触摸屏,下面简单介绍下电阻式触摸屏的原理。
电阻式触摸屏利用压力感应进行控制。电阻触摸屏的主要部分是一块与显示器表面非常配合的电阻薄膜屏,这是一种多层的复合薄膜,它以一层玻璃或硬塑料平板作为基层,表面涂有一层透明氧化金属(透明的导电电阻)导电层,上面再盖有一层外表面硬化处理、光滑防擦的塑料层、它的内表面也涂有一层涂层、在他们之间有许多细小的(小于1/1000英寸)的透明隔离点把两层导电层隔开绝缘。 当手指触摸屏幕时,两层导电层在触摸点位置就有了接触,电阻发生变化,在X和Y两个方向上产生信号,然后送触摸屏控制器。控制器侦测到这一接触并计算出(X,Y)的位置,再根据获得的位置模拟鼠标的方式运作。这就是电阻技术触摸屏的最基本的原理。
电阻屏的特点有:
1)是一种对外界完全隔离的工作环境,不怕灰尘、水汽和油污。
2)可以用任何物体来触摸,可以用来写字画画,这是它们比较大的优势。
3)电阻触摸屏的精度只取决于A/D转换的精度,因此都能轻松达到4096*4096。
从以上介绍可知,触摸屏都需要一个AD转换器, 一般来说是需要一个控制器的。ALIENTEK TFTLCD模块选择的是四线电阻式触摸屏,这种触摸屏的控制芯片有很多,包括:ADS7843、ADS7846、TSC2046、XPT2046和AK4182等。这几款芯片的驱动基本上是一样的,也就是你只要写出了ADS7843的驱动,这个驱动对其他几个芯片也是有效的。而且封装也有一样的,完全PIN TO PIN兼容。所以在替换起来,很方便。
ALIENTEK TFTLCD模块自带的触摸屏控制芯片为XPT2046。XPT2046是一款4导线制触摸屏控制器,内含12位分辨率125KHz转换速率逐步逼近型A/D转换器。XPT2046支持从1.5V到5.25V的低电压I/O接口。XPT2046能通过执行两次A/D转换查出被按的屏幕位置, 除此之外,还可以测量加在触摸屏上的压力。内部自带2.5V参考电压可以作为辅助输入、温度测量和电池监测模式之用,电池监测的电压范围可以从0V到6V。XPT2046片内集成有一个温度传感器。 在2.7V的典型工作状态下,关闭参考电压,功耗可小于0.75mW。XPT2046采用微小的封装形式:TSSOP-16,QFN-16(0.75mm厚度)和VFBGA-48。工作温度范围为-40℃~+85℃。
该芯片完全是兼容ADS7843和ADS7846的,关于这个芯片的详细使用,可以参考这两个芯片的datasheet。

31.2 硬件设计
本章实验功能简介:开机的时候先通过24C02的数据判断触摸屏是否已经校准过,如果没有校准,则执行校准程序,校准过后再进入手写程序。如果已经校准了,就直接进入手写程序,此时可以通过按动屏幕来实现手写输入。屏幕上会有一个清空的操作区域(RST),点击这个地方就会将输入全部清除,恢复白板状态。程序会设置一个强制校准,就是通过按KEY0来实现,只要按下KEY0就会进入强制校准程序。
所要用到的硬件资源如下:
1)  指示灯DS0
2)  KEY0按键
3) TFTLCD模块(带触摸屏)
4)  24C02
所有这些资源与STM32的连接图,在前面都已经介绍了,这里我们只针对TFTLCD模块与STM32的连接端口再说明一下,TFTLCD模块的触摸屏总共有5跟线与STM32连接,连接电路图如图31.2.1所示:

图31.2.1 触摸屏与STM32的连接图
    从图中可以看出,T_MISO、T_PEN、T_CS、T_MOSI和T_SCK分别连接在STM32的:PF8、PF10、PB2、PF9和PB1上。
31.3 软件设计
打开上一章的工程,首先在HARDWARE文件夹下新建一个TOUCH文件夹。然后新建一个touch.c和touch.h的文件保存在TOUCH文件夹下,并将这个文件夹加入头文件包含路径。
打开touch.c文件,在里面输入与触摸屏相关的代码,这里我们也不全部贴出来了,仅介绍几个重要的函数。
首先我们要介绍的是TP_Read_XY2这个函数,该函数专门用于从触摸屏控制IC读取坐标的值(0~4095),TP_Read_XY2的代码如下:
//连续2次读取触摸屏IC,且这两次的偏差不能超过
//ERR_RANGE,满足条件,则认为读数正确,否则读数错误.      
//该函数能大大提高准确度
//x,y:读取到的坐标值
//返回值:0,失败;1,成功。
#define ERR_RANGE 50 //误差范围
u8 TP_Read_XY2(u16 *x,u16 *y)
{
       u16 x1,y1;
      u16 x2,y2;
      u8 flag;   
    flag=TP_Read_XY(&x1,&y1);  
    if(flag==0)return(0);
    flag=TP_Read_XY(&x2,&y2);      
    if(flag==0)return(0);  
    if(((x2<=x1&&x1<x2+ERR_RANGE)||(x1<=x2&&x2<x1+ERR_RANGE))
//前后两次采样在+- ERR_RANGE 内
    &&((y2<=y1&&y1<y2+ERR_RANGE)||(y1<=y2&&y2<y1+ERR_RANGE)))
    {
        *x=(x1+x2)/2;
        *y=(y1+y2)/2;
        return 1;
    }else return 0;  
}
该函数采用了一个非常好的办法来读取屏幕坐标值,就是连续读两次,两次读取的值之差不能超过一个特定的值(ERR_RANGE),通过这种方式,我们可以大大提高触摸屏的准确度。另外该函数调用的TP_Read_XY函数,用于单次读取坐标值。TP_Read_XY也采用了一些软件滤波算法,具体见光盘的源码。接下来,我们介绍另外一个函数TP_Adjust,该函数源码如下:
//触摸屏校准代码
//得到四个校准参数
void TP_Adjust(void)
{                                                     
//省略部分代码   
}   
TP_Adjust是此部分最核心的代码,在这里,给大家介绍一下我们这里所使用的触摸屏校正原理:我们传统的鼠标是一种相对定位系统,只和前一次鼠标的位置坐标有关。而触摸屏则是一种绝对坐标系统,要选哪就直接点哪,与相对定位系统有着本质的区别。绝对坐标系统的特点是每一次定位坐标与上一次定位坐标没有关系,每次触摸的数据通过校准转为屏幕上的坐标,不管在什么情况下,触摸屏这套坐标在同一点的输出数据是稳定的。不过由于技术原理的原因,并不能保证同一点触摸每一次采样数据相同,不能保证绝对坐标定位,点不准,这就是触摸屏最怕出现的问题:漂移。对于性能质量好的触摸屏来说,漂移的情况出现并不是很严重。所以很多应用触摸屏的系统启动后,进入应用程序前,先要执行校准程序。 通常应用程序中使用的LCD坐标是以像素为单位的。比如说:左上角的坐标是一组非0的数值,比如(20,20),而右下角的坐标为(220,300)。这些点的坐标都是以像素为单位的,而从触摸屏中读出的是点的物理坐标,其坐标轴的方向、XY值的比例因子、偏移量都与LCD坐标不同,所以,需要在程序中把物理坐标首先转换为像素坐标,然后再赋给POS结构,达到坐标转换的目的。
校正思路:在了解了校正原理之后,我们可以得出下面的一个从物理坐标到像素坐标的转换关系式:
                                          LCDx=xfac*Px+xoff;
                                          LCDy=yfac*Py+yoff;
其中(LCDx,LCDy)是在LCD上的像素坐标,(Px,Py)是从触摸屏读到的物理坐标。xfac,yfac分别是X轴方向和Y轴方向的比例因子,而xoff和yoff则是这两个方向的偏移量。
这样我们只要事先在屏幕上面显示4个点(这四个点的坐标是已知的),分别按这四个点就可以从触摸屏读到4个物理坐标,这样就可以通过待定系数法求出xfac、yfac、xoff、yoff这四个参数。我们保存好这四个参数,在以后的使用中,我们把所有得到的物理坐标都按照这个关系式来计算,得到的就是准确的屏幕坐标。达到了触摸屏校准的目的。
TP_Adjust就是根据上面的原理设计的校准函数,注意该函数里面多次使用了lcddev.width和lcddev.height,用于坐标设置,主要是为了兼容不同尺寸的LCD(比如320*480和320*240的屏都可以兼容)。其他的函数我们这里就不多介绍了,保存touch.c文件,并把该文件加入到HARDWARE组下。接下来打开touch.h文件,在该文件里面输入如下代码:
#ifndef __TOUCH_H__
#define __TOUCH_H__
#include "sys.h"
#define TP_PRES_DOWN 0x80  //触屏被按下  
#define TP_CATH_PRES 0x40  //有按键按下了                     
//触摸屏控制器
typedef struct
{
       u8 (*init)(void);                   //初始化触摸屏控制器
       u8 (*scan)(u8);                    //扫描触摸屏.0,屏幕扫描;1,物理坐标;      
       void (*adjust)(void);             //触摸屏校准
       u16 x0;                               //原始坐标(第一次按下时的坐标)
       u16 y0;
       u16 x;                                //当前坐标(此次扫描时,触屏的坐标)
       u16 y;                                                
       u8  sta;                              //笔的状态
                                                 //b7:按下1/松开0;
                               //b6:0,没有按键按下;1,有按键按下.
////////////////////////触摸屏校准参数/////////////////////////                                                   
       float xfac;                                 
       float yfac;
       short xoff;
       short yoff;        
//新增的参数,当触摸屏的左右上下完全颠倒时需要用到.
//touchtype=0的时候,适合左右为X坐标,上下为Y坐标的TP.
//touchtype=1的时候,适合左右为Y坐标,上下为X坐标的TP.
       u8 touchtype;
}_m_tp_dev;
extern _m_tp_dev tp_dev;          //触屏控制器在touch.c里面定义
//与触摸屏芯片连接引脚      
#define PEN        PFin(10)       //PF10 INT
#define DOUT      PFin(8)        //PF8  MISO
#define TDIN        PFout(9)       //PF9  MOSI
#define TCLK       PBout(1)       //PB1  SCLK
#define TCS         PBout(2)       //PB2  CS
//省略部分代码        
#endif
上述代码,我们定义了_m_tp_dev结构体,用于管理和记录触摸屏相关信息,在外部调用的时候,我们一般直接调用tp_dev的相关成员函数/变量屏即可达到需要的效果。这样种设计简化了接口,另外管理和维护也比较方便,大家可以效仿一下。其他部分我们不做多的介绍,最后我们打开test.c,修改代码如下:
//清屏,重新装载对话界面                                    
void Load_Drow_Dialog(void)
{
       LCD_Clear(WHITE);//清屏  
      POINT_COLOR=BLUE;//设置字体为蓝色
       LCD_ShowString(lcddev.width-24,0,200,16,16,"RST");//显示清屏区域
      POINT_COLOR=RED;//设置画笔蓝色
}                                                         
int main(void)
{           
       u8 key;
       u8 i=0;      
      Stm32_Clock_Init(9);    //系统时钟设置
       uart_init(72,9600);      //串口初始化为9600
       delay_init(72);                  //延时初始化
       LED_Init();                 //初始化与LED连接的硬件接口
       LCD_Init();                  //初始化LCD
       usmart_dev.init(72);      //初始化USMART      
       KEY_Init();                //按键初始化         
      POINT_COLOR=RED;//设置字体为红色
       LCD_ShowString(60,50,200,16,16,"WarShip STM32");   
       LCD_ShowString(60,70,200,16,16,"TOUCH TEST");      
       LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");
       LCD_ShowString(60,110,200,16,16,"2012/9/11");
     LCD_ShowString(60,130,200,16,16,"Press KEY0 to Adjust");
      tp_dev.init();
       delay_ms(1500);
       Load_Drow_Dialog();                                                                        
       while(1)
       {
             key=KEY_Scan(0);
              tp_dev.scan(0);              
              if(tp_dev.sta&TP_PRES_DOWN)               //触摸屏被按下
              {   
                    if(tp_dev.x<lcddev.width&&tp_dev.y<lcddev.height)
                     {   
                            if(tp_dev.x>(lcddev.width-24)&&tp_dev.y<16)Load_Drow_Dialog();//清除
                            else TP_Draw_Big_Point(tp_dev.x,tp_dev.y,RED);            //画图                                 }
              }else delay_ms(10);       //没有按键按下的时候            
              if(key==KEY_RIGHT)  //KEY_RIGHT按下,则执行校准程序
              {
                     LCD_Clear(WHITE);//清屏
                  TP_Adjust();  //屏幕校准
                     TP_Save_Adjdata();     
                     Load_Drow_Dialog();
              }
              i++;
              if(i==20) {i=0; LED0=!LED0;}         
       }
}
此函数就实现了我们上面介绍的本章所要实现的功能。当然这里还用到我们之前写的24CXX的代码,用来保存和调用触摸屏的校准信息(在触摸屏校准函数和初始化函数里面)。
31.4 下载验证
在代码编译成功之后,我们通过下载代码到ALIENTEK战舰STM32开发板上,得到如图31.4.1所示:
图31.4.1 程序运行效果
如果已经校准过了,则在等待1.5s之后进入手写界面,同时DS0开始闪烁,界面如图31.4.2所示:
图31.4.2 手写界面
此时,我们就可以在该界面下用笔或者手指输入信息了。如果没有校准过,则会自动进入校准程序(当你发现精度不行的时候,也可以通过按KEY0进入校准程序),如图31.4.3所示,在校准完成之后自动进入手写界面。

图31.4.3 校准界面
《STM32开发指南》第三十一章 触摸屏实验.rar (622.08 KB)

实验26 触摸屏实验.rar (142.04 KB)


沙发
xujihu| | 2014-4-29 21:35 | 只看该作者
学习            

使用特权

评论回复
板凳
jjg809898461| | 2014-5-29 20:01 | 只看该作者
请教一下,芯片上的miso是不是要对应模块上的mosi,还有那个t_pen管脚是干嘛用的呢?

使用特权

评论回复
地板
longfenghugui| | 2014-8-21 15:20 | 只看该作者

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:我的STM32开发板店铺:http://openedv.taobao.com 我的技术论坛论坛:www.openedv.com

91

主题

264

帖子

71

粉丝