Library 23- Read RFID tag with MF RC522 on STM32F4

In this library I’m talking about RFID (Radio-Frequency IDentification).

Radio-frequency identification (RFID) is the wireless non-contact use of radio-frequency electromagnetic fields to transfer data, for the purposes of automatically identifying and tracking tags attached to objects. The tags contain electronically stored information. Some tags are powered by and read at short ranges (a few meters) via magnetic fields (electromagnetic induction). Others use a local power source such as a battery, or else have no battery but collect energy from the interrogating EM field, and then act as a passive transponder to emit microwaves or UHFradio waves (i.e., electromagnetic radiation at high frequencies). Battery powered tags may operate at hundreds of meters. Unlike a barcode, the tag does not necessarily need to be within line of sight of the reader, and may be embedded in the tracked object.

source: For that I used Mifare RC522 RFID reader from NXP. I got it on Ebay almost for free with 2 RFID cards included. This chip works with RFID on 13.56MHz. To get this to work, you also need RFID cards with same working frequency (included in packet from ebay). I got this working on STM32F429 Discovery board with SPI communication and display data on LCD on board. Detection distance was about 10cm from receiver.



  • Read RFID card at 13.56MHz
  • Working with SPI


    • STM32F4xx
    • STM32F4xx RCC
    • STM32F4xx GPIO
    • STM32F4xx SPI
  • TM
    • TM SPI
    • defines.h


My RFID uses SPI. This chip has also support for UART or I2C communication. And also, my RFID board has CS (chip select) pin marked as SDA (I2C Serial Data) so don’t worry if you don’t have CS pin on your board.

CS (SDA) PG2 Chip select for SPI
SCK PB3 Serial Clock for SPI
MISO PB4 Master In Slave Out for SPI
MOSI PB5 Master Out Slave In for SPI
GND GND Ground
VCC 3.3V 3.3V power
RST 3.3V Reset pin

You can also choose other pins. To change them open your defines.h file and edit what you need

Initialize RC522

Initialize chip with function below

Check RFID Card

To check if card was put on receiver, you can check this with function below

Compare RFID Card

I also made a compare function, which is reeealy simple function to compare 2 5 bytes long arrays if they are equal. Useful when you have to compare your ID number with card number to detect if you “have access” to eg. open door.


In this example I check for my RFID card (blue). RFID reads card id and if they are equal, it simply write data to LCD.

No RFID Card on receiver

No RFID Card on receiver

RFID Card detected and OK

RFID Card detected and OK

RFID Card detected OK but wrong card

RFID Card detected OK but wrong card

View project on Github, download library below.

TM STM32F4 MFRC522 Library

Read RFID Cards with Mifare MF RC522


Owner of this site. Also electronic enthusiasts, web developer, 3D printer fan, handball player and more. Big fan of STM32F4 devices. In anticipation of the new Discovery board for STM32F7 lines.

You may also like...

Read before commenting!

Before you make a new comment, make sure you agree with things listed below:

  • - Read post to make sure if it is already posted what you are asking for,
  • - Make sure you have the latest version of libraries used in your project,
  • - Make a clean and grammatically correct written message,
  • - Report as many details as possible, including what have you done so far,
  • - Do NOT post any code here. Use Pastebin,
  • - Do NOT post any error codes here. Use Pastebin,
  • - Specify STM32Fxxx family and used Discovery/EVAL/Nucleo or custom made board,
  • - Make sure your clock is set correct for PLL,
  • - If you are using my HAL drivers, please check this post how to start.
