在當(dāng)前的金融POS終端及相關(guān)領(lǐng)域,ISO7816通訊協(xié)議得到了廣泛應(yīng)用。英創(chuàng)的工控主板EM9161,可在其異步串口的基礎(chǔ)上,通過(guò)簡(jiǎn)單的設(shè)置,就可把串口轉(zhuǎn)為符合ISO7816協(xié)議的接口,實(shí)現(xiàn)與各種智能卡的通訊。本文主要介紹采用EM9161的COM2口,實(shí)現(xiàn)ISO7816通訊的基本方法。
上圖表示EM9161作為ISO7816主控方與智能卡的連接示意圖,其中原COM2口的數(shù)據(jù)發(fā)送管腳TXD2作為ISO7816的半雙工數(shù)據(jù)信號(hào)DIO;原COM2口的RTS2n控制線作為ISO7816的時(shí)鐘信號(hào)SCK。兩個(gè)信號(hào)線的電平均為3.3V的TTL信號(hào)電平。
應(yīng)用程序進(jìn)行ISO7816通訊的基本流程為:
1、按標(biāo)準(zhǔn)方法打開(kāi)串口“COM2:”,并設(shè)置相應(yīng)串口參數(shù);
2、通過(guò)DeviceIoControl(…)函數(shù)使能ISO7816通訊模式,并設(shè)置相關(guān)參數(shù);
3、設(shè)置波特率,注意在使能ISO7816模式后,必須重新設(shè)置波特率;
4、進(jìn)行數(shù)據(jù)通訊,數(shù)據(jù)幀的奇偶校驗(yàn)位需要與通訊對(duì)端匹配;
5、通過(guò)DeviceIoControl(…)函數(shù)禁止ISO7816通訊模式;
6、按標(biāo)準(zhǔn)方法關(guān)閉串口“COM2:”。
為了實(shí)現(xiàn)從通常的異步串口到ISO7816的轉(zhuǎn)換,EM9161的串口驅(qū)動(dòng)增加了2個(gè)IOCTL功能如下:
#include
#define IOCTL_SERIAL_ENABLE_ISO7816\
CTL_CODE(FILE_DEVICE_SERIAL_PORT,40,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_SERIAL_DISABLE_ISO7816 \
CTL_CODE(FILE_DEVICE_SERIAL_PORT,41,METHOD_BUFFERED,FILE_ANY_ACCESS)
使能ISO7816的DeviceIoControl調(diào)用,需要同時(shí)設(shè)置相應(yīng)的參數(shù)。這些參數(shù)包括ISO7816的協(xié)議類型,幀數(shù)據(jù)的應(yīng)答規(guī)范等,定義相應(yīng)的參數(shù)如下:
#define AT91C_US_USMODE_ISO7816_0 0x4// ISO7816 protocol: T = 0
#define AT91C_US_USMODE_ISO7816_1 0x6 // ISO7816 protocol: T = 1
#define AT91C_US_INACK (0x1 << 20)??? // Inhibit Non Acknowledge
#define AT91C_US_DSNACK (0x1 << 21)??? // Disable Successive NACK
此外ISO的波特率按如下公式計(jì)算:
BR = (DI / FI)× SCK
上式中的SCK = 串口波特率×FI / DI,例如串口波特率為9600,F(xiàn)I / DI = 372,則SCK時(shí)鐘頻率為3.57MHz。在EM9161中,對(duì)DI和FI的設(shè)置,是通過(guò)設(shè)置(FI/DI)這個(gè)比值來(lái)實(shí)現(xiàn)的,其中有效的值如下表所示:
DI = 1 |
DI = 2 |
DI = 4 |
DI = 8 |
DI = 16 |
DI = 32 |
DI = 12 |
DI = 20 |
|
FI = 372 |
372 |
186 |
93 |
47 |
23 |
12 |
31 |
19 |
FI = 558 |
558 |
279 |
140 |
70 |
35 |
17 |
47 |
28 |
FI = 774 |
774 |
372 |
186 |
93 |
47 |
23 |
62 |
37 |
FI = 1116 |
1116 |
558 |
279 |
140 |
70 |
35 |
93 |
56 |
FI = 1488 |
1488 |
744 |
372 |
186 |
93 |
47 |
124 |
74 |
FI = 1806 |
1806 |
930 |
465 |
233 |
116 |
58 |
155 |
93 |
FI = 512 |
512 |
256 |
128 |
64 |
32 |
16 |
43 |
26 |
FI = 768 |
768 |
384 |
192 |
96 |
48 |
24 |
64 |
38 |
FI = 1024 |
1024 |
512 |
256 |
128 |
64 |
32 |
85 |
51 |
FI = 1536 |
1536 |
768 |
384 |
192 |
96 |
48 |
128 |
77 |
FI = 2048 |
2048 |
1024 |
512 |
256 |
128 |
64 |
171 |
102 |
選擇藍(lán)色區(qū)域的值,可得到對(duì)應(yīng)的黃色區(qū)域的FI和綠色區(qū)域的DI,由此可計(jì)算相應(yīng)的波特率。
在具體的調(diào)用中,參數(shù)的傳遞是通過(guò)兩個(gè)DWORD實(shí)現(xiàn)的,代碼如下:
DWORD dwMode, dwFI_DI_Ratio;
DWORDpBuf[2];
dwMode = AT91C_US_USMODE_ISO7816_0;
dwFI_DI_Ratio = 372;
pBuf[0] = dwMode;
pBuf[1] = dwFI_DI_Ratio;
if (!DeviceIoControl ( m_hSer, // 串口handle
IOCTL_SERIAL_ENABLE_ISO7816, // 命令碼
pBuf, sizeof(pBuf), // input buffer
NULL, 0, // output buffer
NULL, NULL ))
{
printf('IOCTL_SERIAL_ENABLE_ISO7816 failed!\r\n');
}
關(guān)閉ISO7816通訊模式比較簡(jiǎn)單,沒(méi)有任何參數(shù):
if (!DeviceIoControl ( m_hSer, // 串口handle
IOCTL_SERIAL_DISABLE_ISO7816, // 命令碼
NULL, 0,
NULL, 0,
NULL, NULL ))
{
printf('IOCTL_SERIAL_DISABLE_ISO7816 failed!\r\n');
}
-
嵌入式主板
+關(guān)注
關(guān)注
7文章
6085瀏覽量
35295
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論