您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > STM32开发指南V1.0-库函数版本(下册)
417第三十一章触摸屏实验本章,我们将介绍如何使用STM32来驱动触摸屏,ALIENTEK战舰STM32开发板本身并没有触摸屏控制器,但是它支持触摸屏,可以通过外接带触摸屏的LCD模块(比如ALIENTEKTFTLCD模块),来实现触摸屏控制。在本章中,我们将向大家介绍STM32控制ALIENTKETFTLCD模块,使用软件模拟SPI来实现对TFTLCD模块的触摸屏控制,最终实现一个手写板的功能。本章分为如下几个部分:31.1触摸屏简介31.2硬件设计31.3软件设计31.4下载验证41831.1触摸屏简介我们一般液晶所用的触摸屏,最多的就是电阻式触摸屏了(多点触摸属于电容式触摸屏,比如几乎所有智能机都支持多点触摸,它们所用的屏就是电容式的触摸屏),ALIENTEKTFTLCD自带的触摸屏属于电阻式触摸屏,下面简单介绍下电阻式触摸屏的原理。电阻式触摸屏利用压力感应进行控制。电阻触摸屏的主要部分是一块与显示器表面非常配合的电阻薄膜屏,这是一种多层的复合薄膜,它以一层玻璃或硬塑料平板作为基层,表面涂有一层透明氧化金属(透明的导电电阻)导电层,上面再盖有一层外表面硬化处理、光滑防擦的塑料层、它的内表面也涂有一层涂层、在他们之间有许多细小的(小于1/1000英寸)的透明隔离点把两层导电层隔开绝缘。当手指触摸屏幕时,两层导电层在触摸点位置就有了接触,电阻发生变化,在X和Y两个方向上产生信号,然后送触摸屏控制器。控制器侦测到这一接触并计算出(X,Y)的位置,再根据获得的位置模拟鼠标的方式运作。这就是电阻技术触摸屏的最基本的原理。电阻屏的特点有:1)是一种对外界完全隔离的工作环境,不怕灰尘、水汽和油污。2)可以用任何物体来触摸,可以用来写字画画,这是它们比较大的优势。3)电阻触摸屏的精度只取决于A/D转换的精度,因此都能轻松达到4096*4096。从以上介绍可知,触摸屏都需要一个AD转换器,一般来说是需要一个控制器的。ALIENTEKTFTLCD模块选择的是四线电阻式触摸屏,这种触摸屏的控制芯片有很多,包括:ADS7843、ADS7846、TSC2046、XPT2046和AK4182等。这几款芯片的驱动基本上是一样的,也就是你只要写出了ADS7843的驱动,这个驱动对其他几个芯片也是有效的。而且封装也有一样的,完全PINTOPIN兼容。所以在替换起来,很方便。ALIENTEKTFTLCD模块自带的触摸屏控制芯片为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。41931.2硬件设计本章实验功能简介:开机的时候先通过24C02的数据判断触摸屏是否已经校准过,如果没有校准,则执行校准程序,校准过后再进入手写程序。如果已经校准了,就直接进入手写程序,此时可以通过按动屏幕来实现手写输入。屏幕上会有一个清空的操作区域(RST),点击这个地方就会将输入全部清除,恢复白板状态。程序会设置一个强制校准,就是通过按KEY0来实现,只要按下KEY0就会进入强制校准程序。所要用到的硬件资源如下:1)指示灯DS02)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,满足条件,则认为读数正确,否则读数错误.420//该函数能大大提高准确度//x,y:读取到的坐标值//返回值:0,失败;1,成功。#defineERR_RANGE50//误差范围u8TP_Read_XY2(u16*x,u16*y){u16x1,y1;u16x2,y2;u8flag;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&&x1x2+ERR_RANGE)||(x1=x2&&x2x1+ERR_RANGE))//前后两次采样在+-ERR_RANGE内&&((y2=y1&&y1y2+ERR_RANGE)||(y1=y2&&y2y1+ERR_RANGE))){*x=(x1+x2)/2;*y=(y1+y2)/2;return1;}elsereturn0;}该函数采用了一个非常好的办法来读取屏幕坐标值,就是连续读两次,两次读取的值之差不能超过一个特定的值(ERR_RANGE),通过这种方式,我们可以大大提高触摸屏的准确度。另外该函数调用的TP_Read_XY函数,用于单次读取坐标值。TP_Read_XY也采用了一些软件滤波算法,具体见光盘的源码。接下来,我们介绍另外一个函数TP_Adjust,该函数源码如下://触摸屏校准代码//得到四个校准参数voidTP_Adjust(void){u16pos_temp[4][2];//坐标缓存值u8cnt=0;u16d1,d2;u32tem1,tem2;floatfac;u16outtime=0;cnt=0;POINT_COLOR=BLUE;BACK_COLOR=WHITE;LCD_Clear(WHITE);//清屏POINT_COLOR=RED;//红色LCD_Clear(WHITE);//清屏POINT_COLOR=BLACK;421LCD_ShowString(40,40,160,100,16,(u8*)TP_REMIND_MSG_TBL);//显示提示信息TP_Drow_Touch_Point(20,20,RED);//画点1tp_dev.sta=0;//消除触发信号tp_dev.xfac=0;//xfac用来标记是否校准过,所以校准之前必须清掉!以免错误while(1)//如果连续10秒钟没有按下,则自动退出{tp_dev.scan(1);//扫描物理坐标if((tp_dev.sta&0xc0)==TP_CATH_PRES)//按键按下了一次(此时按键松开了.){outtime=0;tp_dev.sta&=~(16);//标记按键已经被处理过了.pos_temp[cnt][0]=tp_dev.x;pos_temp[cnt][1]=tp_dev.y;cnt++;switch(cnt){case1:TP_Drow_Touch_Point(20,20,WHITE);//清除点1TP_Drow_Touch_Point(lcddev.width-20,20,RED);//画点2break;case2:TP_Drow_Touch_Point(lcddev.width-20,20,WHITE);//清除点2TP_Drow_Touch_Point(20,lcddev.height-20,RED);//画点3break;case3:TP_Drow_Touch_Point(20,lcddev.height-20,WHITE);//清除点3TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,RED);//画点4break;case4://全部四个点已经得到//对边相等tem1=abs(pos_temp[0][0]-pos_temp[1][0]);//x1-x2tem2=abs(pos_temp[0][1]-pos_temp[1][1]);//y1-y2tem1*=tem1;tem2*=tem2;d1=sqrt(tem1+tem2);//得到1,2的距离tem1=abs(pos_temp[2][0]-pos_temp[3][0]);//x3-x4tem2=abs(pos_temp[2][1]-pos_temp[3][1]);//y3-y4tem1*=tem1;tem2*=tem2;d2=sqrt(tem1+tem2);//得到3,4的距离fac=(float)d1/d2;422if(fac0.95||fac1.05||d1==0||d2==0)//不合格{cnt=0;TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE);//清除点4TP_Drow_Touch_Point(20,20,RED);//画点1TP_Adj_Info_Show(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//显示数据continue;}tem1=abs(pos_temp[0][0]-pos_temp[2][0]);//x1-x3tem2=abs(pos_temp[0][1]-pos_temp[2][1]);//y1-y3tem1*=tem1;tem2*=tem2;d1=sqrt(tem1+tem2);//得到1,3的距离tem1=abs(pos_temp[1][0]-pos_temp[3][0]);//x2-x4tem2=abs(pos_temp[1][1]-pos_temp[3][1]);//y2-y4tem1*=tem1;tem2*=tem2;d2=sqrt(tem1+tem2);//得到2,4的距离fac=(float)d1/d2;if(fac0.95||fac1.05)//不合格{cnt=0;TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE);//清除点4TP_Drow_Touch_Point(20,20,RED);//画点1TP_Adj_Info_Show(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//显示数据continue;}//正确了//对角线相等tem1=abs(pos_temp[1][0]-pos_temp[2][0]);//x1-x3tem2=abs(pos_temp[1][1]-pos_temp[2][1
本文标题:STM32开发指南V1.0-库函数版本(下册)
链接地址:https://www.777doc.com/doc-6360117 .html