电容触摸屏原理:当手指触摸屏幕时,手指与导电涂层之间形成了一个微小的电容。传感器会检测这个电容的变化,并将其转化为触摸信号。
电阻触摸屏原理:主要基于电阻效应,即当触摸屏被触摸时,触摸点处的导电层之间会形成一个电阻,导致电流通过。
电容触摸屏比电阻触摸屏贵一些,电阻只能支持单点触碰,电容屏支持多点,可以通过这个去判断到底是电阻屏还是电容屏。而且电阻触摸屏要大力触碰才可以感应到,电容屏相对而言用比较小的力就可以。
概论
本博客主要说一下电阻屏,电阻屏有两个ITO图层,两个ITO图层的两端分别引出X-/X+/Y-/Y+四个电极,
一个叫X层,一个叫Y层,当触摸屏被按下时,两个ITO层相互接触,从触点处把ITO层分为两个电阻,且由于ITO层均匀导电,两个电阻的大小与触点离两电极的距离成比例关系,利用这个特性,可通过以下过程来检测坐标。
STM32F103的电阻屏控制器原理图如下
右侧的是SPI的几个引脚可与STM32的排针相连,之后通讯;
PENIRQ是中断引脚, 表示有触摸信号;
左边引脚用于检测触摸信号的位置;
电阻屏的原理框图如下:
左下部分我们可以联想到刚刚说的,想测X方向电压时我们可以令X+=3.3V,X-=GND,然后让ADC 去检测触点处电压。与XN/YN/XP/YP相连的是mos管,可以看作是开关,而开关受到控制逻辑的控制,控制逻辑受控于最右侧的那些引脚,比如我们触摸电阻屏产生PENIRQ中断之后就会去控制XN/YN/YP/XP的电压去测具体位置。
PENIRQ跳变到低电平时就提醒我们要去通过SPI发送一个控制字给控制逻辑进行触摸位置的检测了。控制字有八位,
第7位为1的时候会开启检测
第3位MODE用于控制是八位还是十二位(12位的精度低但速度快)的分辨率,一般配置成0(0是2位的)
1-0位是用来配置是否节省电源的,配置成00的时候节省电源,
第6-4位是最重要的 意义如下(需要结合第二位是高电平还是低电平,低电平看下面那个表)
我们以下面那个图为例,X+下面是in,意思是给X+输入电压源,Y-下面是measure,意思是用于测量,那么也就是说当A2-A0为001的时候,要给X+输入电压源,让Y+去检测,可以用于检测X方向的电压值
同理我们可以配置A2-A0为101去检测Y方向的电压。
所以我们如果要检测Y方向的电压值就要把控制字设置成11010000(也就是0xD0),X方向配置成0x90(10010000)
看板子的原理图查引脚可知,我们没用到硬件spi 用到的是fsmc 所以我们要软件模拟spi的时序
新建touch文件 配置引脚 因为没有用到硬件spi所以不用复用功能
DCLK-------推挽输出 DOUT———输出 DIN----------输入
CS——推挽输出 PENIRQ——输入
SPI的配置:
引脚的通讯要用到SPI,SPI的通讯过程是通讯开始先让CS变成低电平 时钟一直间歇输出方波,0方波,0……MOSI,MISO是作为数据的输入输出,
所以我们可以定义一些宏
【图中CS对应的setbit是低电平,最后一行MISO是去读取从机数据,所以用readinputdatabit函数,读取SPI_MISO_PIN的值返回去】
前面提到我们一摸触摸屏,PENIRQ就会变成低电平 ,所以我们可以通过这个去检测是否被触摸
之后配置模式
初始化配置好之后就去配置模拟时序 我们在开始的时候配置CS高电平持续一段时间后,变成低电平,之后我们要设置数据,再发送八个时钟(因为是在时钟上升沿就去采样,所以要准备好数据),用刚刚的宏定义CLK_HIGH(),CLK_LOW()【由于不知道一开始的时钟是不是高电平,所以要在配置CS引脚的时候顺便配置成低电平电平】
可以去数据手册看一下是什么时候进行采样,
,如图是在上升沿采样,所以我们要在时钟设置之前去设置数据(即MOSI_1函数、MOSI_0函数,电平高低取决于输入的cmd),【下面函数的最后一行片选取消的需要注释掉】
同理写一个接收函数,读取ADC值,由于相应的ADC是12位的,所以用uint16_t去装它
由图可见,在上升沿的时候DOUT已经有数据了,我们可以和刚刚发送的函数一样 去for一个循环,当作是时钟,而且既然是接收就得去设一个数组去接收adc发过来的值,注意发送和接收相隔一个时钟
状态机编程(用于检测双击、单击、长按、短按)
可以define一个输出TOUCH_PRESSED和TOUCH_NOT_PRESSED,然后定义一个枚举变量TOUCH_STATE用于存放各种状态量
按键按下就是TOUCH_PRESSED,按键按下会有抖动,消抖的逻辑是如果检测到是低电平之后再过一会去检测看看还是否是低电平。如果是的话就说明按键被按下。
一般都是循环调用刚刚写的touch_detect(),用法如下:
不用状态机也可以直接用PENIRQ去检测按下与否:即如果PENIRQ是高电平就是没按下,低电平就是按下了
触摸画板实操(建议去看野火网课效果更好)
配置模拟SPI
这个程序里是一直让片选引脚拉低,就不用像我们之前一样去看时序图让引脚一会低位一会高位,两种方法都可以
配置发送函数(写函数)
其实和我们之前写的read函数是差不多的,右移到最低位和0x01与,看看结果是否为1,为1就发送1,
接收时有:
检测时有:
触摸中断:检测到按下的时候就亮绿灯,获取触摸坐标等
释放亮蓝灯
以上的TouchEvenHandle函数是在mian里循环调用的,strType_XPT2046_Coordinate定义如下
其中按下时的处理函数有:
其中Draw_Trail里的pre_x指的是上一次的坐标点,可以修改这个函数里的内容自己去写一些应用
再回到刚刚触摸中断那里,里面的touchedPoint函数,它是利用一个电阻屏校准电压算法去算的,需要通过一开始出现的那些校准程序的配合(一开始会让我们去点一些屏幕上出现的点),然后校准电压算法进行匹配,得到一个能将触摸电压转换成具体位置的公式
第一个参数用于存放算出来的逻辑坐标,第二个参数是用于存放ADC扫描屏幕出来的物理坐标参数,之后会经过运算得出逻辑上的坐标轴数据存在第一个参数里,第二个参数如下图
上图由函数获得
打开这个函数的声明,里面最重要的是Touch_Calibrate()函数,主要是用于显示一开始屏幕上用于校验的十字交叉点,完整的main函数如下
画按钮的函数如下,被包含在Palette函数里
最后这个触摸画板的部分建议去B站看野火的视频,有很多细节要看视频才能理解,本文仅做概述