首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

工控主板EM9161对ISO7816协议的支持

工控主板EM9161对ISO7816协议的支持

在当前的金融POS终端及相关领域,ISO7816通讯协议得到了广泛应用。英创的工控主板EM9161,可在其异步串口的基础上,通过简单的设置,就可把串口转为符合ISO7816协议的接口,实现与各种智能卡的通讯。本文主要介绍采用EM9161的COM2口,实现ISO7816通讯的基本方法。


      上图表示EM9161作为ISO7816主控方与智能卡的连接示意图,其中原COM2口的数据发送管脚TXD2作为ISO7816的半双工数据信号DIO;原COM2口的RTS2n控制线作为ISO7816的时钟信号SCK。两个信号线的电平均为3.3V的TTL信号电平。
      应用程序进行ISO7816通讯的基本流程为:
      1.按标准方法打开串口“COM2:”,并设置相应串口参数;
      2.通过DeviceIoControl(…)函数使能ISO7816通讯模式,并设置相关参数;
      3.设置波特率,注意在使能ISO7816模式后,必须重新设置波特率;      
      4.进行数据通讯,数据帧的奇偶校验位需要与通讯对端匹配;
      5.通过DeviceIoControl(…)函数禁止ISO7816通讯模式;
      6.按标准方法关闭串口“COM2:”。
      为了实现从通常的异步串口到ISO7816的转换,EM9161的串口驱动增加了2个IOCTL功能如下:
#include <winioctl.h>
#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调用,需要同时设置相应的参数。这些参数包括ISO7816的协议类型,帧数据的应答规范等,定义相应的参数如下:
#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的波特率按如下公式计算:
            BR = (DI / FI)× SCK
      上式中的SCK = 串口波特率×FI / DI,例如串口波特率为9600,FI / DI = 372,则SCK时钟频率为3.57MHz。在EM9161中,对DI和FI的设置,是通过设置(FI/DI)这个比值来实现的,其中有效的值如下表所示:

FI
DI=1
DI=2
DI=4
DI=8
DI=16
DI=32
DI=12
DI=20
372
372
186
93
47
23
12
31
19
558
558
279
140
70
35
17
47
28
774
774
372
186
93
47
23
62
37
1116
1116
558
279
140
70
35
93
56
1488
1488
744
372
186
93
47
124
74
1806
1806
930
465
233
116
58
155
93
512
512
256
128
64
32
16
43
26
768
768
384
192
96
48
24
64
38
1024
1024
512
256
128
64
32
85
51
1536
1536
768
384
192
96
48
128
77
2048
2048
1024
512
256
128
64
171
102

      选择蓝色区域的值,可得到对应的黄色区域的FI和绿色区域的DI,由此可计算相应的波特率。
      在具体的调用中,参数的传递是通过两个DWORD实现的,代码如下:
DWORD dwMode, dwFI_DI_Ratio;
DWORD pBuf[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');
}
      关闭ISO7816通讯模式比较简单,没有任何参数:
if (!DeviceIoControl ( m_hSer,                                             // 串口handle
                                 IOCTL_SERIAL_DISABLE_ISO7816,    // 命令码
                                 NULL, 0,         
                                 NULL, 0,      
                                 NULL, NULL ))
{
      printf('IOCTL_SERIAL_DISABLE_ISO7816 failed!\r\n');
}
      设置了ISO模式后,应用程序仍然可以像操作普通串口那样,进行数据的读写,只是需要注意的是ISO7816的半双工模式的,所以数据通讯的过程更像是RS485的过程。用户可参考英创网站的《RS485接口通讯的WinCE编程要点》一文,来规划自己的应用程序。
[查看全文]
[关于英创]
[更多文章]
[技术论坛]
本文PDF格式下载
返回列表