最近開始研究了FM1702sl IC卡,覺得很有必要解決一些開發中存在的問題。
一、 M1射頻卡與讀寫器的通訊
相信大家對這樣的讀卡流程不陌生。
二、 存儲結構
1、 M1卡分為16個扇區,每個扇區由4塊(塊0、塊1、塊2、塊3)組成,(我們也将16個扇區的64個塊按絕對位址編号為0~63,存貯結構如下圖所示:
塊0 | 資料塊 | ||
扇區0 | 塊1 | 資料塊 | 1 |
塊2 | 資料塊 | 2 | |
塊3 | 密碼A 存取控制 密碼B | 控制塊 | 3 |
塊0 | 資料塊 | 4 | |
扇區1 | 塊1 | 資料塊 | 5 |
塊2 | 資料塊 | 6 | |
塊3 | 密碼A 存取控制 密碼B | 控制塊 | 7 |
∶ ∶ ∶ | |||
資料塊 | 60 | ||
扇區15 | 1 | 資料塊 | 61 |
2 | 資料塊 | 62 | |
3 | 密碼A 存取控制 密碼B | 控制塊 | 63 |
2、 第0扇區的塊0(即絕對位址0塊),它用于存放廠商代碼,已經固化,不可更改。
3、 每個扇區的塊0、塊1、塊2為資料塊,可用于存貯資料。
資料塊可作兩種應用:
★ 用作一般的資料儲存,可以進行讀、寫操作。
★ 用作資料值,可以進行初始化值、加值、減值、讀值操作。
4、 每個扇區的塊3為控制塊,包括了密碼A、存取控制、密碼B。具體結構如下:
密碼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.1.2) | 訪 問 條 件 (對資料塊 0、1、2) | |||||
C1X | C2X | C3X | Read | Write | Increment | Decrement, transfer, Restore |
KeyA|B | KeyA|B | KeyA|B | KeyA|B | |||
1 | KeyA|B | Never | Never | Never | ||
1 | KeyA|B | KeyB | Never | Never | ||
1 | 1 | KeyA|B | KeyB | KeyB | KeyA|B | |
1 | KeyA|B | Never | Never | KeyA|B | ||
1 | 1 | KeyB | KeyB | Never | Never | |
1 | 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 |
Never | KeyA|B | KeyA|B | Never | KeyA|B | KeyA|B | |||
1 | Never | Never | KeyA|B | Never | KeyA|B | Never | ||
1 | Never | KeyB | KeyA|B | Never | Never | KeyB | ||
1 | 1 | Never | Never | KeyA|B | Never | Never | Never | |
1 | Never | KeyA|B | KeyA|B | KeyA|B | KeyA|B | KeyA|B | ||
1 | 1 | Never | KeyB | KeyA|B | KeyB | Never | KeyB | |
1 | 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正确後,可讀、可寫。
三、 工作原理
卡片的電氣部分隻由一個天線和ASIC組成。
天線:卡片的天線是隻有幾組繞線的線圈,很适于封裝到IS0卡片中。
ASIC:卡片的ASIC由一個高速(106KB波特率)的RF接口,一個控制單元和一個
8K位EEPROM組成。
工作原理:讀寫器向M1卡發一組固定頻率的電磁波,卡片内有一個LC串聯諧振電路,其頻率與讀寫器發射的頻率相同,在電磁波的激勵下,LC諧振電路産生共振,進而使電容内有了電荷,在這個電容的另一端,接有一個單向導通的電子泵,将電容内的電荷送到另一個電容内儲存,當所積累的電荷達到2V時,此電容可做為電源為其它電路提供工作電壓,将卡内資料發射出去或接取讀寫器的資料。
我在stm32上進行了一些測試,主要源碼如下
int main(void)
{
uchar i;
unsigned char status, try;
unsigned char buf[16], DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE};
unsigned char buffer[16]={"123fddd"};
//System_Setup();
NVIC_Configuration();
GPIO_ini();
InitializeSystem( );
USART_Configuration();
LED_Configuration();
RS232_REC_Flag=0;
while (1)
{
try = 4;
while(--try)
{
status = Request(RF_CMD_REQUEST_ALL); //尋卡
if(status != FM1702_OK) continue;
status = AntiColl(); //沖突檢測
if(status != FM1702_OK) continue;
status=Select_Card(); //選卡
if(status != FM1702_OK) continue;
status = Load_keyE2_CPY(DefaultKey); //加載密碼
if(status != TRUE) continue;
status = Authentication(UID, 4, RF_CMD_AUTH_LB); //驗證1扇區keyA
if(status != FM1702_OK) continue;
if(RS232_REC_Flag==1)
{
status=MIF_Write(RS232_buff,19); //寫卡,将buffer[0]-buffer[15]寫入1扇區0塊
memsets(RS232_buff);
delay(100);
RS232_rec_counter = 0;//發送完将接收計數器清零
}else{
status=MIF_READ(buf,19); //讀卡,讀取1扇區0塊資料到buffer[0]-buffer[15]
}
if(status == FM1702_OK)
{
if(RS232_REC_Flag==1)
{
//RS232_Send_Data("write:",6);
RS232_REC_Flag = 0;
}
else
{
//RS232_Send_Data("read:",5);
delay(100);
RS232_Send_Data(buf,16);
}
LED_ON;
delay(10000);
}
}
if(try == 0) LED_OFF;
}
}
序列槽得到的資料如下
這裡需要解釋地方就是這些資料,00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FE 為密碼區的資料,前六位為keyA,之是以為00是因為他對使用者不是透明的,不管你怎麼修改keyA密碼,但是keyB不是。是以我們看到了B的密碼為 FF FF FF FF FF FE 。我們通過序列槽發送資料到讀卡器修改這個扇區的密碼,也就是發送區的資料。我們将密碼B改為了FF FF FF FF FF FE ,keyA為 00 00 00 00 00 00。實際上keyA key B初始密碼都為FF FF FF FF FF FF 當然因卡而定。
這是我覺得最為重要的一個地方。
有一個問題答疑的地方如下:
1 問:多張卡在讀卡器上的時候,我讀取了其中一張卡的時候,然後要執行halt操作才可以其他的卡
答:這是可以的
2 問:讀到一張卡的時候,在沒有執行halt操作之前,如果再操作這張卡,且在同一扇區,那麼直接執行讀操作時就不用再重複執行防沖突選卡操作
答:可以的
3 問:至于要換成其他的扇區時候
答 : 讀是可以的,寫要重新尋卡等一系列操作。
有什麼疑問可以咨詢我:QQ:978508554