基于XPT2046的电阻式触摸屏设计

  • 学习29105次

简介:

XPT2046是一款四线制电阻触摸屏控制芯片,由深圳市矽普特科技有限公司研发生产,被广泛的应用于触摸屏驱动,堪称经典之作!

XPT2046-1

xpt2046-2

接线方法:

1、9、10引脚接VCC,6引脚接GND,2、3、4、5引脚接触摸屏的4条引脚线,16、15、14、12引脚接单片机SPI引脚,11接单片机某个引脚。

工作原理:

把XPT2046第11引脚接到单片机的引脚设置为中断引脚,触摸屏没有被触摸时,11引脚保持高电平,当有触摸屏被触摸时,11引脚变为低电平。所以单片机检测11引脚的高低电平,就可以知道有没有触摸屏触摸事件发生。如果发生了触摸屏按下事件,单片机通过SPI口,首先发送读取X坐标的命令0X90,然后读出2个字节的数据,然后再发送读取Y坐标的命令0XD0,然后再读出2个字节的数据。这时候,XY的坐标值就知道了,因为XPT2046是12位精度的ADC,所以读出的2个字节中,只有高12位是有效数据。

校准流程:

触摸液晶屏的4个角,采集X和Y坐标的12位值。这时候,就分别得到了X坐标和Y坐标的最小值和最大值,根据液晶屏的分辨率,再通过数学等比公式,就可以通过采集得到的12位ADC值得出现在触摸到屏幕的哪个点了。

……………………………………………………………………..

对于一个资深级的电子人,看了我上面的表述,就知道XPT2046怎么用了。但是,对于小白的你,上面的表述对你而言就是雾里看花。不要着急,下面我给你从0补起。

首先,你要知道,我上面所讲的内容是:使用XPT2046驱动4线电阻式触摸屏。那么,你见过4线电阻式触摸屏吗?没见过怎么办?好办啊!请看下图:

电阻式触摸屏

大部分的电阻式触摸屏,都是4线制的,就是引出了4条线的意思。我随便找了一个,请看下图:

电阻式触摸屏2

看它引出的排线,共4条线,所以是4线制的,也就是说,这个触摸屏,就可以用XPT2046驱动。

瑞生(Ration)的2.4寸TFT上面所配的触摸屏,也是4线制的,如下图所示:

电阻式触摸屏3

上图中,红色圆圈就是电阻式触摸屏的4条引脚。

看到这里,你就赚了,你已经认识了电阻式触摸屏的真面目了,这就是工作单位要的工作经验,想要更多干货,请继续往下看吧。

现在来看看,XPT2046怎么与它连接?

1.电源

作为一个芯片,肯定有VCC和GND,就是要给它供电。我们首先要看它的datasheet上供电的范围,如下图所示:

xpt2046特性

由datasheet可以看出。此芯片的供电电压,我们使用常用的3.3V和5V电源都可以。再加上“支持1.5V~5.25V的数字I/O口”特性。就是说,我们常用的5V的和3.3V的单片机,都可以作为他的控制器了,是不是在单片机选型上放宽很多了?

2.与触摸屏的连接

我们发现,XPT2046的2、3、4、5脚名称为XP、YP、XN、YN。P就是Positive,“正”的意思;N就是Negative,“负”的意思。所以有时候,你会看到引脚名称写法为X+、Y+、X-、Y-。这四个引脚,就是连接触摸屏的四个引脚。当你买触摸屏的时候,你的触摸屏商家就会告诉你触摸屏上的引线名称。如下图所示:

电阻式触摸屏引脚

3.与单片机(MCU)的连接

XPT2046与单片机采用SPI连接。分别为引脚16:DCLK(SPI时钟引脚);引脚15:CS(使能引脚或者叫做片选引脚);引脚14:DIN(数据输入引脚);引脚12:DOUT(数据输出引脚)。有些单片机上,带SPI,有些单片上,不带SPI。带SPI模块的单片机,可以配置SPI模块与XPT2046通信。不带SPI模块的单片机,可以随便找4个引脚,模拟SPI时序,与XPT2046通信。

除了SPI通信的4个引脚,还有一个引脚必须接:PENIRQ。当触摸屏有触摸事件发生,这个引脚就会拉低,所以我们把这个引脚接到单片机的某个中断引脚,就可以随时发现触摸屏有被按下。

XPT2046的SPI时序如下图所示:

XPT2046时序图

BUSY是XPT2046的引脚13,是“忙时信号线”。

