SPI 多点触摸屏学习嵌入式总结

1. 引言

在嵌入式开发中,触摸屏作为人机交互的重要接口,广泛应用于工控、医疗、消费电子等领域。本文基于 SPI 接口的多点触摸屏,从硬件原理、驱动框架到实际调试,系统梳理学习过程中的关键知识点与踩坑记录,帮助初学者快速建立整体认知。

2. 硬件基础

2.1 SPI 接口简介

SPI(Serial Peripheral Interface)是一种高速全双工同步串行总线,通常由四根线组成:

  • SCLK:时钟信号,由主机产生
  • MOSI:主机输出,从机输入
  • MISO:主机输入,从机输出
  • CS/SS:片选信号,低电平有效

SPI 支持多种工作模式(CPOL/CPHA 组合),触摸屏控制器通常工作在模式 0 或模式 3,具体需查阅芯片数据手册。

2.2 多点触摸屏工作原理

多点触摸屏(如电容式触摸屏)通过检测电容变化来定位触摸点。触摸控制器(如 GT911、FT5x06 等)负责扫描触摸面板,将触摸坐标通过 SPI 或 I2C 接口上报给主控。

典型架构如下:
#mermaid-svg-iu1s4mYnvPRHfjU4{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-iu1s4mYnvPRHfjU4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-iu1s4mYnvPRHfjU4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-iu1s4mYnvPRHfjU4 .error-icon{fill:#552222;}#mermaid-svg-iu1s4mYnvPRHfjU4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-iu1s4mYnvPRHfjU4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-iu1s4mYnvPRHfjU4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-iu1s4mYnvPRHfjU4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-iu1s4mYnvPRHfjU4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-iu1s4mYnvPRHfjU4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-iu1s4mYnvPRHfjU4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-iu1s4mYnvPRHfjU4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-iu1s4mYnvPRHfjU4 .marker.cross{stroke:#333333;}#mermaid-svg-iu1s4mYnvPRHfjU4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-iu1s4mYnvPRHfjU4 p{margin:0;}#mermaid-svg-iu1s4mYnvPRHfjU4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-iu1s4mYnvPRHfjU4 .cluster-label text{fill:#333;}#mermaid-svg-iu1s4mYnvPRHfjU4 .cluster-label span{color:#333;}#mermaid-svg-iu1s4mYnvPRHfjU4 .cluster-label span p{background-color:transparent;}#mermaid-svg-iu1s4mYnvPRHfjU4 .label text,#mermaid-svg-iu1s4mYnvPRHfjU4 span{fill:#333;color:#333;}#mermaid-svg-iu1s4mYnvPRHfjU4 .node rect,#mermaid-svg-iu1s4mYnvPRHfjU4 .node circle,#mermaid-svg-iu1s4mYnvPRHfjU4 .node ellipse,#mermaid-svg-iu1s4mYnvPRHfjU4 .node polygon,#mermaid-svg-iu1s4mYnvPRHfjU4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-iu1s4mYnvPRHfjU4 .rough-node .label text,#mermaid-svg-iu1s4mYnvPRHfjU4 .node .label text,#mermaid-svg-iu1s4mYnvPRHfjU4 .image-shape .label,#mermaid-svg-iu1s4mYnvPRHfjU4 .icon-shape .label{text-anchor:middle;}#mermaid-svg-iu1s4mYnvPRHfjU4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-iu1s4mYnvPRHfjU4 .rough-node .label,#mermaid-svg-iu1s4mYnvPRHfjU4 .node .label,#mermaid-svg-iu1s4mYnvPRHfjU4 .image-shape .label,#mermaid-svg-iu1s4mYnvPRHfjU4 .icon-shape .label{text-align:center;}#mermaid-svg-iu1s4mYnvPRHfjU4 .node.clickable{cursor:pointer;}#mermaid-svg-iu1s4mYnvPRHfjU4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-iu1s4mYnvPRHfjU4 .arrowheadPath{fill:#333333;}#mermaid-svg-iu1s4mYnvPRHfjU4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-iu1s4mYnvPRHfjU4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-iu1s4mYnvPRHfjU4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iu1s4mYnvPRHfjU4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-iu1s4mYnvPRHfjU4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iu1s4mYnvPRHfjU4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-iu1s4mYnvPRHfjU4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-iu1s4mYnvPRHfjU4 .cluster text{fill:#333;}#mermaid-svg-iu1s4mYnvPRHfjU4 .cluster span{color:#333;}#mermaid-svg-iu1s4mYnvPRHfjU4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-iu1s4mYnvPRHfjU4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-iu1s4mYnvPRHfjU4 rect.text{fill:none;stroke-width:0;}#mermaid-svg-iu1s4mYnvPRHfjU4 .icon-shape,#mermaid-svg-iu1s4mYnvPRHfjU4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iu1s4mYnvPRHfjU4 .icon-shape p,#mermaid-svg-iu1s4mYnvPRHfjU4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-iu1s4mYnvPRHfjU4 .icon-shape .label rect,#mermaid-svg-iu1s4mYnvPRHfjU4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iu1s4mYnvPRHfjU4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-iu1s4mYnvPRHfjU4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-iu1s4mYnvPRHfjU4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 触摸面板
触摸控制器
SPI 总线
主控 MCU
应用层处理

