外观
SPI XPT2046 示例
2026-05-15
概述
本文介绍如何在 睿擎工业开发平台 中创建并运行 SPI 总线通信 示例工程。通过驱动 XPT2046 触摸屏控制器,演示了基于 RT-Thread SPI 设备驱动框架的开发流程。
XPT2046 触摸控制器
XPT2046 是一款 4 线制电阻式触摸屏控制器,内含 12 位分辨率、125kHz 转换速率的逐步逼近型 A/D 转换器。它采用标准的 SPI 串行接口进行通信,常用于嵌入式设备中获取触控位置的 X、Y 坐标。
硬件连接
开发板的 SPI 接口与 XPT2046 硬件已经连接,芯片位置如图所示:

查手册获取 SPI 配置与控制字
根据 XPT2046 数据手册可知:
SPI 参数配置:支持 SPI 模式 0( CPOL =0, CPHA =0),数据位宽 8 位,高位先行(MSB First)。
控制字(Command):
- 读取 X 坐标 ADC 值的命令字为:
0xD0 - 读取 Y 坐标 ADC 值的命令字为:
0x90
数据格式:返回结果为 12 位有效数据,包含在两个字节中,需进行移位拼接。
读取 XPT2046 设备的触摸坐标
本示例展示如何通过 SPI 总线挂载并初始化 XPT2046 触摸控制器,然后通过发送指定的控制字(Command)读取 12 位精度的 X 和 Y 坐标 ADC 值。
构建与烧录
创建工程点击展开
依次点击 “文件” -> “新建” -> "RT-Thread RuiChing App 项目"。

在弹出新建向导中选择 开发版 、BSP: 、示例 、 调试器/下载器。选择好之后点击 “完成”。

点击 “完成” 后,等待工程创建完成。

创建完成。

构建工程点击展开
单击工程使工程进入 Active-Debug 模式。

点击工具栏上的构建按钮进行工程编译。

构建成功后,会显示构建成功的信息。

固件下载点击展开
固化驱动

固化 APP

核心示例代码
SPI 示例相关代码说明
rt_spi_bus_attach_device:该函数实现了 SPI 从设备的挂载与注册流程,包括设备句柄、设备的名称、挂载的总线名称和cs片选引脚。rt_spi_configure:该函数实现了 SPI 从设备参数的配置流程,包括通信模式(Mode)、数据宽度(Data Width)以及支持的最大通信速率(Max Hz)。rt_spi_transfer:该函数实现了向 XPT2046 设备发送0xD0或0x90控制指令,并接收返回的 12 位触摸坐标 ADC 原始数据的全双工传输操作。
spi_example.c
static rt_err_t _xpt2046_device_init(void)
{
rt_err_t ret = RT_EOK;
struct rt_spi_device *dev;
struct rt_spi_configuration cfg = {
.mode = RT_SPI_MODE_0 | RT_SPI_MSB,
.data_width = 8,
.max_hz = 1000000,
};
if (rt_device_find(SPI_DEVICE_NAME) == RT_NULL)
{
dev = rt_malloc(sizeof(struct rt_spi_device));
if (dev == RT_NULL)
{
rt_kprintf("malloc dev failed\n");
ret = -RT_ERROR;
goto __dev_err;
}
ret = rt_spi_bus_attach_device(dev, SPI_DEVICE_NAME, SPI_BUS_NAME,
(void *)SPI_CS_PIN);// 挂载 SPI 从设备
if (ret != RT_EOK)
{
rt_kprintf("mount spi bus failed\n");
ret = -RT_ERROR;
goto __attach_err;
}
}
dev = (struct rt_spi_device *)rt_device_find(SPI_DEVICE_NAME);
if (dev == RT_NULL)
{
rt_kprintf("not find device %s\n", SPI_DEVICE_NAME);
ret = -RT_ERROR;
goto __dev_err;
}
rt_spi_configure(dev, &cfg);// 配置 SPI 从设备参数
return RT_EOK;
__attach_err:
rt_free(dev);
__dev_err:
return ret;
}
static rt_uint16_t _xpt2046_read_adc(struct rt_spi_device *spi_dev,
rt_uint8_t cmd)
{
rt_uint8_t tx[3] = {cmd, 0x00, 0x00};
rt_uint8_t rx[3] = {0};
rt_spi_transfer(spi_dev, tx, rx, 3);// 向 XPT2046 设备发送控制指令,并接收返回的 12 位触摸坐标
return ((((rt_uint16_t)rx[1]) << 8) | rx[2]) >> 4;
}
int spi_xpt2046_example(void)
{
struct rt_spi_device *spi_dev_xpt2046 = RT_NULL;
rt_uint16_t x = 0, y = 0, vbatt = 0;
int i = 0;
if (_xpt2046_device_init() != RT_EOK)
{
return -RT_ERROR;
}
spi_dev_xpt2046 = (struct rt_spi_device *)rt_device_find(SPI_DEVICE_NAME);
if (spi_dev_xpt2046 == RT_NULL)
{
rt_kprintf("device %s not found\n", SPI_DEVICE_NAME);
return -RT_ERROR;
}
for (i = 0; i < 5; i++)
{
x = _xpt2046_read_adc(spi_dev_xpt2046, XPT2046_CMD_READ_X);
y = _xpt2046_read_adc(spi_dev_xpt2046, XPT2046_CMD_READ_Y);
rt_kprintf("XPT2046 touch coordinate: X = %d, Y = %d", x, y);
rt_kprintf("\n");
rt_thread_mdelay(100);
}
return RT_EOK;
}运行示例
操作步骤
- 将程序下载到开发板
- 打开串口终端连接开发板
- 系统在启动后
main函数会自动调用其内容函数 - 也可在终端输入
spi_xpt2046_example命令
预期结果
RT-Thread 终端
Hello, RuiChing
XPT2046 touch coordinate: X = 749, Y = 1171
msh />XPT2046 touch coordinate: X = 1233, Y = 1415
XPT2046 touch coordinate: X = 1366, Y = 1513
XPT2046 touch coordinate: X = 1513, Y = 1621
XPT2046 touch coordinate: X = 1566, Y = 1571
msh />spi_xpt2046_example
XPT2046 touch coordinate: X = 853, Y = 1209
XPT2046 touch coordinate: X = 1285, Y = 1380
XPT2046 touch coordinate: X = 1418, Y = 1461
XPT2046 touch coordinate: X = 1446, Y = 1507
XPT2046 touch coordinate: X = 1509, Y = 1620