摘要:本應用筆記闡述了在DS5250安全微控制器上輕松實現磁卡讀卡和解碼操作的設計。文章還演示了開發同時具有磁卡讀卡功能和安全微控制器高級加密功能的實際應用。這一實例采用DS5250評估(EV)板連接磁卡讀卡器。本應用筆記提供源代碼,很容易裝載到Maxim的其它8051微控制器中。
本應用筆記介紹怎樣使用DS5250安全微控制器實現和磁卡讀卡器的接口。之所以選擇DS5250,是因為它具有開發常用讀卡設備(例如銷售終端POS等設備)所需要的安全和加密功能。
磁卡讀卡器電路可以執行底層任務:把磁條磁通量解碼成比特流。DS5250管理頂層任務:將這些比特轉換成字符,讀取并驗證數據。
讀卡器工作電平為3V;它不能直接采用DS5250的5V電源供電。由于DS5250評估板不提供3V供電,因此,采用了單獨的線性穩壓器(例如, MAX1658)對讀卡器供電。請參見圖1。
圖1. 實際應用的連接
復位讀卡器時,主機微控制器(例如,本應用筆記的DS5250)必須按照以下順序驅動STROBE和DATA (請參考MagTek文檔,了解確切的電壓電平和時序參數)。
讀卡器通過握手周期告訴主機什么時候開始讀卡,什么時候完成讀卡。
每7位字符在同步輸出時最低有效位(LSB)在前,最高位(即,第7位)是奇偶校驗位,可用于驗證卡數據的完整性。除去奇偶校驗位,其余6位定義了64個字符中的某一個,可以編碼到磁道A上。例如,000000b代表空格符,000001b代表感嘆號。以下代碼為char7bit[64]字符陣列。
注意:由于其內在的安全特性,DS5250安全微控制器受美國出口法的控制。如需獲得包括數據資料、用戶指南在內的所有DS5250文檔,需要簽署保密協議(NDA)。而本應用筆記及其源代碼都可以免費提供,直接裝載到Maxim的任一8051微控制器中。
簡介
背面帶有編碼磁條的卡通常稱為磁卡,廣泛用于銀行、儲值等金融領域。信用卡、ATM和借記卡都是典型的磁卡,有的卡片還嵌入了智能卡芯片。其它應用包括:游戲、影印和公交等領域的禮品卡、安全卡以及房間鑰匙卡等。采用標準ISO格式時,這些磁卡的最大容量只有160字節,一般不能存儲大量數據。與智能卡或便攜式閃存相比,磁卡的存儲容量足以支持金融和銀行應用,被廣泛應用于該領域。而且,磁卡價格低,比較可靠,不需要內部供電,讀取相對方便。本應用筆記介紹怎樣使用DS5250安全微控制器實現和磁卡讀卡器的接口。之所以選擇DS5250,是因為它具有開發常用讀卡設備(例如銷售終端POS等設備)所需要的安全和加密功能。
磁卡讀卡器電路可以執行底層任務:把磁條磁通量解碼成比特流。DS5250管理頂層任務:將這些比特轉換成字符,讀取并驗證數據。
硬件和軟件要求
硬件
本實例采用了DS5250評估(EV)板(B版),進行了以下改動: 實際應用還需要以下硬件:- 讀卡器—MagTek?三磁道讀卡器,含有3V解碼器ASIC;序列號為21030001,G版或更新版本(www.magtek.com/)
- 兩個上拉電阻(大約10kΩ)
- 線性穩壓器(能夠從5V電源產生3V至3.6V供電)
- 用于測試的磁卡(ATM卡、信用卡等)
- MagTek關于Delta三磁道3V讀卡器ASIC的文檔:www.magtek.com/documentation/public/99875337-7.01.pdf
- MagTek關于磁卡磁道位置和格式的文檔: www.magtek.com/documentation/public/99800004-1.pdf
- MagTek磁卡數據的字符轉換表: www.magtek.com/documentation/public/99875065-4.pdf
軟件
本實例應用程序以C語言編寫,采用了Keil的μVision? IDE 2.40a版進行編譯(www.keil.com/)。利用Maxim的微控制器工具包(MTK)將編譯后的應用程序裝載到DS5250中。應用程序的詳細信息
下面幾節介紹實例應用程序的實現。可以從Maxim的FTP網站下載完整的C語言代碼。連接讀卡器
MagTek讀卡器有5個接口引腳(包括電源和地):- 引腳1—STROBE
該信號僅用于讀卡器輸入。由主機微控制器驅動,逐位輸出卡的數據位,觸發復位過程。 - 引腳2—DATA
該信號通常是讀卡器的輸出,包含磁道A/B/C的卡數據位,由STROBE信號同步輸出。在某些情況下(例如,觸發復位時),可以由主機微控制器驅動該信號。 - 引腳3—VDD
讀卡器的電源(2.7V至3.6V)。 - 引腳4—GND
- 引腳5—GND
讀卡器工作電平為3V;它不能直接采用DS5250的5V電源供電。由于DS5250評估板不提供3V供電,因此,采用了單獨的線性穩壓器(例如, MAX1658)對讀卡器供電。請參見圖1。
圖1. 實際應用的連接
復位
首次上電后,主機微控制器在進行讀卡之前必須復位讀卡器。每次進行卡掃描之后,也必須按順序進行復位,以清除內部讀卡器ASIC的內存,使讀卡器能夠準備就緒。接收新的讀卡操作。復位讀卡器時,主機微控制器(例如,本應用筆記的DS5250)必須按照以下順序驅動STROBE和DATA (請參考MagTek文檔,了解確切的電壓電平和時序參數)。
- DATA和STROBE都以高電平(空閑)狀態開始。
- 將DATA置為低電平。
- 保持DATA為低電平,將STROBE驅動為低電平,然后再次驅動為高電平。
- 再次驅動STROBE為低電平,隨后釋放DATA,使其能夠浮空至高電平。
- 當DATA浮空為高電平時,將STROBE驅動為低電平,然后再次驅動為高電平。在這一點,復位讀卡器,處于低功耗等待狀態。
- 將STROBE驅動為低電平,然后再次驅動為高電平。對讀卡器進行“配置”,使其能夠進行讀卡操作。
// Generate a long delay for card reset and read intervals. void longDelay() { int i, j; for (i = 1; i < 5; i++) { for (j = 1; j < 5000; j++) { ; } } } // Generate a shorter delay (used between STROBE/DATA transitions). void delay() { int i; for (i = 1; i < 1000; i++) { ; } } // Release the DATA line (P0.0) and allow it to float high. void dataHigh() { P0 |= 0x01; delay(); } // Drive the DATA line (P0.0) low. void dataLow() { P0 &= 0xFE; delay(); } // Release the STROBE line (P0.1) and allow it to float high. void strobeHigh() { P0 |= 0x02; delay(); } // Drive the STROBE line (P0.1) low. void strobeLow() { P0 &= 0xFD; delay(); } void resetCardReader() { dataHigh(); strobeHigh(); longDelay(); dataLow(); // Force DATA low. longDelay(); strobeLow(); // Drive STROBE low, then high again. strobeHigh(); strobeLow(); // Drive STROBE low, then release DATA. dataHigh(); longDelay(); strobeHigh(); // Drive STROBE low and high again two more times strobeLow(); // to complete the reset and leave the card reader strobeHigh(); // in the ready state, prepared to scan a card. strobeLow(); }
檢測讀卡操作
讀卡器一旦復位并進行配置后,就可以進行讀卡操作。讀卡時,MagTek讀卡器執行一次完整的讀周期;不需要主控制器干預。卡的磁條中所有三個磁道A、B、C的全部內容都被存儲到讀卡器IC中。讀卡周期完成后,可以由主控制器將數據逐位同步輸出。讀卡器通過握手周期告訴主機什么時候開始讀卡,什么時候完成讀卡。
- 該周期以STROBE低電平和DATA浮空高電平(空閑狀態)開始。
- 當讀卡器探測到磁條移過讀卡器探頭時,開始對卡進行掃描。它將DATA線驅動為低電平,告訴主機開始讀卡操作。
- 主機驅動STROBE為高電平,然后再變為低電平,做出響應。
- 讀卡器將DATA再次驅動為高電平。
- 一旦讀卡周期完成后,讀卡器再次將DATA驅動為低電平。這一操作告訴主機已經完成了讀卡過程,可以同步輸出卡數據。
// Wait for the DATA line to be driven low by the card reader. void waitForDataLow() { int i = 0xFF; dataHigh(); // Make sure that DATA is floating high. while ((i & 1) == 1) { i = P0; } } .... resetCardReader(); printf("\r\n"); printf("Waiting for card swipe...\r\n"); printf("\r\n"); waitForDataLow(); // DATA low indicates that card swipe has begun. strobeHigh(); longDelay(); strobeLow(); longDelay(); waitForDataLow(); // DATA low indicates that card swipe is complete.
讀取并解碼卡數據
完成讀卡,并且所有卡數據經過解碼并存儲在讀卡器ASIC后,讀卡器將DATA線驅動為低電平。如上所述,這一操作提示DS5250可以同步輸出卡數據。在這一點,DS5250在同步輸出每一位數據時,將STROBE驅動為高電平,然后再驅動低電平,以順序讀出每一位卡數據。在STROBE驅動為高電平,然后再驅動為低電平后,讀卡器ASIC將下一位數據在DATA線上同步輸出。ASIC在第0位將DATA驅動為高電平,第1位時將DATA驅動為低電平。// Clock a single bit value out of the card reader by driving STROBE high, // then low, and reading the DATA line. int readBit() { int i; strobeHigh(); // Drive STROBE high. strobeLow(); // Drive STROBE low (DATA line now contains bit). i = P0; if ((i & 1) == 0) { return 1; // Low on DATA line indicates a 1 bit. } else { return 0; // High on DATA line indicates a 0 bit. } }讀卡器同步輸出的前16位是“前導”位,指出讀卡器ASIC的版本。這些為并非卡的數據,應用程序可以忽略它們。
磁道A譯碼
16位前導碼之后,DATA線上同步輸出704位數據,其中包括從磁卡磁道A讀取的數據。當采用標準ISO格式進行編碼時,磁道A含有76個字符,使用的7位字符集含有字母、數字等符號。每7位字符在同步輸出時最低有效位(LSB)在前,最高位(即,第7位)是奇偶校驗位,可用于驗證卡數據的完整性。除去奇偶校驗位,其余6位定義了64個字符中的某一個,可以編碼到磁道A上。例如,000000b代表空格符,000001b代表感嘆號。以下代碼為char7bit[64]字符陣列。
// 0123456789012345678901234567890123456789012345678901234567890 123 char char7bit[64] = " !'#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"; // Clock out and decode a 7-bit character from the track memory, returning the // character value. 7-bit (alphanumeric) characters are found on Track A only. char read7BitChar() { int i, c; // Each character is composed of 7 bits, which we clock out of the track memory // beginning with the least significant bit. Bit 7 is parity, which is ignored. c = 0; for (i = 1; i < 128; i *= 2) { c |= (readBit() * i); } c &= 0x3F; return char7bit[c]; // Decode/return the character using the 7-bit table. } .... // Track A - 76 characters, 7 bits per alphanumberic character including parity. printf("Track A > "); for (i = 0; i < 76; i++) { putchar(read7BitChar()); } printf("\r\n\r\n"); // At this point, we have read 532 bits of the 704-bit Track A memory on the // card reader IC. Flush the remaining 172 bits. for (i = 0; i < 172; i++) { readBit(); }不同類型的卡在磁道A上有不同的數據。磁道A還可以含有字母字符。因此,磁道A常用于存儲持卡人的姓名、地址和賬號等數字信息。正如上面代碼所示,在同步輸出磁道B的數據之前,必須讀出磁道A的所有704位數據(即使并非所有位都含有編碼數據)。
磁道B譯碼
磁道B的編碼和磁道A相似,只是采用了5位(4位數據和1位奇偶校驗位)編碼,而不是7位編碼。磁道B的字符集只含有數字字符和符號,如下面的char5bit[16]字符陣列所示。// 0123456789012345 char char5bit[16] = "0123456789:;<=>?"; // Clock out and decode a 5-bit character from the track memory, returning the // character value. 5-bit (numeric+symbol) characters are found on Tracks B and C. char read5BitChar() { int i, c; // Each character is composed of 5 bits, which we clock out of the track memory // beginning with the least significant bit. Bit 5 is parity, which is ignored. c = 0; for (i = 1; i < 32; i *= 2) { c |= (readBit() * i); } c &= 0x0F; return char5bit[c]; // Decode/return the character using the 5-bit table. } .... // Track B - 40 characters, 5 bits per numeric/symbol character including parity. printf("Track B > "); for (i = 0; i < 40; i++) { putchar(read5BitChar()); } printf("\r\n\r\n");在磁道A的最后,讀取磁道C之前,必須讀取磁道B的所有剩余位(如果需要用到磁道C)。由于已經從磁道B (40個字符 x 5位)讀取了200位,在訪問磁道C之前,必須同步輸出其余504位。
磁道C譯碼
磁道C的編碼方式和磁道B一樣,并采用了同一字符集,最多可編碼107個7位字符。磁道C最初的目的是作為可寫數據區,以支持離線金融交易,但不常用。大部分磁卡在磁道C上不帶有編碼數據。結論
磁卡廣泛應用于金融、接入控制、政府以及儲值等領域。通過加入一個簡單的MagTek卡掃描讀卡器,為DS5250評估板提供少量的支持硬件,開發系統即可支持磁卡讀取功能以及安全微控制器的高級安全加密功能。利用Keil的μVision C編譯器,很容易在DS5250安全微控制器上演示磁卡讀取和解碼功能。注意:由于其內在的安全特性,DS5250安全微控制器受美國出口法的控制。如需獲得包括數據資料、用戶指南在內的所有DS5250文檔,需要簽署保密協議(NDA)。而本應用筆記及其源代碼都可以免費提供,直接裝載到Maxim的任一8051微控制器中。
評論
查看更多