STM32 CortexM4 主控板触摸屏保姆级别总结

2023-10-14 13:50

本文主要是介绍STM32 CortexM4 主控板触摸屏保姆级别总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、实物图

二、触摸屏种类分类

   电阻式屏幕

特点:定位准确且可以实现单点触摸;电阻式屏幕是一种传感器,它将矩形区域的触摸点的物理位置转换为代表X/Y轴的电压,现在很多的LCD屏幕都是采用了电阻式的触摸屏,这种屏幕可以用5、6、7、8线来产生偏置电压,同时可以读回触摸点的电压。

电阻式触摸屏是一种传感器,基本上是薄膜加上玻璃的结构,薄膜和玻璃相邻的一面上均涂有ITO(纳米铟锡金属氧化物)涂层,ITO具有很好的导电性和透明性。当触摸操作时,薄膜下层的ITO会接触到玻璃上层的ITO,经由感应器传出相应的电信号,经过转换电路送到处理器,通过运算转化为屏幕上的X、Y值,而完成点选的动作,并呈现在屏幕上。

其优缺点也很明显,缺点是他只能支持单点触摸,不能实现多点触发触摸功能;但是由于这个单点触摸的特点,使得它触摸的精度很高。


  1.  

电感式触摸屏

支持多点触摸,价格偏贵。工业应用最广泛,我们现在市面上的手机都是感应式的触摸屏,它的优缺点是跟电阻式的触摸屏相反,优点是可以实现多点感应,而缺点就是精度没那么高。

  

 红外线式

特点是:价格十分低廉,但其外框易碎,容易产生光干扰,曲面情况下失真,所以一般情况下我们不会选择这样的触摸屏。这个一般用在特殊的工艺。

表面声波式

特点是:可以解决各种缺点,但是屏幕表面如果有水滴和尘土会使触摸屏变的迟钝。

XPT2046采集触摸AD芯片

   触摸屏接口连接原理

 

XPT2046特性

工作电压范围为2.2V-5.25V,支持1.5V~5.25V的数字IO口,内建2.5V参考电压源;
电源电压测量(0V-6V)内建结温测量功能触摸压力测量;
采用SPI3线控制通信接口且有自动power-down功能;
封装:QPN-16.TSSOP-16和VFBGA-48与TSC2046、AK4182A完全兼容

XPT2046结构原理

 

 XPT2046引脚

屏幕X/Y坐标的输入+/-端

 

 

 应用引脚

 

 使用到的引脚

看原理图,我们知道,有红框圈起来的引脚要用我们进行配置:

 

T_MISO  PB2 引脚

        XPT2046的串行数据输出端。STM32的数据输入端,数据在DCLK的下降沿                                   移出,当CS高电平时为高阻状态,配置为输入模式,空闲为高。

T_PEN   PB1引脚

       笔中断输出,配置为输入模式,空闲模式为高电平;

T_CS     PC13引脚

     片选信号。控制转换时序和使能串行输入输出寄存器,高电平时ADC掉电;

T_MOSI   PF11引脚

     XPT2046的串行数据输入端,STM32的输出端,当CS为低电平时,数据在DCLK上升沿锁存进来;

T_SCK   PB0引脚

      XPT2046外部时钟信号输入,STM32的时钟信号输出;

小结

  STM32发数据的时候,片选拉低,DCLK拉高,把数据锁存在T_MOSI引脚传输出去;当STM32读数据的时候,片选拉低,DCLK拉低,读取T_MISO电平状态。

XPT2046控制说明

单端还是差分模式

选择VBAT、 Temp和AUX时可以配置为单端模式,作为触摸屏应用时,可以配置为差分模式,这可有效消除由于驱动开关的寄生电阻及外部的干扰带来的测量误差,提高转换准确
度。

 

笔中断输出

有人按下屏幕时,触摸屏下拉到地,也就是按下为低电平

 

控制字节

用于选择采集的是X还是Y轴的AD值,作用:控制字节由 DIN 输入的控制字如表 3 所示,它用来启动转换,寻址,设置 ADC 分辨率,配置和对 XPT2046 进行掉电控
制。

代码实例

 扫描触摸屏

touch:存放读取到的x/y坐标值,返 回 值 : 0:有按下;1:无按下