Comment will be deleted on breaking these rules without notification!
  • vahid


    I use your code for using RFID. but the function of TM_MFRC522_Check(CardID) returns “MI_ERR “. Can you help me?

    • Hi,

      Invalid pinout? No valid card? Is your card there?…Many options 🙂

      • vahid

        Already checked the card with nfc reader on a cell phone. Pinout seem fine. Apparently the easy way of copy paste, didn’t work for me. SPI communication works but I can’t read the ID.
        Anyway, I don’t have that much background on the mechanism of the whole system to realize how it works to be able to debug. can you introduce some useful sources. MFRC522 datasheet is barely understandable.

  • tran huu trung

    Hi. when i compling tm_stm32f4_spi.c. Errors occur at line #20 “SPI4” “SPI5” “SPI6” and “GPIO_AF_SPI4, 5 , 6” are undefined. i already add your GPIO and SPI libraries. can you fix me? tks a lot

    • Update standard peripheral drivers.

      • tran huu trung

        i have already updated driver.i use keil v5

        • No, you didn’t.
          If you would, that error will never come.
          1.0.8 pack version is needed at least.

          • Mohammad Kamel

            hi i have a question i have such a problem i got a new library from but when i add them by hand it doesnt work and i use coocox with i cant update its default library like its spi what should i do please help me thank you alot

          • What doesn’t work here?

          • Mohammad Kamel

            when i use your code i have some errors said SPI5 not declared and …… you said the problem is peripheral drivers i downloded the newest library but i still has problem and i use coocox and dont khow how to update its internall drivvers for example its spi what should i do thank you

          • That’s true what I said.

            Please, show me a link of what you downloaded.
            Newest STD drivers for F4 are version 1.5.1.

          • Mohammad Kamel

            here you are:


            and one more question how can i update the internal coocox library like its spi instead of adding what i need by hand one by one

          • If you would do really that, then errors won’t happen.

            I have no idea. I’m not using Coocox. And I always include all necessary files from external files, nothing “built-in” inside programs because when updates are done, everything may fail.

          • Mohammad Kamel

            oh thank you alot i will work harder to understand what is the problem thank you alot

          • Mohammad Kamel

            excuse me i found a toutorial about my problem but i dont khow which on of its start_up i must use thank you i confused beetwen number one and two i use stm32f407vg thankyou alot

          • then select 40_41xxx.s

  • kavita

    how can i use MFRC522 with interrupt

  • ali goya


    i used your code that was fantastic thanks for sharing this code

    but i have a question i need to write sth in rfid card blocks and then read them i think

    i must use read or write methods but how ?? i dont khow the block addresses

    how can i find their addresses to write sth on them

    thanks for your help

  • kavita

    how can i get data from blocks of MFRC522

  • Daniel Ponzo

    Hi Tilen,
    my mr522an module has a ss pin instead of cs pin which i suppose is the same thing. pls. correct me if wrong.
    besides, f4 disco does not have pg2 then i´ve changed lines of _mfrc522.h so as to set port B pin 6 for cs (ss).
    but it still not running.
    could you suggest something¿?
    best regards.

    • Hello,

      Yes, CS (Chip Select) is the sane as SS (Slave Select).
      Show me how you changed settings.

      • Daniel Ponzo

        Have changed as written after // in Default CS pin used:

        * Pinout
        * Can be overwritten in defines.h file
        /* Default SPI used */
        #ifndef MFRC522_SPI
        #define MFRC522_SPI SPI1
        #define MFRC522_SPI_PINSPACK TM_SPI_PinsPack_2

        /* Default CS pin used */
        #ifndef MFRC522_CS_PIN
        #define MFRC522_CS_RCC RCC_AHB1Periph_GPIOG // changed to _GPIOB #define MFRC522_CS_PORT GPIOG // changed to GPIOB
        #define MFRC522_CS_PIN GPIO_Pin_2 // changed to GPIO_Pin_6


        2015-11-19 19:24 GMT-03:00 Disqus :

  • insaf

    hello, would you please tell me from where did u get the values uint8_t MyID[4] = {21, 0xdc, 0x52, 0xb6, 0x7b} ? is it from dumpInfo ? i can’t get mine

    • Function TM_MFRC522_Check returns MI_OK when card is detected. Pointer passedto this function has then valid card ID. So I record some my cards and write them to lcd for test to see its id values.

      • insaf

        thank you for responding. Actually i have a problem that TM_MFRC522_Status_t is “undefined” when i compile and i’m using stm32f407. i removed the part of the LCD in your code but i am not able to read the tag

  • darlington

    Hi, thank you for this tutorial!
    I tried to implement your code, I can see the version of my rc522 (0x37 register) so the SPI communication is working but when I try to check cards, TM_MRFC522_ToCard is called and then i=0 so status is ERR. Have you got any idea?
    Thank you!

    • I don’t have. Is card compatible with RC522?

    • Francisco Jimenes

      Maybe you do right Check() and Anticoll process. I have MI_NOTAGERR or MI_ERR if change value of i=2000. I=200 or low implies I decrements to 0, I with high values imply MI_NOTAGERR. (Because of Timer unit IRQ has reached value of 0). Finally. Have you completed the SelectTag process and Authentication process?.

      Thank you.

  • darlington

    Yes, it works with arduino.
    n = TM_MFRC522_ReadRegister(MFRC522_REG_COMM_IRQ);
    This line gives me 0x04 for the 2000 call, could it be the issue?

  • Tin

    Hi Tilen, i have an small issue. in TM_MFRC522_Check function you have TM_MFRC522_Halt(). i dont about TM_MFRC522_Halt(). can you explain about its function? Thanks!

  • Nick

    Hello, Tilen!

    Thanks for your library! Your example works good. But could you help me with one problem?

    How to read dump of memory of RFID card using your library? Functions TM_Auth and TM_Read do not work properly – authentification always return MI_ERROR.

    And why Card ID is 5 element buffer? As I understand, it must be 4 or 7 bytes.

    Do you have any examples of reading memory of RFID cards? I would be very grateful, if you send me them.

    • Hi,

      actually I don’t have functions for reading data.

      • Nick

        So, with your library I can only read card id and no more?

  • tarik sah

    hi Tilen
    Thanks your library but i cant build this project.
    keil says undefined symbol DMA_DeInit and DMA_Init (they are refered your library tm_stm32f4_spi_dma )
    thank you.

  • Bekir

    Hello, Tilen! Thanks for sharing really good tutorials. I’ve learned a lot from you. Could you please do some more example of this librarry ? Writing some data into TAG and than reading would be helpful. If you have time, CRC included examples too. Thanks a lot.

  • mert

    Hello,how to do write data on card sectors? Would you give me example code? Thank you

    • This lib does not write.

      • mert

        Hello Tilen,Do you know how it is done or lib code?

  • dinhthong

    Can you explain what this function does in the mfrc522.c:
    TM_MFRC522_Status_t TM_MFRC522_ToCard
    btw, I would like to ask how long did you work on this project to make it worked?
    Because reading the datasheet and understanding what things does takes a lot of time… Hope you share your experience ! Thanks a lot.

    • In fact, I didn’t write it entirely but port it to STM32 from other sources.
      Datasheet reading before it starts working is very painful process, for me it was impossible that time.

      I managed to geet reading to work but it may not be perfect because of hard to understand.

      That’s the reason why writing is not implemented yet and I’m not planning to do it in the future.

  • dava

    hi.How am ı import #include “defines.h”.I am using HAL library

  • Võ Kiệt

    can use this library for STM32f411VE with library HAL ??

    • It can work, just a little port is required.

      • Võ Kiệt

        i don’t understand ? can you explain for me ?

  • Pingback: STM32F4 RFID project full code and pinouts – Everything in this world I can imagine and share()

  • Francisco Luna Garcia

    Hi Tilen,

    I have a problem: when I try to authenticate my mifare card using MFRC422_Auth(*) functions, It returns error -> the MFRC522_REG_STATUS2 is always 0 value.
    In my case, I want to read bolck 3, sector 16 with key FFFFFFFF. The call function is as follows:

    statusRFID = TM_MFRC522_Auth(0x60,63, RFID_KEY, CardID)

    This returns statusRFID = MI_OK; but later when I call readRegister(MFRC522_REG_STATUS2) & 0x08) , statusRFID turns MI_ERR.


    • I wouldn’t know. I’m not that detailed expert on this device.

  • Francisco Jimenes

    Hi Tilen. I have same problem as Francisco Luna.

    It seem that only I can check and do anticoll (getting UID serial manufacturer number) but I have problem in receiving data from RFID when I want to do:

    1) Select TAG process.
    2) Authentication process.

    Process for sending check requires 1 byte to send and Anticoll process 2 byte to send into the main function.

    TM_MFRC522_Status_t TM_MFRC522_ToCard(uint8_t command, uint8_t* sendData, uint8_t sendLen, uint8_t* backData, uint16_t* backLen);

    Process for Select TAG requires 9 bytes, and authentication similar bytes (I suppose 8-9).

    I have seen a lot of issues with this and management of SPI hardware. I use Hardware SPI , I have tested with emulated SPI using GPIO lines. But same results, only process that go ok are Check and Anticoll. My microcontroller is STM32F030CC.

    I have tested one similar code as yours in python, using one raspberry with MFRC522, It does all process.

    What do you think it is?

    Thanks a lot.

    Francis Jimenez