基于MCS-51的Mifare智能IC卡读卡器软件设计
文章出处:http://www.nexussmartsolutions.com 作者:林芊 ,朱延钊 人气: 发表时间:2011年10月07日
0 引言
非接触式Ic卡根据电磁感应原理,读写操作只需将卡片放在读写器附近一定的距离之内就能实现数据交换,无需任何接触,使用非常方便、快捷,不易损坏。因此,在电子钱包、公路收费、公共汽车自动售票、门禁系统等方面有着广泛的应用前景。目前,Philips公司的Mifare卡是该领域的主流产品,其较为成熟的型号为Mifarel IC$70(简称MF1 IC$70),遵从ISO/IEC14443A标准,支持一卡多用,具有极高的可靠性和保密性。
为配合Mifare卡工作,必须有相应的读卡芯片,其中MF RC500就是典型的代表作。目前,由读卡芯片制成的读卡模块以及外围硬件电路已经相当成熟,而对软件的开发却相对滞后。本文正是以此为出发点,在典型的硬件电路上进行读卡器的软件设计,力求提高软件的通用性和保证数据的稳定性。
1 MF1 ICS70卡的主要性能特点
a)工作频率13.56 MHz,传输速率106 kbit/s,读写距离最大1 00mm(取决于天线),工作温度范围一20℃ 一+50℃ ,具有防冲突机制,支持多卡操作。b)4 kB的EEPROM分为40个扇区:前2 kB分32个扇区,每个扇区分4块;后2 kB分8个扇区,每个扇区分16块(如表1所示)。IC卡以块(Block)为存储单位,每块16 B,共256个块,从扇区0的第0块到扇区39的第15块依次编号为块0~255。
c)所有扇区各自独立,每个扇区最后一块为该扇区的控制块,含有存取控制字节和两组6B的密码(Key A和Key B);其他块为数据块。扇区0的块0用于存储该Ic卡的序列号(32位)和厂商信息,这部分内容在Ic卡出厂时已被固化,因此这块是写保护的。
表1 MF1 IC$70的存储结构
2 SPI接口通信
2.1 硬件描述
本电路采用性价比很高的ZLGS00A串行读卡模块来配合MF1 IC$70工作,其中集成了MF RC500读卡芯片。采用三线SPI接口,半双工通信方式,能够与MCU直接连接。软件设计的核心是针对SCLK、SDA—TA和ss这3个引脚。引脚说明及接口规范如表2所示。
表2 ZLG5OOA读卡模块SPI接口引脚说明
接口空闲时主机SS=1,SCLK=0,SDATA=0,从机SS=1,SCLK=1,SDATA:0。其中,SCLK为单向时钟线,时钟信号必须由MCU产生,由读卡模块接收,ss为双向数据发送使能端,SDATA为双向数据传输线,都由数据发送端控制,数据接收端必须释放该线。
2.2 SPI信号波形
SPI信号必须严格遵守时序规范,否则将出现通信错误。无论数据传输的方向如何,SPI线上信号的波形总是如图1所示。
由图中可以看出,在ss为低电平时,时钟和数据线上的信号才有效,且在SCLK为低时SDATA变化,SCLK为高时SDATA应保持稳定。
MCU必须根据数据传输的方向严格控制以下几个时间,以确保数据传输无误。
a)t1:数据接收器响应至MCU产生第1个SCLK上升沿的时间;
b)t2:两个字节传输之间,SCLK低电平的持续时间;
c)t3:传输最后一个字节最后一位的SCLK信号的升沿至ss上升沿的时间;
d)tH:SCLK信号的高电平持续时间;
e)tL:SCLK信号的低电平持续时间。
2.3 SPI底层程序设计
2.3.1 写数据
MCU一读卡模块。除响应信号外,3根线上的信号全由MCU产生。如表3所示。
表3 MCU向读卡模块写数据动作流程
2.3.2 读数据
读卡模块-MCU。响应信号和SCLK信号由MCU产生,ss信号和SDATA信号由读卡模块产生。如表4所示。
表4 MCU从读卡模块读数据动作流程
3 存储模式
由于实际应用中读卡环境的随意性,对卡的操作可能会造成数据丢失,例如在数据写入的过程中Ic卡离开感应区等。因此,必须采取必要的措施来防止数据的丢失以及对丢失的数据进行恢复。为确保数据的稳定性,笔者对存储模式和存取操作两方面进行设计,在此先论述存储模式的设计,而对于存取操作的设计将在第4节阐述。
3.1 存储模式设计
为防止数据的丢失以及为已丢失的数据提供恢复的蓝本,在数据的存储模式上采用两层冗余存储模式。第1层是块内冗余存储。写入数据时按表5列出的格式,对块值和块地址进行冗余备份。数据(0—3号字节的Value或12号字节的Adr)读出后,将其与备份值相对比,无误后方可确认为真值;若有误,则视为该块数据出现“部分丢失”现象,须进行恢复。
表5 块内冗余存储模式
第2层是块间冗余存储。如表1所示,将4 kB的存储空间分配给72个逻辑地址(LgeAdr),编号0—71,每个逻辑地址指向同一扇区内的3个数据块(起始地址是扇区内的块0)。为防止对控制块的误操作,每个扇区的控制块不映射到逻辑地址中。如表6所示,逻辑地址中的第1个块是数据区,用于正常存储数据;第2个块是备份区,用于备份数据区的内容,当数据区的内容发生“完全丢失”现象时,可以此作为恢复的蓝本(具体操作在4.2节讨论);第3块为预留区,可在实际应用中记录其他信息。
表6 逻辑地址的单元映射
3.2 地址变换函数
对Ic卡存储空间的实际物理操作,仅仅通过逻辑地址是不可行的,所以必须进行地址变换,将逻辑地址变为相应的扇区号(sector)和块号(block,指向低位块)。具体函数如下:
uehar AdrTrans(uehar—LgeAdr,uehar 一sector,uehar 一block)
{if(-LgcAdr>’=72)return DATA_E111; //超出逻辑块地址范围,返回错误
else if(_LgcAdr<32) 一sector=一LgcAdr; //0—31号扇区
else -sector=(-LgeAdr一32)/5+32; //32—39扇区
block = _ LgcAdr 3 + 一sector; //转换物理块号
return DATA-OK;}
4 存取操作
对MF1 ICS70有读、写、加值、减值、存储、传输共6种基本操作,它们在读卡模块自带的函数库中都有相应的实现函数。但是,这些函数并未考虑到数据稳定性的问题,所以仅仅调用它们是不够的,必须在存储的过程中加入保证数据稳定性的算法。读和写是上述6种基本操作中最基本的两种操作,其他操作均可间接地通过它们来实现。下面在存储模式的基础上对存储操作进行设计。
4.1 写操作
数据的丢失往往发生在写操作的过程中,写入的不成功会导致数据丢失。根据存储模式的设计,每一个逻辑地址可存放一个4字节的数据和1字节的地址,所以定义该数据为长整型(1ong),在读、写操作时须用单字节指针来对其进行转存。具体操作是:先将long型操作数转存人buf[0...3]位,将逻辑地址Lg-cAdr存人buf[12]位;再依据块内冗余存储模式对数据进行备份;最后将数据进行两次发送,先发送到块间冗余存储模式的备份区,再发送到数据区,只要有一次发送成功则视为整个发送过程成功。程序如下:
uehar DamWrite(1ong 一Value,uehar—LgeAdr,uchar—block,
uchar idam _ bur)
{uehar temp=(uehar )_Value; //转存指针
uehar writecheck:DATA— ERR; //写入状态标记,用于返回值
— buf[0]= (temp+3);-buf[1]= (temp+2);-buf[2]
= (temp+1);-buf[3]: temp; //数据转存到缓冲区
_ buf[4]: 一buf[0];bull5]: 一—buf[1];—buf[6]= 一一
buf[2];_buf[7]=一_buf[3]; //值备份
_ buf[8]=一bur[0];一buf[9]=一buf[1];一buf[10]= 一buf
[2];_buf[11]=-buf[3];
_ buf[12]=一LgeAdr;_bull13]: 一一LgcAdr;_bull14]=一Lg·
cAdr;buf[15]=一一LgcAdr; //转存地址,并备份
writecheck= writeeheck& mils_
write(一block+1,一bur); //
将数据写入备份块
writecheck= writecheck& mils— write(一block,一bur); //将
数据写入数据块
retum writecheck; //返回最终发送状态}
4.2 读操作
读操作是不会引起数据丢失的,但在读出数据后有必要对所读出的内容进行校验,确认其完整性后方可认定为真值,否则须予以修正。依据两层冗余存储模式,修正亦分为两种:部分丢失恢复和完全丢失恢复。部分丢失恢复利用块内冗余备份,真值的依据是:相同的数据为真值,即应有2份Value相同以及3份Adr相同,对出错的那一份数据进行修正。由于写操作中进行了两次发送,卡内数据是安全的,当数据区内容“完全丢失”时,从备份区读出数据来恢复数据区的内容。
具体的读操作是:先从卡中读出数据区内容,进行块内数据正确性检查及纠错;然后判断数据是否“完全丢失”,若否,则可确认为真值,若是,则从备份区读出数据;最后根据存储模式的格式对读出内容进行转换。程序如下:
uchar DataRead(1ong -Value,uchar$~LgcAdr,uchar—block,
uchar idata $一buf)
{uchar$temp=(uchar$)-Value;//转存指引‘
if(mifs_read(一block,一buf)!=0)return DATA~ERR; //读卡
DataCheck(一buf); //数据正确性检查及纠错
//若数据为全0,视为数据丢失;此时从备份块中滨取数据
if(-buf[0]==0&&-buf[1]==0&&-buf[2]==0&&-
buf[3]==0) mifs—read(_block+1,buf);
(temp+3)=_bufEo];$(temp+2)=—buf[1];$(temp+1 1)
= -bull2];$temp=一buf[3];//值转换
LgcAdr=~ buf[12];//读出逻辑地址
return DATA— OK;}
5 主程序流程
6 结束语
本文在Mifare智能Ic卡应用的典型电路上进行软件设计,程序的读写效率和数据稳定性都达到很高的要求。算法及程序的通用性好,可移植到不同的电路系统中,根据实际应用稍加修改即可满足要求。本文主要从通用的角度进行设计,在实际具体应用中应根据需要添加必要的辅助程序,如存储器扩展、LCD显示、语音提示等。非接触式Ic卡读卡系统具备迅速、方便、安全、可靠、稳定等优点,目前正逐步取代传统磁卡和接触式IC卡,具有巨大的市场竞争力和广阔的发展前景。
(作者单位:华南理工大学物理科学与技术学院,华南理工大学计算中心)