4、触摸屏硬件接口:SPI与I2C接口对比、中断引脚配置、复位时序设计
好,咱们进入第四章。这一章聊的是触摸屏的硬件接口,说白了就是芯片之间怎么「说话」的。SPI和I2C这两个接口,做嵌入式的没人不知道。但具体到触摸屏这个场景,选哪个、怎么配、坑在哪,我踩过的坑还真不少。
4.1 SPI vs I2C:接口选型背后的门道
先看一张对比表,这是我做项目时常用的决策依据:
| 对比项 | SPI | I2C |
|---|---|---|
| 引脚数量 | 4线(CS、SCLK、MOSI、MISO) | 2线(SCL、SDA) |
| 通信速率 | 典型10-50MHz,最高可达100MHz+ | 标准100kHz/400kHz,快速1MHz |
| 传输方式 | 全双工,主从模式 | 半双工,多主多从 |
| 硬件复杂度 | 简单,无地址仲裁 | 需要地址匹配和仲裁逻辑 |
| 触摸屏适用场景 | 高刷新率、多点触控、数据量大 | 低功耗、引脚受限、单点或低速触控 |
我个人习惯,做工业级POS机时首选SPI。为什么?因为POS机经常要支持多点触控和手势识别,数据量不小。I2C在400kHz下传一次多点坐标数据,延迟明显。你想想看,用户划一下屏幕,等100ms才有反应,这体验能好吗?
但I2C也有它的主场。比如一些低成本的消费级设备,引脚少、走线简单,I2C就够用了。我记得有一次帮客户改方案,他们原来用SPI的触摸屏,但主控芯片的SPI口被占用了,只剩两个I2C引脚。我直接换了颗I2C接口的触控芯片,虽然刷新率从200Hz降到了100Hz,但单点触控完全够用,还省了PCB面积。
4.2 中断引脚配置:别让CPU空转
触摸屏的中断引脚,是驱动里最容易被忽视的细节。很多人直接配成上升沿触发,结果发现中断频繁触发,CPU负载飙升。
为什么会这样?因为触摸屏在空闲时,中断引脚的电平状态可能不稳定。有些芯片在无触摸时,INT引脚是高阻态,外部需要上拉电阻。如果上拉电阻选得太大,噪声就会耦合进来,产生虚假中断。
我建议的配置方法:
- 触发方式:优先用下降沿触发。大多数触控芯片在检测到触摸时,INT引脚从高拉低。释放触摸时再拉高。这样每个触摸事件只产生一次中断。
- 上拉电阻:4.7kΩ到10kΩ之间。我习惯用4.7kΩ,抗噪性好。如果功耗敏感,可以选10kΩ。
- 去抖处理:中断服务函数里不要直接读坐标。先读状态寄存器确认触摸有效,再读坐标数据。我曾经遇到过中断引脚抖动,连续触发几十次,后来加了5ms的去抖延时才解决。
4.3 复位时序设计:上电顺序决定生死
触摸屏的复位时序,说白了就是芯片上电后,怎么让它进入正常工作状态。很多芯片手册里会写一个时序图,但实际项目中,时序参数往往需要微调。
典型的复位时序包含三个阶段:
- 上电稳定期:VDD从0V上升到稳定电压,一般需要1-10ms。这个阶段不要对芯片做任何操作。
- 复位脉冲:拉低RST引脚,保持至少1ms(具体看芯片手册)。然后拉高,芯片开始内部初始化。
- 初始化等待:拉高RST后,芯片需要一段时间完成内部校准和自检。这个时间从几毫秒到几十毫秒不等。
我常用的复位代码(以SPI接口为例):
// 触摸屏复位函数
void touch_reset(void) {
// 1. 拉低RST
HAL_GPIO_WritePin(TOUCH_RST_GPIO_Port, TOUCH_RST_Pin, GPIO_PIN_RESET);
// 2. 保持低电平10ms(留足余量)
HAL_Delay(10);
// 3. 拉高RST
HAL_GPIO_WritePin(TOUCH_RST_GPIO_Port, TOUCH_RST_Pin, GPIO_PIN_SET);
// 4. 等待芯片初始化完成(典型值20ms)
HAL_Delay(20);
// 5. 发送初始化命令(如设置工作模式、采样率等)
touch_send_cmd(0x01, 0x00); // 示例:复位后配置
}
嗯,这里还要提一个细节:复位时序里的延时,不要用简单的空循环。在RTOS环境下,空循环会阻塞任务调度。我习惯用系统提供的延时函数,比如FreeRTOS的vTaskDelay(),或者HAL库的HAL_Delay()。这样既能保证时序,又不浪费CPU。
最后说一句,触摸屏的硬件接口设计,看似简单,但每个细节都影响最终体验。SPI和I2C选哪个,中断怎么配,复位时序怎么调,这些都是在项目里反复验证过的。你按照这个思路去做,基本不会出大问题。