基于STM32的触摸屏学习笔记
本文共有三个内容:一、电阻触摸屏的原理;二、XPT2046的控制字与数字接口;三、程序源码讲解(参考正点原子的代码)
一、电阻触摸屏的原理,上图:
![](../img/eep/emb/emb-79093b0kscdijdx0.jpg)
图上的文字介绍了触摸的原理,下面总结一下触摸的原理:
触摸屏工作主要是两个电阻屏(上下两层)在工作,如上图,当某一层电级加上电压时,会在该网络上形成电压梯度。如果有外力使得上下两层在某一点接触,则在未加电压的那一层可以测得接触点的电压,从而得出接触点的坐标(X或Y)。举个例子:当我们在上层的电极间(Y+和Y-)加上电压,则会在上层形成电压梯度(这里读者可以想想AD转换的原理),当有外力使得上下两层在某一点接触时,在底层X层就可以测得接触点处的电压(每个点电压都不同),再根据测得电压和电极电压的关系与距离成正比关系(看上图的关系式)就可以得到该点的Y坐标。然后,将电压切换到下层电极(X+和X-)上,并在顶层Y层上测量接触点的电压,从而得到X坐标。
原理说完了,不知道读者注没注意到上一段中提到 ‘要测得接触点的电压’,怎么测得电压还转换为数字呢?那就需要一个AD转换器,AD转换器在哪儿?下面就来介绍一下本文中的触摸屏控制芯片-XPT2046:4导线控制器;内含12位分辨率,125KHz转换速率逐步逼近型A/D转换器;支持从1.5V~5.25V的低电压IO接口。通过两次AD转换查出被按的屏幕位置。除此之外,该芯片还有内部自带2.5V参考电压作为辅助输入,温度测量和电池监测模式,电池监测的范围可以从0V~6V,功耗小等等。XPT2046引脚图如下:
![](../img/eep/emb/emb-79094shnfdi3cbsq.png)
二、XPT2046的控制字与数字接口:
![](../img/eep/emb/emb-790955zcjoqehxt3.png)
![](../img/eep/emb/emb-790964qaly3b0iql.png)
再来看XPT2046的数字接口(传输格式):
![](../img/eep/emb/emb-790974no34yjg5pa.png)
下面详细解释下XPT2046的转换时序:
1、为完成一次电压切换和AD转换,前8个时钟通过DIN引脚往XPT2046发8位控制字节(控制字);
2、转换器收到有关下次转换的足够信息之后,接着根据获得的信息设置输入多路选择器和参考源输入,并进入采样模式;
3、3个多时钟周期后,控制字节设置完成,转换器进入转换状态;
4、接着12个时钟周期你将完成真正的AD转换;
5、如果是度量比例转换方式(控制字节的第2位)=0,驱动器将一直工作,第13个时钟将输出转换结果的最后一位,剩下3个时钟完成转换器忽略的最后字节。
一次完整的转换需要24个串行同步时钟(DCLK)来完成。
三、程序源码讲解(参考正点原子的代码)
首先我们要知道触摸屏控制器XPT2046的哪些引脚与STM32的IO相连。在上文的XPT2046引脚图中,11,12,13,14,15,16引脚,13引脚(转换状态信号)不用;第二,我们这里不用笔中断(引脚11),而是将笔中断引脚接到了STM32的F10上。
注意:拿万用表测F10引脚,不触摸时输出3.3几V,触摸屏幕时,此引脚会输出低电平(0V)。其实我之前用的是示波器测的,不触摸时输出3.3几V,当触摸时,F10的输出电压会在几百mV到2V之间,不知道咋回事,折腾半天。可能是我不会使示波器。感兴趣的读者可以去测一测
1、通过模拟SPI时序往XPT2046中写一个字节void TP_Write_Byte(u8 num)
![](../img/eep/emb/emb-79098twpsvsu20nn.png)
和通过模拟SPI时序从XPT2046中读取adc值(AD转换结果)u16 TP_Read_AD(u8 CMD),
![](../img/eep/emb/emb-79099sgxxmbb5mhf.png)
这里说一下,形参CMD是命令控制字,详情第二讲。。这里我们可以CMD_RDX=0xD0和CMD_RDY=0x90传入CMD中,就是读取X方向的AD值时,把控制字的A2~A0配置为101,读取Y方向的AD值时,把控制字的A2~A0配置为001,都是选择12位模式,差分输入,低功率模式。
注意:这里提一下为什么要用差分输入模式:手册说,配置为差分输入模式可有效消除由于驱动开关的寄生电阻及外部的干扰带来的测量误差,提高转换精度。
一般来说我们要调用多次u16 TP_Read_AD(u8 CMD)这个函数,因为一次转换往往与真实值存在较大误差,故我们设定一个次数:READ_TIMES,多次转换。然后斩头去尾留中间,再取平均值,这样得到的AD转换结果就相当精确了。看函数u16 TP_Read_XOY(u8 xy)。
![](../img/eep/emb/emb-79100kqw00vd4aod.png)
2、还有u8 TP_Read_XY(u16 *x,u16 *y)就是同时读取X、Y的AD转换值,是上一个函数u16 TP_Read_XOY(u8 xy)的升级版~
而u8 TP_Read_XY2(u16 *x,u16 *y)是连续两次读取X和Y的AD转换值,并将有效的AD值存入*x和*y指向的内存中,这样得到的AD值就很准确了,再通过相应的比例计算就可以转换为实际坐标了。。
![](../img/eep/emb/emb-79102rbvlnf0izi4.png)
——————————————————————— 华丽分割线 ———————————————————————————
上面
- STM32学习笔记:在IAR中建立FWlib 3.0项目(08-13)
- 基于STM32单片机的火控系统信号采集测试(11-14)
- 基于LabVIEW的STM32调试平台设计(11-17)
- 基于STM32的LF RFID识别系统设计(11-25)
- STM32中断与嵌套NVIC快速入门(01-25)
- 基于TLC5947的旋转LED屏显示控制器设计(01-25)