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

如何解决STM32驱动MFRC522收发功能失效问题?

MFRC522与STM32无线通信故障调试求助

我正在开发一款基于STM32和MFRC522的PCB,用于读写13.56MHz RFID标签。目前已实现寄存器的读写操作,但无线通信功能无法正常工作。硬件与常见Arduino MFRC522 breakout board高度匹配,线圈场强良好,因此确信问题出在固件层面。

MFRC.c驱动文件

/* Write single byte MFRC register
 *
 * @param addr: register address
 *
 * @param data: value to write to register
 */

HAL_StatusTypeDef MFRC_REGW(uint8_t addr,uint8_t data){
    uint8_t value=data;
    if(HAL_I2C_Mem_Write(&hi2c1, MFRC_ADDR<<1, addr, 1, &value, 1, 100)!=HAL_OK){
        return(HAL_ERROR);
    }
    else{
        return(HAL_OK);
    }
    HAL_Delay(1);
}

/* Read single byte from MFRC register
 *
 * @param addr: register address
 *
 * @param data: pointer to store read value
 */

HAL_StatusTypeDef MFRC_REGR(uint8_t addr,uint8_t* data){
    if(HAL_I2C_Mem_Read(&hi2c1, MFRC_ADDR<<1, addr, 1, data, 1, 100)!=HAL_OK){
        return(HAL_ERROR);
    }
    else{
        return(HAL_OK);
    }
    HAL_Delay(1);
}

/* Write to MFRC FIFO buffer
 *
 * @param data: Array of data to write to FIFO
 *
 * @param size: Size of array (bytes)
 */

HAL_StatusTypeDef MFRC_FIFOW(uint8_t* data,uint8_t size){
    for(int i=0;i<size;i++){
        if(HAL_I2C_Mem_Write(&hi2c1, MFRC_ADDR<<1, 0x09, 1, &data[i], 1, 100)!=HAL_OK){
            return(HAL_ERROR);

        }
        HAL_Delay(1);

    }
    return(HAL_OK);
}

/* Read from MFRC FIFO buffer
 *
 * @param data: Array to store read values (Ensure array is large enough)
 *
 * @param size: Number of bytes to read from FIFO
 */

HAL_StatusTypeDef MFRC_FIFOR(uint8_t* data,uint8_t size){
    for(int i=0;i<size;i++){
        if(HAL_I2C_Mem_Read(&hi2c1, MFRC_ADDR<<1, 0x09, 1, &data[i], 1, 100)!=HAL_OK){
            return(HAL_ERROR);
        }
        HAL_Delay(1);

    }
    return(HAL_OK);
}

/*
 * Function to calculate CRC on whatever data is in FIFO
 * !!CRCIRQ bit in DivIrqReg register can be used to detect when CRC has been calculated!!
 *
 * @param result: Array to store the two bytes of CRC
 *
 * */

HAL_StatusTypeDef CALC_CRC(uint8_t* data,uint8_t size,uint8_t* result){
    uint8_t CRCIRQ;
    MFRC_REGW(CMD_REG,IDLE); //clear command register
    MFRC_REGW(DIVIRQ,0x04); //Clear interrupt bits so we can detect when CRCIRQ is set
    MFRC_REGW(FIFO_LEV,0x80);
    MFRC_FIFOW(data, size); //Write data to FIFO ready for CRC calculation
    MFRC_REGW(CMD_REG,CALCCRC); //Execute CRC calculation command
    HAL_Delay(100);
    MFRC_REGR(DIVIRQ,&CRCIRQ);
    if((CRCIRQ&0x04)!=0x04){
        return(HAL_ERROR);
    }
    MFRC_REGW(CMD_REG,IDLE);
    MFRC_REGR(CRCL, &result[0]);
    MFRC_REGR(CRCH,&result[1]);
    return(HAL_OK);

}

/* Initialise MFRC to begin transceiving
 *
 * Code is written to interface with MIFARE Ultralight PICC. Different PICCs will need different baud rate.
 */

