问题描述
我有 MFRC522 (datasheet here) RFID 模块和 Nucleo 板 (F411RE)。我试图为这个模块找到一个为 STM32 制作的库,但我没有成功。我发现很少,但它们都不起作用。 (它甚至没有编译和修复错误只会让它变得更糟......)所以我决定将标准的 Arduino 库 (source code here) 移植到 STM32 上,我知道它可以正常工作。我删除了对串行函数的所有调用,并重写了 SPI 写入和读取方法以使用 HAL 而不是 Arduino 的 SPI 类。
void MFRC522::PCD_WriteRegister(PCD_Register reg,uint8_t value) {
HAL_GPIO_WritePin(csPort,csPin,GPIO_PIN_RESET);
HAL_SPI_Transmit(readers[reader],(uint8_t*)®,1,100);
HAL_SPI_Transmit(readers[reader],&value,100);
HAL_GPIO_WritePin(csPort,GPIO_PIN_SET);
}
uint8_t MFRC522::PCD_ReadRegister(PCD_Register reg) {
uint8_t data;
uint8_t zero = 0x00;
uint8_t addr = 0x80 | reg;
HAL_GPIO_WritePin(csPort,&addr,100);
HAL_SPI_TransmitReceive(readers[reader],&zero,&data,GPIO_PIN_SET);
return data;
}
我正在使用此代码读取卡片:
bool readID() {
if (!rfid.PICC_IsNewCardPresent()) {
return false;
}
if (!rfid.PICC_ReadCardSerial()) {
return false;
}
for (int i = 0; i < 4; i++) {
lastId[i] = rfid.uid.uidByte[i];
}
rfid.PICC_HaltA();
return true;
}
但问题是,PICC_IsNewCardPresent() 方法总是返回 false。使用调试器我设法发现问题是 PCD_CommunicateWithPICC 方法:
uint16_t i;
for (i = 2000; i > 0; i--) {
uint8_t n = PCD_ReadRegister(ComIrqReg); // ComIrqReg[7..0] bits are: Set1 TxIRq RxIRq IdleIRq HiAlertIRq LoAlertIRq ErrIRq TimerIRq
if (n & waitIRq/*constant 0x30*/) { // One of the interrupts that signal success has been set.
break;
}
if (n & 0x01) { // Timer interrupt - nothing received in 25ms
return STATUS_TIMEOUT;
}
}
结束于
return STATUS_TIMEOUT;
循环甚至没有第二次运行......我在我的示波器上捕获了读取 ComIrqReg 寄存器的情况,STM32 发送了 0x88,它与读取的 ComIrqReg 请求相对应,IC 以 0x45 响应。我在调试器中检查了 n 变量值,它也读取了 0x45,所以我的读取方法可能不是问题。
Picture of the captured communication
我还查看了模块的初始化,并检查了几个字节是否与应该发送的字节相对应,对我来说也很好。
Picture of the captured initialization
0x45 的读取值为 0b01000101,即 n&0x01 为 0b1 例如。 true 并返回 STATUS_TIMEOUT ... 我需要让第 5 个或第 6 个 LSB 为真。
您知道为什么模块总是返回 0x45 值吗?我什么也想不出来……模块 100% 工作(用 Arduino 确认)所以问题必须出在 STM32 部分。你会尝试什么?
感谢您的帮助!
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)