********************************************************************************/ 
unsigned char Xpt2046_ScanTouch(Touch_Typedef *touch)
{Touch_Typedef ad;unsigned char ucRetVaule;if(T_PEN == 0){				//判断触摸屏有没有被按下if(T_PEN == 0){Xpt2046_ReadXYAD(&ad);touch->xval = ad.xval * Kx + Bx;touch->yval = ad.yval * Ky + By;ucRetVaule = 0;}}else{touch->xval=0xffff;touch->yval=0xffff;ucRetVaule = 1;}return ucRetVaule;
}

 

读取X/Y轴AD值,并滤波处理


void Xpt2046_ReadXYAD(Touch_Typedef *touch)
{unsigned char i, j;unsigned short adx[5], ady[5];unsigned short temp;for(i=0; i<5; i++){		//先采集多次数据adx[i] = Xpt2046_ReadAD(0xd0);ady[i] = Xpt2046_ReadAD(0x90);}for(i=0; i<5; i++){		//先排序,找出最大和最小的值for(j=0; j<5-i-1; j++){if(adx[j] > adx[j+1]){temp = adx[j];adx[j] = adx[j+1];adx[j+1] = temp;}if(ady[j] > ady[j+1]){temp = ady[j];ady[j] = ady[j+1];ady[j+1] = temp;}}}touch->xval = adx[2];touch->yval = ady[2];
}

读取轴AD值

unsigned short Xpt2046_ReadAD(unsigned char cmd)
{unsigned char vh, vl;T_CS = 0;				//拉低片选,选中器件,开始通信Xpt2046_WriteByte(cmd);	//发送测量命令Delay_Us(1);			//等到芯片忙结束vh = Xpt2046_ReadByte();//读取数据的高位vl = Xpt2046_ReadByte();//读取数据的低位T_CS = 1;				//拉低片选,取消选中,结束通信return ((vh<<8|vl)>>4);	//返回结果,其中只有12位有效
}

触摸屏校准函数

这个可以通用,需要的直接复制就好了

void Xpt2046_TouchAdjust(void)
{unsigned short lcd_pos[4][2] = {20, 20, 300, 20, 20, 460, 300, 460, };Touch_Typedef touch_pos[4];				//用来存放x,y的4个AD值unsigned char i, j;double len1 = 0.00f, len2 = 0.00f;Lcd_ShowString(30, 130, "touch adjust start", RED, WHITE, 16);while(1){for(i=0; i<4; i++){					//读取4个对应的触摸屏坐标for(j=0; j<30; j++){			//画一个十字架Lcd_DrawPoint(lcd_pos[i][0]-15+j, lcd_pos[i][1], RED);Lcd_DrawPoint(lcd_pos[i][0], lcd_pos[i][1]-15+j, RED);}printf("等待校验\r\n");while(T_PEN == 1);				//等待按下触摸屏 Delay_Ms(50);					//延时50ms待数据稳定printf("按下触摸屏\r\n");Xpt2046_ReadXYAD(&touch_pos[i]);//获得触摸屏测量的x,y轴数值while(T_PEN == 0); 				//等待松开手Delay_Ms(200);for(j=0; j<30; j++){			//清掉十字架图标Lcd_DrawPoint(lcd_pos[i][0]-15+j, lcd_pos[i][1], WHITE);Lcd_DrawPoint(lcd_pos[i][0], lcd_pos[i][1]-15+j, WHITE);}}//校验坐标-计算点击的触摸点是否正确  如果不正确重新校准//水平两个点之间的距离比较		len1 = (float)sqrt((touch_pos[1].xval-touch_pos[0].xval)*(touch_pos[1].xval-touch_pos[0].xval) \+ (touch_pos[1].yval-touch_pos[0].yval)*(touch_pos[1].yval-touch_pos[0].yval));len2 = (float) sqrt((touch_pos[3].xval-touch_pos[2].xval)*(touch_pos[3].xval-touch_pos[2].xval) \+ (touch_pos[3].yval-touch_pos[2].yval)*(touch_pos[3].yval-touch_pos[2].yval));		if(((len1/len2)<0.95) || ((len1/len2)>1.05)){continue; 	}//垂直两个点之间的距离比较len1 = (float)sqrt((touch_pos[2].xval-touch_pos[0].xval)*(touch_pos[2].xval-touch_pos[0].xval) \+ (touch_pos[2].yval-touch_pos[0].yval)*(touch_pos[2].yval-touch_pos[0].yval));len2 = (float)sqrt((touch_pos[3].xval-touch_pos[1].xval)*(touch_pos[3].xval-touch_pos[1].xval) \+ (touch_pos[3].yval-touch_pos[1].yval)*(touch_pos[3].yval-touch_pos[1].yval));		if(((len1/len2)<0.95) || ((len1/len2)>1.05)){continue;	//点击的点不符合要求}		//对角线两个点之间的距离比较len1 = (float)sqrt((touch_pos[3].xval-touch_pos[0].xval)*(touch_pos[3].xval-touch_pos[0].xval) \+ (touch_pos[3].yval-touch_pos[0].yval)*(touch_pos[3].yval-touch_pos[0].yval));len2 = (float)sqrt((touch_pos[2].xval-touch_pos[1].xval)*(touch_pos[2].xval-touch_pos[1].xval) \+ (touch_pos[2].yval-touch_pos[1].yval)*(touch_pos[2].yval-touch_pos[1].yval));		if(((len1/len2)<0.95) || ((len1/len2)>1.05)){continue;}	//计算校准参数   Kx (Ky)--斜率;Bx(By) --偏移量//计算x映射 Xlcd = Kx * touch_x + BxKx = (float)(lcd_pos[1][0]-lcd_pos[0][0]) / (touch_pos[1].xval-touch_pos[0].xval);Bx = lcd_pos[0][0] - Kx*touch_pos[0].xval;//计算y映射 Ylcd = Ky*touch_y + ByKy = (float)(lcd_pos[2][1]-lcd_pos[0][1]) / (touch_pos[2].yval-touch_pos[0].yval);By = lcd_pos[0][1] - Ky*touch_pos[0].yval;     Lcd_Fill(0, 0, 320, 480, WHITE);Lcd_ShowString(30, 130, "touch adjust OK", RED, WHITE, 16);printf("校准参数 Ky=%f;Kx=%f;By=%d;Bx=%d;\r\n",Ky, Kx, By, Bx);Delay_Ms(1000);Delay_Ms(1000);Lcd_Fill(0, 0, 320, 480, WHITE);break;				}	
}

这篇关于STM32 CortexM4 主控板触摸屏保姆级别总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/210921

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

Centos7安装JDK1.8保姆版

工欲善其事,必先利其器。这句话同样适用于学习Java编程。在开始Java的学习旅程之前,我们必须首先配置好适合的开发环境。 通过事先准备好这些工具和配置,我们可以避免在学习过程中遇到因环境问题导致的代码异常或错误。一个稳定、高效的开发环境能够让我们更加专注于代码的学习和编写,提升学习效率,减少不必要的困扰和挫折感。因此,在学习Java之初,投入一些时间和精力来配置好开发环境是非常值得的。这将为我

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

二分最大匹配总结

HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter

整数Hash散列总结

方法:    step1  :线性探测  step2 散列   当 h(k)位置已经存储有元素的时候,依次探查(h(k)+i) mod S, i=1,2,3…,直到找到空的存储单元为止。其中,S为 数组长度。 HDU 1496   a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 。 x在 [-100,100] 解的个数  const int MaxN = 3000

状态dp总结

zoj 3631  N 个数中选若干数和(只能选一次)<=M 的最大值 const int Max_N = 38 ;int a[1<<16] , b[1<<16] , x[Max_N] , e[Max_N] ;void GetNum(int g[] , int n , int s[] , int &m){ int i , j , t ;m = 0 ;for(i = 0 ;

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

go基础知识归纳总结

无缓冲的 channel 和有缓冲的 channel 的区别? 在 Go 语言中,channel 是用来在 goroutines 之间传递数据的主要机制。它们有两种类型:无缓冲的 channel 和有缓冲的 channel。 无缓冲的 channel 行为:无缓冲的 channel 是一种同步的通信方式,发送和接收必须同时发生。如果一个 goroutine 试图通过无缓冲 channel

9.8javaweb项目总结

1.主界面用户信息显示 登录成功后,将用户信息存储在记录在 localStorage中,然后进入界面之前通过js来渲染主界面 存储用户信息 将用户信息渲染在主界面上,并且头像设置跳转,到个人资料界面 这里数据库中还没有设置相关信息 2.模糊查找 检测输入框是否有变更,有的话调用方法,进行查找 发送检测请求,然后接收的时候设置最多显示四个类似的搜索结果