(1)寻卡
M1射频卡的通讯协议和通讯波特率是定义好的,当有卡片进入读写器的操作范围时,读写器以特定的协议与它通讯,从而确定该卡是否为M1射频卡,即验证卡片的卡型。调用的函数及参数解释如下所示:
参数说明: req_code[IN]:寻卡方式
0x52 = 寻感应区内所有符合14443A标准的卡
0x26 = 寻未进入休眠状态的卡
pTagType[OUT]:卡片类型代码
0x4400 = Mifare_UltraLight
0x0400 = Mifare_One(S50)
0x0200 = Mifare_One(S70)
0x0800 = Mifare_Pro(X)
0x4403 = Mifare_DESFire
返回: 成功返回MI_OK
char PcdRequest(u8 req_code,u8 *pTagType)
向 FIFO 中写入 PICC_REQIDL 命令,通过 PCD_TRANSCEIVE 命令将 FIFO 中数据通过天线发送出去,此时若有卡在天线作用范围内,将识别命令,并返回卡类型;由于本次采用的是M1卡,所以返回的值是0x0400,具体程序请参考附录。
(2)防冲突机制
当有多张卡进入读写器操作范围时,防冲突机制会从其中选择一张进行操作,未选中的则处于空闲模式等待下一次选卡,该过程会返回被选卡的序列号。调用的函数及参数解释如下所示:
参数说明: pSnr[OUT]:卡片序列号,4字节
返回: 成功返回MI_OK
char PcdAnticoll(u8 *pSnr)
向 FIFO 中写入 PICC_ANTICOLL + 0x20 ,通过 PCD_TRANSCEIVE 命令将 FIFO 中数据通过天线发送出去,卡返回卡序列号由于是非接触式的,同一时间天线作用范围内可能不只一张卡时,即有多于一张的MIFARE 1 卡发回了卡序列号应答,则发生了冲突。此时,由于每张卡的卡序列号各不相同, MCM 接收到的信息 ( 即卡序列号 ) 至少有 1 位既是 0 又是 1( 即该位的前、后半部都有副载波调制 ) , MCM 找到第 1 个冲突位将其置 1( 排除该位为 0 的卡 ) ,然后查第 2 个,依次排除,最后不再有冲突的 SN 即为被选中的卡,具体程序请参考附录。
(3)选择卡片
选择被选中的卡的序列号,并同时返回卡的容量代码。调用的函数及参数解释如下所示:
参数说明: pSnr[IN]:卡片序列号,4字节
返回: 成功返回MI_OK
char PcdSelect(u8 *pSnr)
向 FIFO 中写入 PICC_SElECTTAG+0x70+卡序列号,通过 PCD_TRANSCEIVE 命令将 FIFO中数据通过天线发送出去,卡返回卡容量(对于 MIFARE 1 卡来说,可能为 88H 或08H ),具体程序请参考附录。
(4)三次互相确认(验证卡片密码)
选定要处理的卡片之后,读写器就确定要访问的扇区号,并对该扇区密码进行密码校验,在三次相互认证之后就可以通过加密流进行通讯。(在选择另一扇区时,则必须进行另一扇区密码校验),具体程序请参考附录。调用的函数及参数解释如下所示:
功能:验证卡片密码
参数说明: auth_mode[IN]: 密码验证模式
0x60 = 验证A密钥
0x61 = 验证B密钥
addr[IN]:块地址
pKey[IN]:密码
pSnr[IN]:卡片序列号,4字节
返回: 成功返回MI_OK
char PcdAuthState(u8 auth_mode,
u8 addr,u8 *pKey,u8 *pSnr)
(5)对数据块的操作
由于本程序只涉及到对M1卡的读数据应用,所以只介绍有关读数据函数的操作。调用的函数及参数解释如下所示:
功能:读取M1卡一块数据
参数说明: addr[IN]:块地址
p [OUT]:读出的数据,16字节
返回: 成功返回MI_OK
char PcdRead(u8 addr,u8 *p )
向 FIFO 中写入 PICC_READ+块地址,通过 PCD_TRANSCEIVE 命令将 FIFO 中数据通过天线发送出去,具体程序参考附录。
`