基于S6700芯片与ISO/IEC15693标准的读卡器设计
javascript:window.open(this.src);" style="cursor:pointer;"/>
3.2 响应结构
VICC响应的一般格式是:
起始位S2 | FLAGS | 响应内容 | CRC16 | 结束位ES2 |
*起台位S2:表示VICC响应数据的开始,定义为当SCLOCK为高电平时DOUT发生一个上升沿。
javascript:window.open(this.src);" style="cursor:pointer;"/>
*结束位ES2:表示VICC响应数据的结束,定义为当SCLOCK为高电平时DOUT发生一个下降沿。
javascript:window.open(this.src);" style="cursor:pointer;"/>
3.3 通信过程注意的问题
①时间寄存器初始化。初始化序列是:S1 01111011 00000001 11000ES1。
②发送顺序。命令字节(8位)发送的顺序是MSB FIRST,其它数据均是LSB FIRST。
③FIFO管理。发送每一位时都要检测DOUT的电平。DOUT高电平时停止发送,直到DOUT恢复为低电平。
④时钟线切换。命令发送过程中,双向时钟SCLOCK线由MCU控制,发送完毕,在接收VICC响应之前必须进行时钟线的切换,将控制权交由ASIC控制。
MCU放弃时钟线控制波形(TRAN1):
javascript:window.open(this.src);" style="cursor:pointer;"/>
MCU获得时线控制波形(TRAN2):
javascript:window.open(this.src);" style="cursor:pointer;"/>
⑤CRC校验。CRC16校验是对15693-3规定的FLAGS、命令序列号、命令内容等字节的校验,不包括起始位和命令字节(8位)。
⑥适当延时。例如:发送命令字节后适当延时约100μs,以利ASIC正确动作。
3.4 举例
以读一个扇区为例,采用普通模式,VCD和VICC交互的完整过程如下:
(发送)S1(起始位)2D(命令字节)40(FLAGS)
20(读扇区命令序号)01(扇区号)00
(校验LOW BYTE)F2(校验HIGH BYTE)
ES1(结束位)TRAN1(SCLOCK切换)
(接收)S2(起始位)00(FLAGS)00(扇区安全状态)
31(数据1)32(数据2)33(数据3)34(数据4)BD 7F(校验)ES2(结束位)
3.5 关于反冲突算法
ISO/IEC 15693中描述的VICC反冲突算法非常费解,笔者通过实践摸索解决了这个问题,此处作为一简单说明。该算法基本上是一种搜索算法,卡内相对应的是一种比较应答机制。举例说明,假如READER磁场范围内有两张卡,其UID分别是E00700000158D1D2和E0070000015869E8,这样当READER采用NON-ADDRESSED模式指令去读的时候,两张卡均会回答,M_ERR线会跳变为高电平表示数据冲突。INVENTORY命令用来查询当前磁场范围内卡的卡号,专用用于解决冲突问题。其参数包括:FLAGS、COMMAND、MASKLENGTH、MASKVALUE。一种最简单的情况,设定:FLAGS.6=Nb_slots_flag=1,MAKLENGTH=4,MASKVALUE=0,当命令序列发送后,MASKVALUE会被自动与卡的UID的最低位比较,因为0≠2≠8,所以两张卡均不回答。同样的命令,如果MASKVALUE=2,则第一张卡就会回答;当MASKVALUE=8时第二张卡回答。如果两张卡的卡号是:E00700000158D1D2和E0070000015869E2,则当MASKLENGTH=4,MASKVALUE=2时两张卡均回答,就会发生冲突。解决的方法是:令MASKLENGTH=8,MASKVALUE=X2,X从0到F自增。这样,X2=D2时第一张卡回答,X2=E2时,第二张卡回答。依此类推。卡的UID最低位冲突的概率为62‰,最低两位冲突的榔为4‰。理解了此算法,就很容易理解标准中所描述的复杂算法。笔者采用这种逐位搜索算法编的读多卡程序,连续读3张卡的时间不超过500ms。
4 软件设计
笔者利用仿真器和PC机作为调试工具,采用8051汇编语言编程并调试通过了ISO/IEC15693-3所要求的所有命令。软件的主要功能包括:从PCRS232口接收命令数据,进行一次分拣处理后打包成ASIC命令序列,并发送给VICC。然后,接收VICC的响应,进行一定的分拣处理后通过RS232发送给PC机。本文只描述有关与VICC通信的部分。程序见网络补充版。http://www.dpj.com.cn。