STM32MP157F-K2的SPI5无法读取RC522 RFID卡问题求助
针对RC522与STM32MP157 SPI通信失败的排查与修复
以下是从你提供的配置和代码中发现的关键问题及修复方案:
1. SPI字节序配置错误
RC522默认采用**MSB(最高位优先)**传输数据,但你的SPI5配置设置了SPI_FIRSTBIT_LSB,这会导致所有数据字节序完全颠倒,直接引发通信失败。
修复:修改SPI初始化参数:
hspi5.Init.FirstBit = SPI_FIRSTBIT_MSB;
2. CS片选引脚未生效
Read_MFRC522函数中控制CS引脚的代码被注释,SPI通信必须在传输前拉低CS选中RC522,传输完成后拉高取消选中,否则芯片不会响应指令。
修复:恢复CS引脚控制逻辑:
uchar Read_MFRC522(uchar addr) { uchar val = 0x00; /* 拉低CS选中RC522 */ HAL_GPIO_WritePin(GPIOG, GPIO_PIN_3, GPIO_PIN_RESET); // 发送读地址指令:地址左移1位,最高位设1表示读操作 RC522_SPI_Transfer(((addr<<1)&0x7E) | 0x80); val = RC522_SPI_Transfer(0x00); /* 拉高CS取消选中 */ HAL_GPIO_WritePin(GPIOG, GPIO_PIN_3, GPIO_PIN_SET); return val; }
注意:确保GPIOG_PIN_3已在CubeMX中配置为推挽输出模式。
3. SPI传输时序不匹配
当前RC522_SPI_Transfer用分开的HAL_SPI_Transmit和HAL_SPI_Receive完成传输,会产生额外时钟间隙,不符合RC522全双工通信的时序要求。
修复:改用HAL_SPI_TransmitReceive实现全双工传输:
uint8_t RC522_SPI_Transfer(uint8_t data) { uint8_t rx_data; // 单次完成收发,保证时序连续 if (HAL_SPI_TransmitReceive(HSPI_INSTANCE, &data, &rx_data, 1, HAL_MAX_DELAY) != HAL_OK) { return 0; // 可根据需求调整错误处理逻辑 } return rx_data; }
4. 主代码未检查通信状态
你直接调用MFRC522_Request和MFRC522_Anticoll却不验证返回状态,导致通信失败时仍输出str数组的垃圾值,无法定位问题根源。
修复:添加状态校验逻辑:
HAL_Delay(1000); status = MFRC522_Request(PICC_REQIDL, str); if (status != MI_OK) { printf("寻卡失败!\n"); HAL_GPIO_WritePin(GPIOH, GPIO_PIN_7, 1); continue; } status = MFRC522_Anticoll(str); if (status != MI_OK) { printf("防冲突检测失败!\n"); HAL_GPIO_WritePin(GPIOH, GPIO_PIN_7, 1); continue; } memcpy(sNum, str, 5); HAL_Delay(100); // 打印数据 printf("接收数据: "); for (int i = 0; i < 5; i++) { printf("%02X ", str[i]); } printf("\n"); // 后续卡判断逻辑...
额外调试建议
- 先降低SPI波特率测试:建议先设为1Mbps(
SPI_BAUDRATEPRESCALER_64,根据系统时钟计算),确认通信正常后再逐步提高。 - 检查RC522供电:必须使用稳定的3.3V供电,接5V会导致芯片损坏或工作异常。
- 确认硬件连接:SCK、MOSI、MISO引脚对应正确,RC522的RST引脚若启用需初始化至高电平。
内容的提问来源于stack exchange,提问作者Ben Mahmoud Ramla
相关产品推荐
相关产品推荐

