XPT2046是一款四线制电阻触摸屏控制芯片,由深圳市矽普特科技有限公司研发生产,被广泛的应用于触摸屏驱动,堪称经典之作!他内含12位分辨率125KHz转换速率逐步逼近型A/D转换器,支持从1.5V到5.25V的低电压I/O接口。能通过执行两次A/D转换查出被按的屏幕位置, 除此之外,还可以测量加在触摸屏上的压力。( e1 W9 t8 x4 E2 v, c$ { / h2 J/ n U+ Y0 c0 P) R" O" F ' {" D, | H) D* W2 p) Y. d 连接方法:. g4 J9 o- c+ m% T " p; ]5 Q# L+ o# @ 说明:1、9、10引脚接VCC,6引脚接GND,2、3、4、5引脚接触摸屏的4条引脚线,16、15、14、12引脚接单片机SPI引脚,11接单片机某个引脚。2 f- x7 i; @8 D( n9 E' i6 |# ?! L 工作原理:7 U8 f d1 e; H; x 把XPT2046第11引脚接到STM32单片机的引脚设置为中断引脚,触摸屏没有被触摸时,11引脚保持高电平,当有触摸屏被触摸时,11引脚变为低电平。所以用STM32单片机检测11引脚的高低电平,就可以知道有没有触摸屏触摸事件发生。如果发生了触摸屏按下事件,单片机通过SPI口,首先发送读取X坐标的命令0X90,然后读出2个字节的数据,然后再发送读取Y坐标的命令0XD0,然后再读出2个字节的数据。这时候,XY的坐标值就知道了,因为XPT2046是12位精度的ADC,所以读出的2个字节中,只有高12位是有效数据。 关于触摸校准: 触摸液晶屏的4个角,采集X和Y坐标的12位值。这时候,就分别得到了X坐标和Y坐标的最小值和最大值,根据液晶屏的分辨率,再通过数学等比公式,就可以通过采集得到的12位ADC值得出现在触摸到屏幕的哪个点了。+ y2 i# V' ?2 t; h" ?3 _7 i+ G: a5 t ……………………………………………………………………..% w+ G5 z! I; A- Z z$ H: W: N 对于一个资深级的电子人,看了我上面的表述,就知道XPT2046怎么用了。但是,对于小白的你,上面的表述对你而言就是雾里看花。不要着急,下面我给你从0补起。2 A9 ~" m/ B8 s4 A+ o 首先,你要知道,我上面所讲的内容是:使用XPT2046驱动4线电阻式触摸屏。那么,你见过4线电阻式触摸屏吗?没见过怎么办?好办!请看下图: 大部分的电阻式触摸屏,都是4线制的,就是引出了4条线的意思。我随便找了一个. t! O0 j2 `1 b: ]: x! I$ a4 e 3 l; A! E' D4 R 看它引出的排线,共4条线,所以是4线制的,也就是说,这个触摸屏,就可以用XPT2046驱动。 看到这里,你就赚了,你已经认识了电阻式触摸屏的真面目了,这就是工作单位要的工作经验,想要更多干货,请继续往下看吧。7 o! ~1 N8 n) m+ f 从前面我们了解到,此芯片的供电电压是常用的3.3V和5V电源都可以。再加上“支持1.5V~5.25V的数字I/O口”特性。就是说,我们常用的5V的和3.3V的单片机,都可以作为他的控制器了,有没有觉得在单片机选型上放宽很多了? XPT2046与MCU连接: XPT2046与单片机采用SPI连接。分别为引脚16:DCLK(SPI时钟引脚);引脚15:CS(使能引脚或者叫做片选引脚);引脚14:DIN(数据输入引脚);引脚12:DOUT(数据输出引脚)。带SPI模块的单片机,可以配置SPI模块与XPT2046通信。不带SPI模块的单片机,可以随便找4个引脚,模拟SPI时序,与XPT2046通信。 除了SPI通信的4个引脚,还有一个引脚必须接:PENIRQ。当触摸屏有触摸事件发生,这个引脚就会拉低,所以我们把这个引脚接到单片机的某个中断引脚,就可以随时发现触摸屏有被按下(用外部中断)。 XPT2046的SPI时序# N( X, c+ y' ^9 V: y, V7 B1 ? - r, f5 @3 o& F3 S9 h7 q BUSY是XPT2046的引脚13,是“忙时信号线”,我们没有用到,不接 : G! e( j! b1 Y2 a/ Z 当我们读出了触摸屏的ADC值后,就可以把它对应到TFT LCD上了 最后提醒朋友们,使用外部中断别忘了打开AFIO复用时钟。 来看看触摸画板的效果吧% S& H5 I% m6 M/ R, l 画的丑了点,轻喷. V1 U/ Z4 W0 s4 T( y. z" }0 N 这是MDK的工程 |
{9 C7 }+ `# f9 T1 i2 |
GPIO_InitTypeDef GPIO_InitStructure;
) e7 z( R( k* J9 j; B+ r( S
//下面是SPI相关GPIO初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;- q2 Y2 l- s, N$ U8 F |9 M
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;# m8 R, p5 E i7 D- `& x3 X0 V
GPIO_Init(GPIOA,&GPIO_InitStructure);
//下面是SPI相关GPIO初始化: j1 g" p+ l! s; Z; S. X! A, a
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;- T' p M4 | V ]8 p4 J6 [) }3 K
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOA,&GPIO_InitStructure);" o2 i, `/ P2 s9 V3 ?. g! Q
//Configure PC6 pin: TP_CS pin
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; 5 L" `4 @0 x9 b
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
3 z% b/ Z; z4 L& v; d- W
//Configure PC4 pin: TP_INT pin 0 m" r. f! P$ Q% T& }
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入; x, \# C' K/ B. X1 o+ K7 {: K% C
GPIO_Init(GPIOC,&GPIO_InitStructure);
} 9 Q, S: Q2 E1 h9 z/ a
模拟+中断的方式
是MDK的,我确定