湖南人文科技学院毕业论文(设计)
Register--write(RegCloekQControl,oxo);//设置时钟控制初始值 Register--Write(RegcloekQControl,0x40);
Register--write(RegTxContral,Oxss);//设置发送控制初始值 Register--write(RegRxControll,0x73):
Register--.write(RegDeeode‘ontrol,oxos)://设置译码控制初始值 Register--write(RegBitphase,OxAD)://初始化位相 Register--write(RegRxThreshold,OxFF);//初始化最小阀值
Register--write(RegRxcontrol2,Ox0l);//根据运行环境的处理速率可调整该值 Register--write(RegFIFoLevel,oxos)://初始化FIFo缓存 Register--Write(RegTime‘lock,oxo7):/l定时器初始值装载 Register--write(RegTimerReload,oxoa); , restart--WratchweDog;//复位看门狗
5.2 读卡过程及程序设计介绍
读卡器软件编程实现对射频卡的一系列操作,主要有:防冲突程序、卡片的读写程序以及对卡片block(数据块)的操作等。读卡程序的设计思想是在上电初始化后,射频场一旦检测有Mifare 1卡进入射频天线的有效范围,读卡程序按顺序启动防冲突程序和认证程序,验证成功后最后操作卡片读写程序。程序流程图见图5-2所示,下面介绍其中的几个主要过程。 5.2.1 询卡
由于Mifare l卡是一种以被动方式工作的卡,进入射频区的Mifare l卡上电后进入IDLE状态,它通过吸收感应区内的磁场能量进行工作,不会主动发出信号。读卡器必须不间断地向外发出请求信号,符合条件的卡只有在接收到请求信号之后才会进行响应(称为响应卡),响应卡会向读卡器返回卡的类型号(2个字节),Mifare l卡返回的类型号为ox0004。
程序中用Mf500ComReq()函数不断向外循环发请求信号,检查感应区是否有符合条件的卡,一旦有符合条件的卡进入并被选中,程序退出循环请求过程,进入防冲突过程。
Request指令分为Request std和Request all两个指令。Request all指令的功能是在
26
湖南人文科技学院毕业论文(设计)
天线范围内检查所有符合条件的卡,无论是处于IDLE状态还是HALT状态的卡,都会响应。Request std指令只对天线范围内处于IDLE状态的卡有效,对HALT状态的卡无效。
考虑到至少有两张卡同时进入感应区的可能,设计中采用Request all指令,Mf500ComReq()函数主要代码及相关注释见附录1。
寻卡N有卡Y防冲突选择卡片验证N是写卡读卡Y写卡启动串口图5-2 读卡过程流程图
5.2.2 防冲突
所谓防冲突又叫防碰撞、防重叠,就是从多张进入感应区的卡中选出一张来进行操
27
湖南人文科技学院毕业论文(设计)
作。如果只有一张进入感应区,并且已经知道了卡的序列号(SN),则可跳过此步,直接进入选卡命令,若不知道卡的序列号,则必须调用防冲突函数Mf5oocascAnticoll(),以得到感应区内卡的序列号。若同时有多张卡在感应区内,防冲突函数能够选择其中的一张卡并得到其序列号。
防冲突指令只是获得一张Mifi甘el卡的序列号,并没有真正选中这张卡。选中卡应由Select(见下一步)指令完成。SN为40位长5个字节,实际有意义的只有前4个字节,最后一个字节是SN的异或校验的校验码,在获得SN之后,一般应在程序中对所接收到的SN进行校验,以确保数据的正确性。
Mf5OOCascAnticoll()函数主要代码及相关注释见附录2。 入口参数:
Select_code:表示模式选择,标准应为0x93;
Bcnt:表示读入多少个位,一般应为32位,即四个有效字节; *sn:表示输入或输出四个字节。 5.2.3 选择卡片
选择卡片就是根据已知的序列号读出卡的容量编码(一字节)。只有经过这一步骤后才算真正选中了一张卡,以后的操作都对这张卡进行。选择卡片指令是很重要的,而且必须首先被使用,因为卡片只有先被选中了,然后才能进行读、写等操作。选择卡片过程是通过Mf500cascse1eet()函数实现的,其主要程序代码及相关注释见附录3。
入口参数:
Select_code:模式选择(一般为ox93);
*snr:表示由微处理器控制RC500向PICC发出四个字节的序号,然后等待 卡片的回应。四个字节是在Anticon操作中接收到的四个字节: *sak:应答信号,共8位,其中bit6和bit3可用。 5.2.4 验证
在对所选Mifare l卡进行读、写之前,必需对Mifare1卡进行验证,也即检 查卡的合法性,这可以通过将存储在MFRC500RAM中的密码集(KEYSET)中的 一组密码与Mifare1卡片上的密码进行比较实现,如果它们匹配,说明所选 Mifare1卡合法,则卡的验证成功,允许对卡进行读、写操作。验证卡片的过程
28
湖南人文科技学院毕业论文(设计)
是通过Mf500LoadKey()函数实现的,其主要程序代码及相关注释如下: unsignedeharMf500LoadKey(unsigned char key[]) regwrite(RegInterruptEn,ox7F)://禁止所有中断 regwrite(RegInterruptRq,ox7F)://复位request中断
regwrite(RegCommand,PCD_IDLE);//中止可能正在运行的其它 regwrite(Regeontrol,regread[[regcontrol]|ox0l);//清空FIFO for (status=0;status<12;status++)
regwrite(RegFIFOData.key[status])://写入key到FIFO regwrite(RegInterruptEn,0x84)://使能IdleIRq中断
regwrite(RegCommand,PCD_LOADKEY)://写入loadkey命令 d0 {
Status=(regread(RegErrorFlag)&ox40); }
while((!(regread (RegPrimary status)&ox08)))://等待命令执行完毕 if(status)
status=MI_WRONGLOAD_MODE;//判断错误类型 e1se
status=MI_O K;
regwrite(RegCommand,PCD_IDLE)://程序终止 return status; }
5.2.5 读取卡片
如果完成了前面几个步骤,说明己经通过了安全检查,所选卡是本系统的卡,就可以对Mifare1卡正常进行读、写了。读卡函数Mf500Read()从已通过密码验证的扇区中读取一个数据块,共16个字节,其中前面几个字节即为卡号(l个字节表示2位卡号,本系统卡号长度为10,所以需要前面5个字节)。Mf500Read()函数主要代码及相关注释见附录4。
入口参数:
block_add:块地址(0-63): value:输出数据指针。 5.2.6 卡挂起
当对卡中的数据处理完后,程序应使卡处于挂起状态,此时即使卡在感应 区域,读卡器也不会再对该卡进行任何。Mf500Halt()函数用来实现卡挂起功能,其主要代码及相关注释如下:
unsigned char Mf500Halt() {
29
湖南人文科技学院毕业论文(设计)
unsigned char status=MI_CODEERR:
regwrite(RegInterruptEn,ox7F;//禁止所有中断 regwrite(RegInterruptRq,ox7F);//复位request中断
regwrite(RegCommand,PCD_IDLE);//中止可能正在运行的其它程序 regwrite(RegControl,regead(RegControl)}ox0l);//清空FIFO regwrite(RegFIFOData,PICC_HALT);//写入命令代码 regwrite(RegFIFOData,ox00);
regwrite(RegInterruptEn,ox84);//使能TimerIRq和ldleIRq regwrite(RegCommand,PCD_TRANSCEIVE)://命令开始执行 mrc500_cnt=0x00;
while((!(regread(RegPrimaryStatus)&0x08))&&(mre500_cnt<100)) mre50_cnt+=l;//超时或命令结束判断 if(mre500_cnt>=100)//超时时的处理 {
regwrite(RegCommand,PCD_IDLE)://中止程序 status=MI_ACCESSTIMEOUT; }
if(status=MI_ACCESSTIMEOUT) status=MI_OK;
regwrite(RegCommand,PCD_IDLE): return Status; }
30