2019年8月16日 星期五

寫入資料到RFID卡片

寫入資料到RFID卡片



參考資料:

RFID卡片中的資料是存在內部的記憶體中,所以,要對卡片進行讀寫,必須先認識卡片內部記憶體的結構。
RFID卡片有幾種不同的類型,Mifare 1最常用且與悠遊卡相容。 

Mifare 1 卡片說明:

記憶體結構

  • 資料記憶體容量為8K EEPROM
  • 分為16個扇區(sector 0~15)
  • 1個扇區有4個區塊(block0~4)
  • 1個區塊有16 Byte(密碼A:6 Bytes;存取控制:4 Bytes:密碼B:6 Bytes)
  • 最右側為區塊絕對編號。(範例程式將會使用此編號)


記憶體使用

  • 扇區0的區塊0的固定存放廠商代碼,不可更改。
  • 每個扇區的區塊0~2為使用者資料區塊,可以存入任何資料。
  • 每個扇區的區塊3為控制區塊,規定依序存放密碼A(6 Bytes)、讀寫控制位元(6 Bytes)及密碼B(6 Bytes)

存取控制

  • 每個扇區都有獨立的"密碼"及"存取控制位元"來控制記憶體資料的存取。
  • 換句話說,要存取區塊內資料需先提供正確的"密碼"及"存取控制位元",否則,資料是不可被隨意存取的。

範例程式說明


(本範例所需函式都包含在同一檔案中,不要與另一篇文章<RFID 讀卡模組運用 >所提MFRC522 Library混用)

硬體接線:

參考http://arduino.cc/en/Reference/SPI,配合所用的Arduino板將7條線接妥。

 RFID 模組 Arduino ICSP
 RST Reset
 3V3 不用接
 MISO MISO
 MISI
(電路板印刷有誤,應為MOSI)
 MOSI
 SCK SCK
 SS pin 10(或可自訂)
 VIN         Vcc     
 GND Gnd

軟體修改:

搜尋下列程式碼,修改數值以配合硬體實際腳位
const int chipSelectPin = 10;    //SS 接腳位置
const int NRSTPD = 5;            //RST接腳位置

此範例主要做以下幾件事情:

  1. 尋找卡片,回傳卡片型態代號。程式行#166~
  2. 呼叫防衝撞程序(Anti-collision loop),回傳卡片序號。程式行#177~
  3. 選擇作用卡片 。程式行#196 ~ 
  4. 寫入新密碼到區塊11(控制區塊),寫入數值100到區塊8(資料區塊)的位址。程式行#206 ~ 
  5. 讀取區塊8的資料。程式行#230 ~ 
  6. 讀取區塊8,減18,運算完成將結果重新寫入。程式行#250 ~
  7. 讀取區塊8,加10,運算完成將結果重新寫入。程式行#278 ~
  8. 中止卡片存取,進入睡眠模式。程式行#308:MFRC522_Halt();

完整的RFID卡片讀寫程序

要對卡片進行讀寫,必須經過一連串的步驟,如下圖所示:




以下簡單說明上圖所示程序所用之函式:

尋找卡片/複位應答(Answer to Request)

呼叫MFRC522_Request(),需要傳入2個參數:
  1. 搜尋模式
  2. 卡片型態回傳位址
參考程式行#718~
/*
* Function:MFRC522_Request
* Description:Find card and read its type
* Input values:reqMode--way to find the card;
*                         TagType--return type of card:
*                                 0x4400 = Mifare_UltraLight
*                                0x0400 = Mifare_One(S50)
*                                0x0200 = Mifare_One(S70)
*                                0x0800 = Mifare_Pro(X)
*                                0x4403 = Mifare_DESFire
* Output value:successful return MI_OK
*/

讀取卡片序號/防衝撞機制

呼叫MFRC522_Anticoll(),使用防衝撞程序來完成讀取卡號。
需要傳入1個位址(指標)參數,以接收序號回傳結果。
參考程式行#603~
/*
* Function:MFRC522_Anticoll
* Description:Anti-collision detection and card serial number reading
* Input values:serNum--return the four byte card serial number, the first five bytes of the checksum
* Output value:Successful return MI_OK
*/

選擇作用卡片

呼叫MFRC522_SelectTag(),需要傳入序號參數,以告知哪一張卡片被選擇了。
參考程式行#680~
/*
* Function:MFRC522_SelectTag
* Description:Election card, read memory capacity
* Input values:serNum--incoming card serial number
* Output value:Successful return of card capacity
*/

認證(Authentication)

一般不管讀取或寫入資料到卡片,都要先經過密碼認證:(參考程式行#208)
呼叫MFRC522_Auth(),需要傳入4個參數:
  1. authMode:認證模式(PICC_AUTHENT1A)
  2. BlockAddr:區塊(絕對)編號
  3. Sectorkey:密碼
  4. serNum:卡片序號
見程式行#718~
/*
* Function:MFRC522_Auth
* Description:Verify card password
* Input values:authMode--Passowrd authentication mode
0x60 = Verify A key
0x61 = Verify B key
BlockAddr--Block address
Sectorkey--Sector's password
serNum--Card serial number, 4 bytes
* Output value:Successful return MI_OK
*/

寫入資料

呼叫MFRC522_Write(),需要傳入2個參數:
  1. 區塊編號
  2. 欲寫入資料
函式原始碼及說明見程式行#783~
/*
* Function:MFRC522_Write
* Description:Write block data
* Input values:blockAddr--block address;writeData--16 bytes of data to be written to block
* Output value:Successful return MI_OK
*/

讀取資料

呼叫MFRC522_Read(),需要傳入2個參數:
  1. 區塊編號
  2. 結果回傳位址
/*
* Function:MFRC522_Read
* Description:Read block data
* Input values:blockAddr--block address;recvData--read a block of data
* Output value:Successful return MI_OK
*/

中止

呼叫MFRC522_Halt()
Ċ
Jonathan Cheng, 
2013年12月1日 上午2:59
ċ
RFID.ino 
(24k)
Jonathan Cheng, 
2013年12月1日 上午6:48
Ċ
mifare_ic.pdf 
(555k)
Jonathan Cheng, 
2013年12月5日 上午6:29

沒有留言:

張貼留言

WOKWI DHT22 & LED , Node-Red + SQLite database

 WOKWI DHT22 & LED , Node-Red + SQLite database Node-Red程式 [{"id":"6f0240353e534bbd","type":"comment&...