HAL_StatusTypeDef MFRC_INIT(void){
    HAL_GPIO_WritePin(GPIOB, NRST, 1); //Make sure MFRC is not reset
    HAL_GPIO_WritePin(GPIOB, NRST, 0);
    HAL_Delay(1);
    HAL_GPIO_WritePin(GPIOB, NRST, 1);
    HAL_Delay(50);
    MFRC_REGW(TX_REG,0x00);
    MFRC_REGW(RX_REG,0x00);
    SET_ANTGAIN();
    MFRC_REGW(MODWIDTH,0x26);
    //MFRC_REGW(TModeReg,0x80); //timer starts automatically after every transmission
    //MFRC_REGW(TPrescalerRegLO,0xA9); //Set prescaler to 169 => f_timer=40kHz, use this for timeouts
    //MFRC_REGW(TReloadHI,0x03); //Set reload counter to 4000 => 100ms timeout
    //MFRC_REGW(TReloadLO,0xE8);
    MFRC_REGW(TXASK,0x40); //Force 100% ASK modulation regardless of ModGsPrereg
    MFRC_REGW(MODE_REG,0x3D);
    MFRC_ANTON();
    return(HAL_OK);


}

/* Transceive data between MFRC and PICC
 *
 * @param sendData: Array of data to send
 *
 * @param sendsize: Number of bytes to send
 *
 * @param recdata: Array to store received data
 *
 * @param recsize: Number of bytes to receive
 *
 */

HAL_StatusTypeDef MFRC_TRANSCEIVE(uint8_t* sendData,uint8_t sendsize,uint8_t* recdata,uint8_t recsize){
    uint8_t IRQval=0;
    uint8_t BIT_val=0;
    uint8_t stat;
    uint8_t transaction[sendsize];

    memcpy(transaction,sendData,sendsize);

    MFRC_REGW(CMD_REG,IDLE); //Clear command register
    MFRC_REGW(IRQ_REG,0x7F);
    MFRC_REGW(BITFRAME,0x00);
    MFRC_REGW(FIFO_LEV,0x80); //Clear FIFO buffer
    MFRC_FIFOW(sendData,sendsize); //Write data to FIFO ready for transmission
    //MFRC_FIFOR(FIFO_State, sendsize);
    //CDC_Transmit_FS(FIFO_State, sendsize);
    MFRC_REGW(CMD_REG,TRANSCEIVE); //Send FIFO data and receive PICC response
    MFRC_REGR(BITFRAME,&BIT_val);
    MFRC_REGW(BITFRAME,(BIT_val|0x80)); //Start send bit
    HAL_Delay(100);
    MFRC_REGR(IRQ_REG,&IRQval);
    if((IRQval&0x30)!=0x30){ //Return error if RXIRQ and IDLEIRQ bits are not set
        return(HAL_ERROR);
    }

    MFRC_FIFOR(recdata,recsize); //Read and store received data
    return(HAL_OK);
}

main.c代码片段

HAL_Delay(5000);
  MFRC_INIT();
  uint8_t value[18];
  uint8_t CRC_val[2];
  uint8_t FIFO;
  uint8_t transaction[4]={0x30,0x00}; //Read starting from 0x00 and we will receive first four pages (16 bytes) + CRC (2 bytes)
  char mess[]="Transceive Error";
  char messcrc[]="CRC error";
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
      if(CALC_CRC(transaction, 2, CRC_val)!=HAL_OK){
          CDC_Transmit_FS(messcrc, strlen(messcrc));
      }
      memcpy(transaction+2,CRC_val,2);
      //CDC_Transmit_FS(transaction, 4);
      if(MFRC_TRANSCEIVE(transaction, 4, value, 18)!=HAL_OK){

      }
      else{
          CDC_Transmit_FS(value, 18);
      }
      HAL_Delay(1000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

当前排查情况

  • 目标功能:读取MIFARE Ultralight PICC的前4页内存
  • 参考实现:基于广泛使用的MFRC522 Arduino库,但核心的MFRC_TRANSCEIVE函数无法正常工作
  • 发送状态:数据已写入FIFO并发送(发送前FIFO_LEVEL寄存器值为4,发送TRANSCEIVE命令后变为0)
  • CRC疑点:针对读取命令0x30,0x00,MFRC522计算出的CRC为0xA802,与在线ISO CRC计算器结果不符,怀疑CRC错误可能是故障根源,但无法确认

求助需求

除CRC问题外,不确定还有哪些可能的故障点,恳请有MFRC522驱动开发经验的人士提供调试思路。

内容的提问来源于stack exchange,提问作者Swiss Gnome

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 20:52:05