【STM32】XPT2046四导线触摸屏控制器 SPI驱动
简介
XPT2046 是一款 4 导线制触摸屏控制器,内含 12 位分辨率 125KHz转换速率逐步逼近型 A/D转换器。XPT2046支持从 1.5V 到 5.25V 的低电压 I/O 接口。XPT2046 能通过执行两次 A/D转换查出被按的屏幕位置, 除此之外,还可以测量加在触摸屏上的压力。
芯片的封装![](/assets/blank.gif)
功能简介
温度检测
XPT2046 集成温度检测功能,用于温度的检测。XPT2046 的温度测量有两种方法
方法1:
利用二极管的 PN 结温度系数相对稳定的特点,通过测试二极管的 PN 结电压来测量温度,可以预先测试并存储室温下的 PN 结电压(典型值为 600mV 左右),PN 结的温度系数约为-2mV/℃,测试其他温度时的 PN 结电压,就可以得到温度。
这种方法测试出的温度随工艺的变化有较大变化,而且需要校正。
方法2:
这种方法不要求指定测试温度基准,精确度可以达到 2℃。这种方法需要进行二次转换:
第一次,设置“A2A1A0”=“000”,测试 temp0 电流时的 PN 结电压 V0
**第二次,设置“A2A1A0”=“111”,实现 91 倍 temp0 大的电流,测试此时的 PN 结电压 V1。**第二次和第一次转换的电压差可以通过等式(1)表示:
其中:
N——电流比率系数,等于 91;
k——伯尔兹曼常数,等于 1.38054 × 10-23 伏特每开(V· K-1);
q——电荷量,等于 1.602189·10-19C
T——温度值(开尔文)
压力检测
XPT2046 也能对触摸的压力进行处理。为了判断触摸物体是笔还是手指,有必要对触摸压力进行测量。一般而言,这种测量的性能要求不高,所以采用 8 位分辨率模式
方法1:
需要知道 X 面板的电阻,X 位置的测量值,触摸屏两附加面板之间的测量值(Z1 和 Z2)
方法2:
要求测出 X 面板和 Y 面板的电阻,X 和 Y 的位置,和 Z1 的位置。可采用公式(4)计算
触摸电阻
数字接口
XPT2046 数据接口是串行接口,其典型工作时序如图 12 所示,图中展示的信号来自带有基本串行接口的单片机或数据信号处理器。处理器和转换器之间的的通信需要 8 个时钟周期,可采用 SPI、SSI 和 Microwire 等同步串行接口。一次完整的转换需要 24 个串行同步时钟(DCLK)来完成。
引脚定义
控制字节由 DIN 输入的控制字如表 5 所示,它用来启动转换,寻址,设置 ADC 分辨率,配置和对 XPT2046 进行掉电控制
起始位——第一位,即 S 位。控制字的首位必须是 1,即 S=1。在 XPT2046 的 DIN 引脚检测到起始位前,所有的输入将被忽略。
地址——接下来的 3 位(A2、A1 和 A0)选择多路选择器的现行通道(见表 3、表 4 和图 6),触摸屏驱动和参考源输入。
MODE——模式选择位,用于设置 ADC 的分辨率。MODE=0,下一次的转换将是 12 位模式;
MODE=1,下一次的转换将是 8 位模式。
SER/——DFR——SER/——DFR位控制参考源模式,选择
单端模式(SER/——DFR=1),或者差分模式(SER/——DFR=0)。在X坐标、Y坐标和触摸压力测量中,为达到最佳性能,首选差分工作模式。参考电压来自开关驱动器的电压。在单端模式下,转换器的参考电压固定为VREF相对于GND引脚的电
压
数字时序![](/assets/blank.gif)
通信的过程很简单,首先主机向XPT2046写入8个字节的控制字节,然后从XPT2046中读出转换数据即可,读出来的数据有16位,只有高12位是有效数据。控制字节的含义如下
—>此图来源于CSDN XPT2046的使用
代码控制
#include "touch.h"
#include "ili9341.h"
#include "usart.h"/****************************************************************************
* 名 称 :void Touch_Init(void)
* 功 能 :初始化GPUI管脚
* 入口参数:void
* 出口参数:void
* 说 明 :void
* 作 者 :koko
****************************************************************************/void Touch_Init(void)
{GPIO_InitTypeDef Touch_Gpio_Spi_structure;EXTI_InitTypeDef Touch_Exti_Structure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO ,ENABLE);Touch_Gpio_Spi_structure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出Touch_Gpio_Spi_structure.GPIO_Speed = GPIO_Speed_50MHz ;Touch_Gpio_Spi_structure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_3|GPIO_Pin_13;GPIO_Init(GPIOC,&Touch_Gpio_Spi_structure);Touch_Gpio_Spi_structure.GPIO_Mode = GPIO_Mode_IPU ; //上拉输入Touch_Gpio_Spi_structure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2 ; Touch_Gpio_Spi_structure.GPIO_Speed = GPIO_Speed_50MHz ;GPIO_Init(GPIOC,&Touch_Gpio_Spi_structure);Touch_CS = 0 ;
}
/****************************************************************************
* 名 称 :static void Touch_Write_CMD(u8 cmd)
* 功 能 :通过SPI时序写入一个8bit控制位
* 入口参数:u8 cmd
* 出口参数:void
* 说 明 :void
* 作 者 :koko
****************************************************************************/
static void Touch_Write_CMD(u8 cmd)
{u8 i;Touch_OUT = 0; //命令 控制位Touch_CLK = 0; for( i =0 ;i <8 ; i ++){if(cmd & 0x80){Touch_OUT = 1;}else{Touch_OUT = 0;}Touch_CLK = 1;delay_us(5);Touch_CLK = 0;cmd <<= 1; }
}/****************************************************************************
* 名 称 :static u16 Touch_Read_Data()
* 功 能 :获取一个12位的数据存储到u16 data内
* 入口参数:void
* 出口参数:u16 data
* 说 明 :null
* 作 者 :koko
****************************************************************************/
static u16 Touch_Read_Data()
{u8 i;u16 data;Touch_OUT = 0;Touch_CLK = 1;for( i = 0;i<12;i++){Touch_CLK = 0;data += Touch_IN ;data <<= 1;Touch_CLK = 1;}return data;
}void XPT2046_getSourceValue(u16 *x_AD_AVG, u16 *y_AD_AVG)
{u16 i,temp;int j;u16 x_AD[Touch_SAMPLING_TIMES] = { 0 };u16 y_AD[Touch_SAMPLING_TIMES] = { 0 };u16 x_AD_temp = 0;u16 y_AD_temp = 0;for (i = 0; i < Touch_SAMPLING_TIMES;) {if (Touch_IQR == 0) {Touch_Write_CMD(READ_CHANNEL_Y); //写读取X通道AD指令x_AD[i] = Touch_Read_Data(); //读取X通道AD值delay_us(2);Touch_Write_CMD(READ_CHANNEL_X); //写读取Y通道AD指令y_AD[i] = Touch_Read_Data(); //读取Y通道AD值delay_us(2);i++;}}//冒泡排序for ( i = 0, temp = 0; i < Touch_SAMPLING_TIMES; i++)for ( j = 0; j < Touch_SAMPLING_TIMES - i - 1; j++) {if (x_AD[j] > x_AD[j + 1]) {temp = x_AD[j];x_AD[j] = x_AD[j + 1];x_AD[j + 1] = temp;}if (y_AD[j] > y_AD[j + 1]) {temp = y_AD[j];y_AD[j] = y_AD[j + 1];y_AD[j + 1] = temp;}}//去掉一个最大值,去掉一个最小值,取平均值for ( i = 1; i < Touch_SAMPLING_TIMES - 1; i++) {x_AD_temp += x_AD[i];y_AD_temp += y_AD[i];}x_AD_temp /= (Touch_SAMPLING_TIMES - 2);y_AD_temp /= (Touch_SAMPLING_TIMES - 2);//赋值*x_AD_AVG = x_AD_temp;*y_AD_AVG = y_AD_temp;
}void XPT2046_getPoint(u16 *x, u16 *y)
{u16 x_AD_AVG = 0;u16 y_AD_AVG = 0;if (Touch_IQR == 0) {XPT2046_getSourceValue(&x_AD_AVG, &y_AD_AVG); //获取原始数据/** 具体计算依据如下,获取触摸屏左上角(800,7700)、右上角(7700,7700)、左下角(800,800)、右下角(7700,800)的AD值* 发现x,y与对应的AD值成简单的线性关系,x对应的AD值从左到右由800增加到7700,y对应的AD值由7700减少到800,于是可以得到以下计算公式*///计算点坐标*x =( 360-226 - (x_AD_AVG - 800) * Touch_X / 6900)*2;*y =( 240-110- (y_AD_AVG - 800) * Touch_X / 6900)*2;//确保x和y不越界if (*x > Touch_X - 1)*x = Touch_X - 1;if (*y > Touch_Y)*y = Touch_Y;}return;
}
#ifndef _TOUCH_H__
#define _TOUCH_H__#include "stm32f10x.h" // Device header
#include "sys.h"
#include "delay.h"//触摸区域
#define Touch_X 320
#define Touch_Y 240
#define Touch_SAMPLING_TIMES 4//指令宏定义
#define READ_CHANNEL_X 0xD0
#define READ_CHANNEL_Y 0x90//IO管脚定义
#define Touch_IQR PCin(1) //T_IQR --> PC1 -->中断输入
#define Touch_IN PCin(2) //T_DO --> PC2 -->数据输人
#define Touch_OUT PCout(3) //T_DI --> PC3 -->数据输出
#define Touch_CLK PCout(0) //T_CLK --> PC0 -->时钟线
#define Touch_CS PCout(13) //T_CS --> PC13 -->片选void Touch_Init(void); //初始化GPIO引脚
void XPT2046_getSourceValue(u16 *x_AD_AVG, u16 *y_AD_AVG);
void XPT2046_getPoint(u16 *x, u16 *y);#endif
【STM32】XPT2046四导线触摸屏控制器 SPI驱动相关推荐
- STM32单片机基础17——使用硬件SPI驱动TFT-LCD(ST7789)
本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件SPI外设与ST7789通信,驱动16bit TFT-LCD 屏幕. 0. 前言 学习 SPI 外设驱动LCD屏幕没有 ...
- (STM32)从零开始的RT-Thread之旅--SPI驱动ST7735(3)使用DMA
上一篇完成了ST7735驱动的移植,并已经可以通过SPI在屏幕上显示字符了,这一章会把SPI修改为DMA的传输方式.由于RTT对于STM32H7的SPI的DMA传输方式目前支持的并不好,这就让上一章裸 ...
- (STM32)从零开始的RT-Thread之旅--SPI驱动ST7735(2)
本篇使用的驱动来自ST官方提供: https://github.com/STMicroelectronics/stm32-st7735.git 需要的可以直接git clone下来移植,核心代码无关芯 ...
- Linux系统SPI驱动总结(一)
SPI是"Serial Peripheral Interface"的缩写,串行外设接口,是一种四线制的同步串行通信接口,用来连接MCU.传感器.存储设备,SPI设备分为主设备和从设 ...
- 单片机驱动android屏幕,STM32单片机对智能手机触摸屏的驱动
描述 由于智能手机的发展和大屏幕的兴起,触摸屏已经得到了广泛的应用.触摸屏分为两种:电阻触屏 俗称"软屏":电容触屏俗称"硬屏". 电阻触摸屏的屏体部分是一块多 ...
- SPI驱动XPT2046芯片读取其内部ADC信息笔记
前言 这次来复习一下SPI以及ADC的有关知识,之前介绍到的磁编码器也是基于SPI协议通信才能读取其内部角度信息,ADC就更不用说了,在电压检测,电机驱动的方面都会涉及到采样量化编码的知识,趁此机会好 ...
- STM32CubeMX | 基于STM32使用HAL库硬件SPI驱动WK2124一拖四SPI转四路串口芯片
STM32CubeMX | 基于STM32使用HAL库硬件SPI驱动WK2124一拖四SPI转四路串口芯片 STM32基础工程生成 首先使用STM32CUBEMX生成STM32的基础工程,配置时钟到7 ...
- STM32使用硬件SPI驱动RC522门禁模块
0.前言 RC522射频门禁识别模块非常常用,某宝卖家提供的程序基本都是使用软件模拟SPI的方式进行驱动的,但是实测使用软件模拟SPI识别速率.准确性没有硬件SPI驱动时高,因此本篇博客用于记录使用S ...
- 基础篇010.2 STM32驱动RC522 RFID模块之二:STM32硬件SPI驱动RC522
目录 1. 实验硬件及原理图 1.1 RFID硬件 1.2 硬件原理图 2. 单片机与RFID硬件模块分析 3. 利用STM32CubeMX创建MDK工程 3.1 STM32CubeMX工程创建 3. ...
最新文章
- new 数组_编程-遍历数组元素N次/填充数组至指定长度
- 阿里开源分布式事务解决方案 Fescar 全解析
- Linux/Unix下的任务管理器-top命令
- python3环境变量_配置环境变量切换到python3.7
- 错误: 元素值必须为常量表达式_C语言编程常见错误集锦 【下】
- java 最好 入门_C++和Java哪个比较好入门?初学者该如何选择?
- 试驾小程序_Linux如何成为Linux:试驾1993-2003发行版
- LIRe 源代码分析 4:建立索引(DocumentBuilder)[以颜色布局为例]
- asp.net后台操作javascript:confirm返回值
- 图片去底色怎么去?图片怎么去底色变透明?
- cesium中文教程(cesium中文教程PDF)
- oracle mod函数
- 不限机型,手机端实时玩转3D、混合现实,快手Y-tech有黑科技(已开源)
- 自定义Toast、程序退出时Toast也退出、Toast的用法
- 本地RTMP流媒体服务器搭建拉流简易版
- dataframe获取字符串中的字数
- java visual linux,如何在 Linux 中安装 Visual Studio Code
- 【元宇宙欧米说】元宇宙场景应用和营销新模式
- Web测试需要兼顾的测试要点有哪些?
- Mac使用bootcamp安装windows双系统以及mac系统全新重装