《基于arm的ic卡读写模块设计》由会员分享,可在线阅读,更多相关《基于arm的ic卡读写模块设计(18页珍藏版)》请在金锄头文库上搜索。
1、基于 ARM 的 IC 卡读写模块设计(本实验取材于我正做的项目“电动汽车智能交流充电桩”中我负责的部分)实验名称 基于 ARM 的 IC 卡读写模块设计 课程 嵌入式系统姓名 叶冠南 班级 控制工程 1202 学号 2111203199实验目的使用 ARM 内核的 MCU实验原理使用基于 ARM 内核的 MCU 芯片以及 RFID 卡完成非接触性 IC 卡读写模块的设计。使用时序模拟的 SPI 通信。实验环境和器件编程语言环境:keil MDK Vision V4.21.0.0MCU 芯片 :基于 ARM 内核的 STM32F103VET6 芯片(Heart103V 开发板)RFID 卡 :
2、RFID-MFRC522 模块调试工具 :JTAG 仿真器 实验内容1. RFIDMFRC522 模块1.1 结构非接触式IC卡的薄膜结构卡内部结构1.2 功能功能框图读卡器通过天线发射激励信号(一组固定频率的电磁波),IC卡进入读写器工作区内,被读写器信号激励。在电磁波的激励下,卡内的LC串联谐振电路产生共振,从而使电容内有了电荷,在这个电容的另一端,接有一个单向导通的电子泵,将电容内的电荷送到另一个电容内储存,当所积累的电荷达到2 V时,此电容可以作为电源为其他电路提供工作电压,供卡内集成电路工作所需。(1)ATR模块: Answer To Request(“请求之应答 ”)当一张MIFA
3、RE 1卡处在读写器的天线工作范围之内时,程序员控制读写器向卡发出Request all(或Request std)命令后,卡的ATR将启动,将卡片块 0 中2个字节的卡类型号 (TagType)传送给读写器,建立卡与读写器的第一步通信联络。如果不进行第一步的ATR工作,读写器对卡的其他操作(读/ 写操作等)将不会进行。 (2)AntiCollision模块:防(卡片)冲突功能如果有多张MIFARE 1卡处在读写器的天线工作范围之内,则AntiCollision模块的防冲突功能将被启动工作。读写器将会首先与每一张卡进行通信,读取每一张卡的序列号(Serial Number)。由于每一张 MIF
4、ARE 1卡都具有惟一的序列号,决不会相同,因此程序员将启动读写器中的AntiCollision防重叠功能配合卡上的防重叠功能模块,根据卡序列号来选定其中一张卡。被选中的卡将被激活,可以与读写器进行数据交换;而未被选中的卡处于等待状态,随时准备与读写器进行通信。AntiCollision模块(防重叠功能)启动工作时,读写器将得到卡片的序列号(Serial Number)。序列号存储在卡的Block 0中,共有5个字节,实际有用的为4个字节,另一个字节为序列号的校验字节 。(3)Select Application 模块:卡片的选择当卡与读写器完成了上述两个步骤,读写器要想对卡进行读/写操作时,
5、必须对卡进行“ Select”操作,以使卡真正地被选中。被选中的卡将卡片上存储在Block 0中的卡容量“Size ” 字节传送给读写器。当读写器收到这一字节后,方可对卡进行进一步的操作,如密码验证等。 (4)Authentication & Access Control 模块:认证及存取控制模块完成上述的三个步骤后,读写器对卡进行读/写操作之前,必须对卡上已经设置的密码进行认证,如果匹配,则允许进一步的读/ 写操作。MIFARE 1 卡上有16个扇区,每个扇区都可分别设置各自的密码,互不干涉,必须分别加以认证,才能对该扇区进行下一步的操作。因此每个扇区可独立地应用于一个应用场合,整个卡可以设
6、计成一卡多用(一卡通)的形式来应用。密码的认证采用了三次相互认证的方法,具有很高的安全性。如果事先不知卡上的密码,则因密码的变化可以极其复杂,试图靠猜测密码而打开卡上一个扇区的可能性几乎为零。(5)Control & Arithmetic Unit:控制及算术运算单元这一单元是整个卡的控制中心,是卡的“头脑” 。它主要对卡的各个单元进行操作控制,协调卡的各个步骤;同时它还对各种收/ 发的数据进行算术运算处理、递增/递减处理和CRC运算处理等,是卡中内建的中央微处理器(MCU)单元。(6)RAM/ROM 单元RAM主要配合控制及算术运算单元,将运算的结果进行暂时存储,例如将需存储的数据由控制及算
7、术运算单元取出送到EEPROM存储器中;将需要传送给读写器的数据由控制及算术运算单元取出,经过RF射频接口电路的处理,通过卡片上的天线传送给读写器。RAM中的数据在卡失掉电源后 (卡片离开读写器天线的有效工作范围)将会丢失。同时,ROM 中则固化了卡运行所需要的必要的程序指令,由控制及算术运算单元取出,对每个单元进行指令控制,使卡能有条不紊地与读写器进行数据通信。 (7)Crypto Unit:数据加密单元该单元完成对数据的加密处理及密码保护。加密的算法可以为DES标准算法或其他。(8)EEPROM存储器及其接口电路:EEPROM INTERFACE/EEPROM MEMORY 该单元主要用于
8、存储用户数据,在卡失掉电源后(卡片离开读写器天线的有效工作范围)数据仍将被保持。1.3 数据读写方式由于项目内板上SPI 接口已被其他外设占用,故本实验中的RFID卡与板上数据之间读写通过普通IO口时序模拟得到。1.4 引脚分配如上图所示,RFID卡模块共有8个引脚,其中5脚空置。另外的1、2、3、4、7 口作为通信线分别在板上为其分配普通IO口PD8、 PD9、 PD10、PD11和PD12。6脚和8脚则分别和板上的地线以及3.3V电源口。1.5 Mifare 1 S50卡存储EEPROM Mifare 1卡内部有1 的 EEPROM,分成015共16个扇区,每个扇区分成03共4块,每块 1
9、6字节。1、扇区0的块0是厂商标志字节,保存着只读的卡信息及厂商信息,比如:AF A7 3E 00 36 08 04 00 99 44 30 43 31 34 36 16。前面四个字节AF A7 3E 00 36是卡序列号,08是卡容量,04 00是卡类型,后面是厂商自定义的一些信息。2、每个扇区的块 0保存着该块的密钥 A密钥B及该块的访问条件,第个扇区都有自己的一套密钥及访问条件,其中,4个字节的访问条件是对每个扇区4 个块的读写定义,格式如下:字节9备用默认值为 0x69,_b是取反。分成C10C13,C20C23,C30C33对块0、块1、块2存取控制X(02):对块3存取控制:比如块
10、3的16字节如下:00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF前面6个字节是密钥 A,因为 Read永远为Never ,所以读到的都是0x00, 最后的6字节是密钥 B,其值一为 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF,中间的4个字节是访问条件,有:C1X0.2 C2X0.2 C3X0.20 0 0C1X3 C2X3 C3X30 0 1对应上表,可得出对该扇区块的存取控制条件。2. 读写的实现利用RFID 卡厂家编制好的头文件添加到工程中。对于IC卡的读写需要经历:判断是否有卡进入;多卡进入时的防冲撞处理;对卡操作前的密钥验
11、证操作,以及后续的不同类型的操作(注册,读卡,消费,充值,注销等) 。取块2来进行数据存储。扇区 块 描述63 第15 扇区尾块62 数据块61 数据块1560 数据块59 第14 扇区尾块58 数据块57 数据块1456 数据块.7 第1扇区尾块6 数据块5 数据块14 数据块3 第0扇区尾块2 数据块1 数据块00 厂商标志块RC522卡存储区的组织示意图在本程序中初步设计卡内存储的用户信息为用户姓名四个汉字以内,以区位码形式存储,以便下一步与触摸屏模块连接时通过字库的支持来实现显示。用户账户余额信息设计为以4个字节存储。而每张IC卡赋予其一个编号,使用4个字节8位数字及字母组合表示。至此
12、需要的存储空间为姓名部分(一个汉字的区位码为两个字节)共需八个字节,余额部分4 个字节,编号部分4 个字节,总共16个字节,对于一个数据块而言恰好完全利用。由于扇区0中储存着大量的厂商信息,故选用扇区1 的块4进行用户信息数据的存储。对卡不同类型的操作是通过对卡的状态变量OprationCard进行赋值完成。附 自定义状态字表:11 密钥A 权限代码 密钥 B6 4 610交易额1交易额2交易额3序列号1序列号2序列号32 2 2 2 2 29 交易时间1 交易时间2 交易时间3 状态交易次数4 4 4 2 28 用户余额 用户姓名(区位码储存) 用户卡号扇区14 8 40x11 有卡进入0x
13、22 防冲撞处理完成0x33 选卡选毕0x44 密钥验证通过#define REGCARD 0xa1 /注册状态#define CONSUME 0xa2 /消费状态 #define READCARD 0xa3 /读卡状态#define ADDMONEY 0xa4 /充值状态#define LOGOFFCARD 0xa5 /注销状态void On_NormalCall()/ if(MainStage = 1)/ / ShowStartPage();/ MainStage = 2;/ /MainStage = 1;signed char Status,i;signed long money_val
14、ue;/,money_value2;float f_money_value;/,f_money_value2;Status = PcdRequest(PICC_REQIDL,/寻天线区内未进入休眠状态的卡,返回卡片类型 2字节if(Status!=MI_OK) return;Status = PcdAnticoll(/防冲撞,返回卡的序列号 4字节if(Status!=MI_OK) return;GPIO_ResetBits(GPIO_BEEPER, BEEPER_PIN); /*开启蜂鸣器*/Delay(0x2FFFFF);GPIO_SetBits(GPIO_BEEPER, BEEPER_P
15、IN); /*关闭蜂鸣器*/ / Delay(0x2FFFFF);memcpy(MLastSelectedSnr, /拷贝&RevBuffer2起始地址的4 字节至 MLastSelectedSnr起始地址的区域Status = PcdSelect(MLastSelectedSnr);/选卡if(Status!=MI_OK) return;if(OprationCard=REGCARD)/注册0Status=PcdAuthState(PICC_AUTHENT1A,11,NewKeyA,MLastSelectedSnr);/地址11 是如何确定的?( 第2扇区尾块序号)if(Status!=MI_OK)Error(Error_RC522);return;Status=PcdWrite(11,if(Status!=MI_OK)Error(Error_RC522);return;for(i=0;i16;i+) /?Write_First_Datai=0xaa;memset( Write_First_Data, 0, sizeof(Write_First_Data) );/将Write_First_Data起始地址的sizeof(Write_Firs