3. 驱动开发流程

3.1 设备树配置

在 Linux 内核中,SPI 触摸屏通常通过设备树描述硬件连接:

dts 复制代码
&spi1 {
    status = "okay";
    touch: touch@0 {
        compatible = "vendor,touch-controller";
        reg = <0>;
        spi-max-frequency = <1000000>;
        interrupt-parent = <&gpio>;
        interrupts = <17 IRQ_TYPE_EDGE_FALLING>;
    };
};

3.2 驱动框架

SPI 触摸屏驱动主要包含以下部分:

  • probe 函数:初始化 SPI 设备、注册输入设备
  • 中断处理:触摸事件到来时读取坐标数据
  • 输入子系统上报 :通过 input_report_abs 上报触摸坐标
c 复制代码
static int touch_probe(struct spi_device *spi)
{
    struct input_dev *input;
    /* 分配并注册输入设备 */
    input = devm_input_allocate_device(&spi->dev);
    input_set_abs_params(input, ABS_MT_POSITION_X, 0, 1024, 0, 0);
    input_set_abs_params(input, ABS_MT_POSITION_Y, 0, 600, 0, 0);
    /* 注册中断 */
    return request_irq(gpio_to_irq(17), touch_irq_handler,
                       IRQF_TRIGGER_FALLING, "touch", spi);
}

3.3 多点触摸上报协议

Linux 内核使用 Type B 协议上报多点触摸:

c 复制代码
input_mt_slot(input, slot_id);
input_mt_report_slot_state(input, ABS_MT_TRACKING_ID, true);
input_report_abs(input, ABS_MT_POSITION_X, x);
input_report_abs(input, ABS_MT_POSITION_Y, y);
input_mt_sync(input);

4. 调试与踩坑记录

4.1 SPI 时钟频率过高导致数据错乱

触摸控制器对 SPI 时钟有上限要求,超过后会出现坐标跳变。解决方法是降低 spi-max-frequency,并确认主控 SPI 模式与控制器匹配。

4.2 中断触发方式不匹配

部分控制器中断为低电平触发,若配置为边沿触发,可能丢失触摸事件。需结合数据手册确认 IRQ_TYPE_LEVEL_LOW 或 IRQ_TYPE_EDGE_FALLING。

4.3 坐标校准

多点触摸屏首次使用需进行校准,可通过 tslib 或内核 input_calibrate 完成,将原始坐标映射到屏幕分辨率。

5. 学习心得

通过本次 SPI 多点触摸屏的学习,我深刻体会到嵌入式开发中「硬件手册 + 内核框架 + 实际调试」三者结合的重要性。遇到问题时,先确认硬件连接与 SPI 时序,再检查驱动上报逻辑,往往能快速定位问题。

6. 总结

SPI 多点触摸屏的开发涉及硬件接口、内核驱动、输入子系统等多个层面。掌握 SPI 协议与触摸控制器工作原理,熟悉设备树配置与输入上报机制,是完成此类外设驱动的关键。希望本文的总结能为同样在学习嵌入式的朋友提供参考。

相关推荐
dadaobusi1 小时前
学习:顶点着色器输出后,三角形为什么是四个分量
学习
lengxuenong2 小时前
枚举及其优化学习手册
c++·学习·算法·青少年编程
M78佐菲2 小时前
ARM学习笔记(12)
linux·arm开发·笔记·嵌入式硬件·学习
奇思妙想聪明勤奋的小羊3 小时前
ai-agent-book第五章:Coding Agent 与通用 Agent 学习笔记
人工智能·笔记·学习
优化Henry3 小时前
BBU与RRU光链路详解:从双纤一收一发到单纤双向
网络·笔记·学习·5g·tdd
辣知4 小时前
辣知·化智68 半仙隐士渭水钓的不是鱼
学习
传奇开心果编程4 小时前
【用案例学Material 3 Expressive】第1课:从一封邮件开始,感受安卓设计新语言的表现力
android·学习·ui·kotlin·android jetpack
sunoo-2294 小时前
【嵌入式 ARM 学习第十二天】SPI 裸机驱动 + I2C 触摸屏驱动 + 三大串行协议深度对比
arm开发·笔记·vscode·学习·imx6ull
墨心@5 小时前
第 4 章《工具》学习总结
学习·自然语言处理·prompt·agent·harness