一、概述
特點:
- 自動識別技術的一種。
- 通過無線射頻方式進行非接觸雙向數據通信
- 利用無線射頻方式對記錄媒體(電子標簽或射頻卡)進行讀寫,從而達到識別目標和數據交換的目的。
典型的RFID系統主要包括兩部分:射頻卡/標簽(Tag)和讀寫器( Reader) 。其系統結構和基本工作原理如圖1所示。當前RFID技術研究主要集中在工作頻率選擇、天線設計、防沖突技術和安全與隱私保護等方面。
標簽適用於對象身份識別,對象可以是人或物體。標簽的主要模塊集成在一個芯片中,完成與讀寫器通信的功能;芯片上有內存用來存儲ID或其他數據,其容量從幾個比特到幾千個比特;芯片外圍連接天線或電池。
RFID標簽依據發送射頻信號的方式不同,分為主動式(Active)和被動式( Passive)兩種,
主動式標簽特點:
- 能主動向讀寫器發送射頻信號,
- 通常由內置電池供電,又稱為有源標簽,
- 通信距離遠,其價格相對較高,主要應用於貴重物品遠距離檢測等應用領域。
被動式標簽特點:
- 被動式標簽不帶電池,又稱為無源標簽,
- 從讀寫器的詢問信號中獲取能量工作,具有價格便宜的優勢。
- 工作距離短、存儲容量有限,主要用於近距離識別系統。
讀寫器主要由一個RF模塊和控制單元組成,通常有內置天線,通過射頻信號與標簽通信。讀寫器可以通過有線連接或無線連接與計算機系統相連,把接收到的標簽信息送到主機進行相應處理。
二、RFID模塊介紹
1、 芯片特點:
- 高度集成的非接觸式(13.56MHz)讀寫卡芯片,此發送模塊利用調制和調節的原理,並將它們完全集成到各種非接觸式通信方法和協議中。
- 它支持ISO14443A/MIFARE。
- 支持I2C、SPI、串口通信接口。
- 只能工作於從模式,最高傳輸速率為10 Mbps
2、 參數介紹:
3、接口說明
4、RFID卡識別過程:
(1)尋卡
(2)防沖突
在很多應用場合,讀寫器要在很短時間內盡快識別多個標簽。由於讀寫器和標簽通信共享無線信道,讀寫器或標簽的信號可能發生沖突,使讀寫器不能正確識別標簽,即發生了碰撞(Collision),
(3)選卡
選擇被選中的卡的序列號,並同時返回卡的容量代碼。
(4)操作卡
選定要處理的卡片之后,讀寫器就確定要訪問的扇區號,並對該扇區密碼進行密碼校驗,在三次相互認證之后就可以通過加密流進行通訊。(在選擇另一扇區時,則必須進行另一扇區密碼校驗。)
三、S50非接觸式IC卡性能簡介
1、 主要指標
- 容量為8K位EEPROM
- 分為16個扇區,每個扇區為4塊,每塊16個字節,以塊為存取單位
- 每個扇區有獨立的一組密碼及訪問控制
- 每張卡有唯一序列號,為32位
- 具有防沖突機制,支持多卡操作
- 無電源,自帶天線,內含加密控制邏輯和通訊邏輯電路
- 數據保存期為10年,可改寫10萬次,讀無限次
- 工作溫度:-20℃~50℃(濕度為90%)
- 工作頻率:13.56MHZ
- 通信速率:106 KBPS
- 讀寫距離:10 cm以內(與讀寫器有關)
2、 存儲結構
(1)M1卡分為16個扇區,每個扇區由4塊(塊0、塊1、塊2、塊3)組成,(我們也將16個扇區的64個塊按絕對地址編號為0~63,存貯結構如下圖所示:
|
|
|
|
|
|
塊0 |
|
數據塊 |
0 |
扇區0 |
塊1 |
|
數據塊 |
1 |
|
塊2 |
|
數據塊 |
2 |
|
塊3 |
密碼A 存取控制 密碼B |
控制塊 |
3 |
|
塊0 |
|
數據塊 |
4 |
扇區1 |
塊1 |
|
數據塊 |
5 |
|
塊2 |
|
數據塊 |
6 |
|
塊3 |
密碼A 存取控制 密碼B |
控制塊 |
7 |
|
|
∶ ∶ ∶
|
|
|
|
0 |
|
數據塊 |
60 |
扇區15 |
1 |
|
數據塊 |
61 |
|
2 |
|
數據塊 |
62 |
|
3 |
密碼A 存取控制 密碼B |
控制塊 |
63 |
(2)第0扇區的塊0(即絕對地址0塊),它用於存放廠商代碼,已經固化,不可更改。
(3)每個扇區的塊0、塊1、塊2為數據塊,可用於存貯數據。
數據塊可作兩種應用:
★ 用作一般的數據保存,可以進行讀、寫操作。
★ 用作數據值,可以進行初始化值、加值、減值、讀值操作。
(4)每個扇區的塊3為控制塊,包括了密碼A、存取控制、密碼B。具體結構如下:
A0 A1 A2 A3 A4 A5 FF 07 80 69 B0 B1 B2 B3 B4 B5密碼A(6字節) 存取控制(4字節) 密碼B(6字節)
(5)每個扇區的密碼和存取控制都是獨立的,可以根據實際需要設定各自的密碼及存取控制。存取控制為4個字節,共32位,扇區中的每個塊(包括數據塊和控制塊)的存取條件是由密碼和存取控制共同決定的,在存取控制中每個塊都有相應的三個控制位,
定義如下:
塊0: C10 C20 C30
塊1: C11 C21 C31
塊2: C12 C22 C32
塊3: C13 C23 C33
三個控制位以正和反兩種形式存在於存取控制字節中,決定了該塊的訪問權限(如 進行減值操作必須驗證KEY A,進行加值操作必須驗證KEY B,等等)。三個控制 位在存取控制字節中的位置,以塊0為例:
對塊0的控制:
bit 7 6 5 4 3 2 1 0
字節6 |
|
|
|
C20_b |
|
|
|
C10_b |
字節7 |
|
|
|
C10 |
|
|
|
C30_b |
字節8 |
|
|
|
C30 |
|
|
|
C20 |
字節9 |
|
|
|
|
|
|
|
|
( 注: C10_b表示C10取反 )
存取控制(4字節,其中字節9為備用字節)結構如下所示:
bit 7 6 5 4 3 2 1 0
字節6 |
C23_b |
C22_b |
C21_b |
C20_b |
C13_b |
C12_b |
C11_b |
C10_b |
字節7 |
C13 |
C12 |
C11 |
C10 |
C33_b |
C32_b |
C31_b |
C30_b |
字節8 |
C33 |
C32 |
C31 |
C30 |
C23 |
C22 |
C21 |
C20 |
字節9 |
|
|
|
|
|
|
|
|
( 注: _b表示取反 )
(6)數據塊(塊0、塊1、塊2)的存取控制如下:
控制位(X=0..2)
|
訪 問 條 件 (對數據塊 0、1、2) |
|||||
C1X |
C2X |
C3X |
Read |
Write |
Increment |
Decrement, transfer, Restore |
0 |
0 |
0 |
KeyA|B |
KeyA|B |
KeyA|B |
KeyA|B |
0 |
1 |
0 |
KeyA|B |
Never |
Never |
Never |
1 |
0 |
0 |
KeyA|B |
KeyB |
Never |
Never |
1 |
1 |
0 |
KeyA|B |
KeyB |
KeyB |
KeyA|B |
0 |
0 |
1 |
KeyA|B |
Never |
Never |
KeyA|B |
0 |
1 |
1 |
KeyB |
KeyB |
Never |
Never |
1 |
0 |
1 |
KeyB |
Never |
Never |
Never |
1 |
1 |
1 |
Never |
Never |
Never |
Never |
(KeyA|B 表示密碼A或密碼B,Never表示任何條件下不能實現)
例如:當塊0的存取控制位C10 C20 C30=1 0 0時,驗證密碼A或密碼B正確后可讀;
驗證密碼B正確后可寫;不能進行加值、減值操作。
(7)控制塊塊3的存取控制與數據塊(塊0、1、2)不同,它的存取控制如下:
|
|
|
密碼A |
存取控制 |
密碼B |
|||
C13 |
C23 |
C33 |
Read |
Write |
Read |
Write |
Read |
Write |
0 |
0 |
0 |
Never |
KeyA|B |
KeyA|B |
Never |
KeyA|B |
KeyA|B |
0 |
1 |
0 |
Never |
Never |
KeyA|B |
Never |
KeyA|B |
Never |
1 |
0 |
0 |
Never |
KeyB |
KeyA|B |
Never |
Never |
KeyB |
1 |
1 |
0 |
Never |
Never |
KeyA|B |
Never |
Never |
Never |
0 |
0 |
1 |
Never |
KeyA|B |
KeyA|B |
KeyA|B |
KeyA|B |
KeyA|B |
0 |
1 |
1 |
Never |
KeyB |
KeyA|B |
KeyB |
Never |
KeyB |
1 |
0 |
1 |
Never |
Never |
KeyA|B |
KeyB |
Never |
Never |
1 |
1 |
1 |
Never |
Never |
KeyA|B |
Never |
Never |
Never |
例如:當塊3的存取控制位C13 C23 C33=1 0 0時,表示:
密碼A:不可讀,驗證KEYA或KEYB正確后,可寫(更改)。
存取控制:驗證KEYA或KEYB正確后,可讀、可寫。
密碼B:驗證KEYA或KEYB正確后,可讀、可寫。
3、工作原理
卡片的電氣部分只由一個天線和ASIC組成。
天線:卡片的天線是只有幾組繞線的線圈,很適於封裝到IS0卡片中。
ASIC:卡片的ASIC由一個高速(106KB波特率)的RF接口,一個控制單元和一個8K位EEPROM組成。
原理:讀寫器向M1卡發一組固定頻率的電磁波,卡片內有一個LC串聯諧振電路,其頻率與讀寫器發射的頻率相同,在電磁波的激勵下,LC諧振電路產生共振,從而使電容內有了電荷,在這個電容的另一端,接有一個單向導通的電子泵,將電容內的電荷送到另一個電容內儲存,當所積累的電荷達到2V時,此電容可做為電源為其它電路提供工作電壓,將卡內數據發射出去或接取讀寫器的數據。
4、M1射頻卡與讀寫器的通訊
- 復位應答(Answer to request)
M1射頻卡的通訊協議和通訊波特率是定義好的,當有卡片進入讀寫器的操作范圍時,讀寫器以特定的協議與它通訊,從而確定該卡是否為M1射頻卡,即驗證卡片的卡型。
- 防沖突機制 (Anticollision Loop)
當有多張卡進入讀寫器操作范圍時,防沖突機制會從其中選擇一張進行操作,未選中的則處於空閑模式等待下一次選卡,該過程會返回被選卡的序列號。
- 選擇卡片(Select Tag)
選擇被選中的卡的序列號,並同時返回卡的容量代碼。
- 三次互相確認(3 Pass Authentication)
選定要處理的卡片之后,讀寫器就確定要訪問的扇區號,並對該扇區密碼進行密碼校驗,在三次相互認證之后就可以通過加密流進行通訊。(在選擇另一扇區時,則必須進行另一扇區密碼校驗。)
5、對數據塊的操作
- 讀(Read):讀一個塊;
- 寫 (Write):寫一個塊;
- 加(Increment):對數值塊進行加值;
- 減(Decrement):對數值塊進行減值;
- 存儲(Restore):將塊中的內容存到數據寄存器中;
- 傳輸(Transfer):將數據寄存器中的內容寫入塊中;
- 中止(Halt):將卡置於暫停工作狀態;
三、模塊連接

RFID使用SPI接口時,要使用到七個管腳,分別為VCC、GND、SDA(CS)、SCK、MOSI、MISO、RST.對應連接到STM32F407主板的U13接口的2、1、4、5、6、7、8。


四、代碼編寫
功能要求:
(1)讀出RFID標簽卡的序號和校驗碼。
(2)顯示卡容量。
(3)向卡中寫入數據,並讀出數據查看寫入是否正確。
SPI模式分析:
由RC522規格書可知SPI接口只支持模式3:

(1)main函數
while(1)
{
MFRC522_Initializtion();
MFRC522Test();
delay_s(1);
}
(2)MFRC522的初始化
主要做gpio初始化,復位、定時器計數器設置、模塊啟動和打開天線的功能。
void MFRC522_Initializtion(void)
{
STM32_SPI1_Init();
MFRC522_Reset();
//Timer: TPrescaler*TreloadVal/6.78MHz = 0xD3E*0x32/6.78=25ms
Write_MFRC522(TModeReg,0x8D); //TAuto=1為自動計數模式,受通信協議影向。低4位為預分頻值的高4位
//Write_MFRC522(TModeReg,0x1D); //TAutoRestart=1為自動重載計時,0x0D3E是0.5ms的定時初值//test
Write_MFRC522(TPrescalerReg,0x3E); //預分頻值的低8位
Write_MFRC522(TReloadRegL,0x32); //計數器的低8位
Write_MFRC522(TReloadRegH,0x00); //計數器的高8位
Write_MFRC522(TxAutoReg,0x40); //100%ASK
Write_MFRC522(ModeReg,0x3D); //CRC初始值0x6363
Write_MFRC522(CommandReg,0x00); //啟動MFRC522
//Write_MFRC522(RFCfgReg, 0x7F); //RxGain = 48dB調節卡感應距離
AntennaOn(); //打開天線
}
(3)MFRC522測試函數
u8 mfrc552pidbuf[18]; u8 card_pydebuf[2]; u8 card_numberbuf[5]; u8 card_key0Abuf[6]={0xff,0xff,0xff,0xff,0xff,0xff}; u8 card_writebuf[16]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; u8 card_readbuf[18]; //MFRC522測試函數 void MFRC522Test(void) { u8 i,status,card_size; //0x52 = 尋感應區內所有符合 14443A 標准的卡 //0x26 = 尋未進入休眠狀態的卡 status=MFRC522_Request(0x52, card_pydebuf);//尋卡 // if(status==0) //如果讀到卡 { status=MFRC522_Anticoll(card_numberbuf);//防撞處理 card_size=MFRC522_SelectTag(card_numberbuf);//選卡 status=MFRC522_Auth(0x60, 4, card_key0Abuf, card_numberbuf); //驗卡 status=MFRC522_Write(4, card_writebuf); //寫卡(寫卡要小心,特別是各區的塊3) status=MFRC522_Read(4, card_readbuf);//讀卡 //MFRC522_Halt();//使卡進入休眠狀態 //卡類型顯示 printf("card_pydebuf:%02X %02X\r\n",card_pydebuf[0],card_pydebuf[1]); //卡序列號顯示,最后一字節為卡的校驗碼 printf("Card Number:"); for(i=0;i<5;i++) printf("%02X ",card_numberbuf[i]); printf("\r\n"); //卡容量顯示,單位為Kbits printf("Card Size:%xkbits\r\n",card_size); //讀卡狀態顯示,正常為0 printf("Card Status:%d\r\n",status); //讀一個塊的數據顯示 printf("Read data:"); for(i=0;i<18;i++) printf("%02X ",card_readbuf[i]); printf("\r\n"); PFout(8)=1; delay_ms(100); PFout(8)=0; delay_ms(100); } }