You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TTGO T-Display ESP32外接RC522 SPI模块可识别固件但无法读卡问题

故障核心诱因
    1. RC522硬复位时序缺失:这是最核心的故障原因。RC522的版本号寄存器属于数字逻辑单元,只要SPI基础通信正常即可读取,但射频收发的模拟前端必须通过RST引脚提供完整的硬复位时序(拉低保持10ms以上再拉高)才能完成校准、启动射频场。直接将RST引脚常置高电平时,仅模块数字部分进入工作状态,射频前端未启动,无法检测卡片。MFRC522库内置的软复位无法完全替代硬复位,市售廉价RC522模块普遍简化了板载复位电路,必须手动控制RST引脚才能完成完整复位。
    1. SPI配置被TFT初始化覆盖:代码中先初始化TFT屏幕时,会修改全局SPI总线的通信模式、位序、时钟参数,后续初始化RC522时如果没有显式重置SPI配置,会沿用TFT留下的错误参数。单字节的版本号读取容错率高可以正常返回,读卡流程需要连续多字节寄存器交互、FIFO读写,参数不匹配时会直接通信失败。
    1. SPI时钟速率过高:RC522标称最高支持10MHz SPI时钟,但飞线接线、GPIO重映射场景下信号完整性较差,高速率下连续通信容易出现数据校验错误,导致读卡失败。
    1. 总线分配判断错误:TTGO T-Display板载TFT默认占用VSPI总线,默认引脚为CLK18/MOSI19,你当前将RC522接在重映射的VSPI引脚(25/26/27)上,并未使用独立的HSPI总线,两个外设实际共用同一SPI主机,没有总线仲裁的情况下会出现配置抢占。
修复方案

方案一:不改动现有接线,软件调整(快速验证)

按以下逻辑修改代码:

  1. 增加RC522硬复位时序
  2. 调整初始化顺序,TFT初始化完成后再重映射SPI引脚、初始化RC522,完全覆盖TFT留下的SPI配置
  3. 显式将RC522的SPI时钟降低到2MHz,提升通信稳定性
  4. 初始化完成后将TFT的CS引脚(GPIO5)常置高,避免意外选中TFT抢占总线

修正后的可直接运行代码:

#include <SPI.h>
#include <MFRC522.h>
#include <TFT_eSPI.h>

#define RST_PIN 17
#define SS_PIN  33
#define TFT_CS  5  // TTGO T-Display板载TFT固定CS引脚

MFRC522 mfrc522(SS_PIN, RST_PIN);
TFT_eSPI tft = TFT_eSPI();

void setup() {
  Serial.begin(115200);
  while (!Serial);

  // 执行RC522硬复位
  pinMode(RST_PIN, OUTPUT);
  digitalWrite(RST_PIN, LOW);
  delay(15);
  digitalWrite(RST_PIN, HIGH);
  delay(5);

  // 先初始化TFT,完成初始绘制
  tft.init();
  tft.fillScreen(TFT_WHITE);
  tft.setCursor(0,0);
  tft.setTextColor(TFT_BLACK);
  tft.println("RC522 Test");

  // TFT初始化完成后,重映射SPI引脚到RC522接线
  SPI.begin(25, 27, 26, SS_PIN);  // 参数顺序:CLK, MISO, MOSI, SS
  // 显式指定SPI总线和2MHz通信速率,重置SPI配置
  mfrc522.PCD_Init(SPI, 2000000);
  delay(10);
  mfrc522.PCD_DumpVersionToSerial();

  // 常拉高TFT_CS,避免TFT抢占总线
  pinMode(TFT_CS, OUTPUT);
  digitalWrite(TFT_CS, HIGH);

  Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}

void loop() {
  // 选中RC522,确保TFT未被选中
  digitalWrite(TFT_CS, HIGH);
  digitalWrite(SS_PIN, LOW);

  if (!mfrc522.PICC_IsNewCardPresent()) {
    digitalWrite(SS_PIN, HIGH);
    delay(10);
    return;
  }

  if (!mfrc522.PICC_ReadCardSerial()) {
    digitalWrite(SS_PIN, HIGH);
    delay(10);
    return;
  }

  mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
  // 释放RC522片选
  digitalWrite(SS_PIN, HIGH);
  delay(10);
}

注意:该方案下如果需要后续操作TFT显示读卡内容,必须在调用TFT绘图函数前重新将SPI引脚映射回TFT默认引脚(18, -1, 19, 5),绘图完成后再切回RC522的引脚配置,否则会出现外设无响应的问题。

方案二:改接独立HSPI总线(长期稳定方案,推荐)

如果需要同时稳定使用TFT和RC522,将RC522改接到ESP32独立的HSPI总线上,和TFT的VSPI完全物理隔离,不需要切换引脚、做总线仲裁,稳定性最高:

  • 接线调整为:
    • RC522 CLK -> GPIO14(HSPI_CLK)
    • RC522 MISO -> GPIO12(HSPI_MISO)
    • RC522 MOSI -> GPIO13(HSPI_MOSI)
    • RC522 CS -> GPIO33(保持原有接线)
    • RC522 RST -> GPIO17(保持原有接线)
  • 代码仅需修改SPI初始化部分,定义独立的HSPI对象给RC522使用,核心初始化代码替换为:
SPIClass hspi(HSPI);  // 定义独立HSPI总线对象

void setup() {
  // 其他初始化代码不变,TFT正常初始化即可
  // ...
  // 初始化独立HSPI总线给RC522
  hspi.begin(14, 12, 13, SS_PIN);
  mfrc522.PCD_Init(hspi, 2000000);
  // ...
}
额外排查点
  • 确保RC522与开发板共地,供电引脚直接接开发板3.3V输出,不要通过细杜邦线长距离供电,RC522工作峰值电流可达100mA,电压跌落会导致射频场功率不足无法读卡
  • RC522模块不要贴在TFT屏幕背面安装,屏幕的金属屏蔽层会吸收射频信号,导致读卡距离极短甚至无响应

内容的提问来源于stack exchange,提问作者Pat K.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 02:27:17