时序图分析:单片机把CS引脚拉低,开始SPI通信。DIN引脚发送1字节命令后,BUSY引脚拉高等待XPT2046内部ADC模块转换,转换结果完成后,BUSY引脚自动拉低,这时,可以通过DOUT引脚读出转换好的2字节数据,就是16个位,其中,高12位是有效数据,低4位无效。其中BUSY引脚可以用“延时一段时间”来代替,节省单片机引脚资源。这段文字,用单片机4个引脚模拟SPI程序表示就是:

    CS=0;
    SCK=0;  
    for(i=0;i<8;i++) // 发送1字节读取命令
    {
        if(Read&0x80)
        MOSI = 1;
        else MOSI = 0;
        Read<<=1;
        SCK = 0;    
        SCK = 1;
    }
    delay_us(6);
    SCK = 1;    
    SCK = 0;       
    for(i=0;i<16;i++) // 接收2字节结果
    {                   
        Num<<=1;      
        SCK = 0;                  
        SCK = 1;
        if(DOUT==1)Num++;          
    }      
    Num>>=4;  // 结果右移4位,获取高12位有效数据        
    CS=1

以上程序中,Read是读取命令,Num是最后得到的值。读取X坐标的命令是0XD0,读取Y坐标的命令是0X90。这个命令从哪里来?这个就要看datasheet了。看时序图中的DIN命令字节,如下图所示:

XPT2046命令字

关于命令字里面每个位的意义,datasheet上是这么说的:

xpt2046命令字解释

bit0和bit1选择功耗,00或11都可以,bit2我们选择差分输入模式,bit3选择12位分辨率,bit7必须为1,由下图(差分模式输入配置)可以看出,测量X坐标A2 A1 A0是001,测量Y坐标A2A1A0是101,最后就可以得出读取X坐标的命令是0XD0,读取Y坐标的命令是0X90。

XPT2046差分输入模式

4.分辨率的转换

以瑞生(Ration)2.4寸TFT上的液晶屏为例,此屏分辨率是240*320,直白的说,就是此屏横着有240个点,竖着有320个点,因为此屏是真彩屏,所以每个点都可以产生不同的颜色。当我们给此屏上面加上触摸屏,就可以用程序来感知用户按下了屏幕的哪个位置。

首先测试屏幕的X坐标,从左往右依次点击屏幕,发现,得到的值由1900左右逐渐递减到165左右;然后测试屏幕的Y坐标,从上到下依次点击屏幕,发现,得到的值由1900左右逐渐递减到150左右。由此得出结论,该触摸屏的原点在右下角。由于我们的液晶屏是以左上角为原点的,所以需要借助数学知识转换一下。

void Change_XY(void)
{
    X=(240-(X_ADC-165)/7.229); 
    Y=(320-(Y_ADC-165)/5.422);
}

此公式如何得到的?(不要和我说你的数学老师走得早……)

首先,看横坐标。液晶屏的坐标是从0~240,触摸屏的值是从1900到165,如何按一下触摸屏,就可以由采集到的触摸屏值,得到所在液晶屏的位置?

然后,看纵坐标。液晶屏的坐标是从0~320,触摸屏的值是从1900到150,如何按一下触摸屏,就可以由采集到的触摸屏值,得到所在液晶屏的位置?

横纵坐标,原理都一样。以横坐标为例讲解。假设现在的横坐标是由240~0,对应的触摸屏的值是1900~165,你会不会把触摸屏的任何一个值对应到240~0之中呢?还不会?再听我讲。你首先把1900~165转换成1735~0,即把每个测量到的值都减去165:X_ADC-165。1735~0对应240~0,现在测得1000,对应240~0中的多少?这应该会了吧?两种方法求解,第一种,等比公式,即:X/240=1000/1735,问X=?显然,X=1000*240/1735=138;第二种,斜率计算法,这里面,有一个斜率,即1735/240=7.229,用1000/7.229=138。两种方法都可以得到结果。这里我们使用斜率的方法。即X=(X_ADC-165)/7.229;现在把240~0的值转换成0~240的值,只需一步:即X=240-((X_ADC-165)/7.229)。同理,可以得出Y的公式。

提示:每一批触摸屏的ADC值都有一些出入,所以你可以按照我给你的上述方法,自行校正触摸屏的精度。

5.总结

现在,你可以用XPT2046+单片机的方式,给你家的任何一个地方安装触摸屏了。这些地方可以是电器上、墙上等你能想到的地方。你可以用单片机检测触摸区域后给出任何你想要的动作,这些动作可以是打开点灯等。祝你成功!

发表评论

关闭菜单