ISO14443协议是Contactless card standards(非接触式IC卡标准)协议,由4个部分组成:
ISO14443术语与缩写:
– 接近式卡 Proximity card(PICC)
– 接近式耦合设备 Proximity coupling device(PCD)
– 防冲突环 anticollision loop
– 比特冲突检测协议 bit collision detection protocol
– 冲突 collision
– 帧 frame
– REQA:请求命令,类型A(Request To Command, Type A)
– REQB:请求命令,类型B(Request To Command, Type B)
– ATQA:请求应答,类型A(Answer To Request, Type A)
– ATQB:请求应答,类型B(Answer To Request, Type B)
– NVB:有效位的数目(Number of Valid Bits)
PICC应具有ISO/IEC 7810中为ID-1型卡规定的要求相应的一般物理特性。还应具有相应的紫外线、X-射线、动态弯曲应力、动态扭曲应力、交变磁场、交变电场、静电、静态磁场及工作温度等附加特性
PICC的初始对话 PCD和PICC之间的初始对话通过下列连续操作:
– PCD的RF工作场激活PICC
– PICC静待来自PCD的命令
– PCD传输命令
– PICC传输响应
这些操作使用下列条款中规定的射频功率和信号接口:
– PCD应产生给予能量的RF场,为传送功率,该RF场与PICC进行耦合,为了通信,该RF场应被调制。
– RF工作场频率(fc)应为13.56MHz±7kHz
当PICC暴露于未调制的工作场内,它能在5ms内接受一个请求。为了检测进入其激励场的PICC,PCD发送重复的请求命令并寻找ATQ,这个过程被称为轮询
– 通信开始:7个数据位发送,LSB首先发送(标准REQA的数据内容是0x26,WAKE-UP请求的数据内容是0x52)
– 通信结束:不加奇偶校验位
– 通信开始:n*(8个数据位+奇数奇偶校验位),n≥1。每个数据字节的LSB首先被发送。每个数据字节后面跟随一个奇数奇偶校验位。
– 通信结束
– POWER-OFF状态:在POWER-OFF状态中,由于缺少载波能量,PICC不能被激励并且应不发射副载波
– IDLE状态 :在该状态中,PICC被加电,并且能够解调和识别从PCD来的有效REQA和WAKE-UP命令
– READY状态:一旦收到有效REQA或WAKE-UP报文则立即进入该状态,用其UID选择了PICC时则退出该状态。在这种状态中,比特帧防冲突或其他任选的防冲突方法都可以使用。所有串联级别都在这一状态内处理以取得所有UID CLn
– ACTIVE状态:通过使用其完整UID选择PICC来进入该状态
– HALT状态:在该状态中,PICC应仅响应使PICC转换为READY状态的WAKE-UP命令
注: 处于HALT状态的PICC将不参与任何进一步的通信,除非使用了WAKE-UP命令
– REQA:由PCD发出,以探测用于类型A PICC的工作场(0x26)
– WAKE-UP:由PCD发出,使已经进入HALT状态的PICC回到READY状态(0x52)
– ANTICOLLISION:防碰撞(0x93)
– SELECT:选择
– HALT:结束(0x50)
ISO/IEC14443的这一部分规定了非接触的半双工的块传输协议并定义了激活和停止协议的步骤。这部分传输协议同时适用于A型卡和B型卡
基于14443-A的操作帧格式
– 请求卡 :0x26
– 唤醒所有卡 :0x52
– 防冲突 :0x93,0x20 得到卡ID
– 选择卡片 :0x93,0x70, ID1,ID2,ID3,ID4, checksum, CRC16
MF RC522 是应用于13.56MHz 非接触式通信中高集成度读写卡系列芯片中的一员。是NXP 公司针对“三表”应用推出的一款低 电压、低成本、体积小的非接触式读写卡芯片,是智能仪表和便携 式手持设备研发的较好选择
RC522部分内部寄存器组介绍如下:
– CommandReg 启动和停止命令的执行
– ComIrqReg 包含中断请求标志
– ErrorReg 错误标志,指示执行的上个命令的错误状态
– Status2Reg 包含接收器和发送器的状态标志
– FIFODtataReg 64 字节 FIFO 缓冲区的输入和输出
– FIFOLevelReg 指示 FIFO 中存储的字节数
– ControlReg 不同的控制寄存器
– BitFramingReg 面向位的帧的调节
– CollReg RF 接口上检测到的第一个位冲突的位的位置
– ModeReg 定义发送和接收的常用模式
– TxModeReg 定义发送过程的数据传输速率
– TxControlReg 控制天线驱动器管脚 TX1 和 TX2 的逻辑特性
– TModeRegTPrescalerReg定义内部定时器的设置
主要介绍SPI数字接口以及FIFO缓冲区
– 在 SPI 通信中 MFRC522 模块用作从机。 SPI 时钟 SCK 由主机产生。数据通过 MOSI线从主机传输到从机;数据通过 MISO 线从 MFRC522 发回到主机
– MOSI 和 MISO 传输每个字节时都是高位在前。MOSI 上的数据在时钟的上升沿保持不变,在时钟的下降沿改变。MISO 也与之类似,在时钟的下降沿,MISO 上的数据由 MFRC522来提供,在时钟的上升沿数据保持不变
– SPI地址,地址字节按下面的格式传输。第一个字节的 MSB 位设置使用的模式。 MSB 位为 1 时从 MFRC522 读出数据; MSB 位为 0 时将数据写入 MFRC522。 第一个字节的位 6-1 定义地址,最后一位应当设置为 0
– 通过写FIFODataReg寄存器来将一个字节的数据存入FIFO缓冲区,之后内部FIFO缓冲区写指针加 1
– 除了读写FIFO缓冲区外,FIFO缓冲区指针还可通过置位寄存器FIFOLevelReg的FlushBuffer位来复位。从而,FIFOLevel位被清零,寄存器ErrorReg的BufferOvfl位被清零,实际存储的字节不能再访问
– 已经存放在 FIFO 缓冲区中的字节数:寄存器FIFOLevelReg的FIFOLevel字段
FIFO每个需要数据流(或数据字节流)作为输入的命令在发现FIFO缓冲区有数据时会立刻处理,但收发命令除外。收发命令的发送由寄存器BitFramingReg的StartSend位来启动;每个需要某一数量的参数的命令只有在它通过FIFO缓冲区接收到正确数量的参数时才能开始处理;FIFO缓冲区不能在命令启动时自动清除。而且,也有可能要先将命令参数和/或数据字节写入FIFO缓冲区,再启动命令;每个命令的执行都可能由微控制器向命令寄存器写入一个新的命令代码(如idle命令)来中断
– IDLE 命令:MFRC522 处于空闲模式。该命令也用来终止实际正在执行的命令
– CALCCRC 命令:FIFO 的内容被传输到 CRC 协处理器并执行 CRC 计算这个命令必须通过向命令寄存器写入任何一个命令(如空闲命令)来软件清除
– TRANSMIT 命令:发送 FIFO 的内容。在发送 FIFO 的内容之前必须对所有相关的寄存器进行设置。该命令在 FIFO 变成空后自动终止
– RECEIVE 命令:该命令在接收到的数据流结束时自动终止。
– TRANSCEIVE 命令:该循环命令重复发送 FIFO 的数据,并不断接收 RF 场的数据。第一个动作是发送,发送结束后命令变为接收数据流。
– MFAUTENT 命令:该命令用来处理 Mifare 认证以使能到任何 Mifare 普通卡的安全通信。在命令激活前以下数据必须被写入 FIFO: 认证命令码,块地址,秘钥,序列号。该命令在 Mifare 卡被认证且 Status2Reg 寄存器的 MFCrypto1On 位置位时自动终止。
– SOFTRESET 命令 :所有寄存器都设置成复位值。命令完成后自动终止
M1芯片,是指菲利浦下属子公司恩智浦出品的芯片缩写,全称为NXP Mifare1系列,常用的有S50及S70两种型号,属于非接触式IC卡。非接触式IC卡又称射频卡,成功地解决了无源(卡中无电源)和免接触这一难题,是电子器件领域的一大突破。主要用于公交、轮渡、地铁的自动收费系统。M1卡,优点是可读可写的多功能卡,缺点是:价格稍贵,感应距离短
工作原理:向M1卡发一组固定频率的电磁波,卡片内有一个LC串联谐振电路,其频率与读写器发射的频率相同,在电磁波的激励下,LC谐振电路产生共振,从而使电容内有了电荷,在这个电容的另一端,接有一个单向导通的电子泵,将电容内的电荷送到另一个电容内储存,当所积累的电荷达到2V时,此电容可做为电源为其它电路提供工作电压,将卡内数据发射出去或接取读写器的数据
S50由1KB的EEPROM、RF接口和数字式控制单元组成。能量和数据都通过天线传送,天线由几匝线圈组成并直接连到S50卡上,不需要其他外部元件
1024*8位的EEPROM存储器被分成16个区,每个区中有4个段,每段有16字节。在擦除状态时,读EEPROM单元的值是逻辑“0”;在写状态时,读EEPROM单元的值是逻辑“1”
– 读/写段,用于譬如无线访问控制
– 值段,用于譬如电子钱包 它需要额外的命令 像直接控制保存值的增加和减少
在执行任何存储器操作前都要先执行确认命令
– 值:表示一个带符号 4 字节值 这个值的最低一个字节保存在最低的地址中 取反的字节以标准2 的格式保存 为了保证数据的正确性和保密性 值被保存了 3 次 两次不取反保存 一次取反保存
– Adr:表示一个 1 字节地址 当执行强大的备份管理时用于保存存储段的地址 地址字节保存了 4次 取反和不取反各保存两次 在执行增 减 恢复 传送操作时 地址保持不变 它只能通过写命令改变
– 密钥A和B(可选),读密钥时返回逻辑 0
– 访问这个区中4个段的条件(保存在第6字节 ~ 第9字节) 访问位(access bits)也可以指出数据段的类型(读/写或值)
如果不需要密钥 B,那么段3的最后6字节可以作为数据字节
用户数据可以使用区尾的第9字节,这个字节具有和字节6、7和8一样的访问权
每个数据段和区尾的访问条件由3个位来定义,它们以取反和不取反的形式保存在指定区的区尾。访问位控制了使用密钥A和B访问存储器的权力。当知道相关的密钥和当前的访问条件时,可以修改访问条件
– 每个字节的bit7控制block3,Bit6控制block2,Bit5控制block1
– Bit4控制block0,Bit3 ~ 0其实就是bit7 ~ 4取反的结果
– Block3出厂默认 ff ff ff ff ff ff ff 07 80 69 ff ff ff ff ff ff
下表中用灰色标明的行是密钥B可被读的访问条件,此时密钥B可以存放数据
– 请求 0x26
– 防冲突 0x93,0x70
– A认证 0x60,addr,keyA, ID
– 读0x30,addr CRC16
– 请求 0x26
– 防冲突 0x93,0x70
– A认证 0x60,addr,keyA, ID
– 写0xA0,addr ,CRC16
– 16bytes,CRC16
本实例使用STM32F103开发板与RC522连接,通过串口将读取出的S50卡信息打印出来,通过按键控制将相关信息写入到S50卡
本实例使用到了蜂鸣器(PB5)、按键(PA0/PE2/PE3/PE4)和LED灯(PC0),RC522除了要接入3.3V供电和GND外,还需要接以下四根线:
/*引脚说明*/:
STM32 PB15(MISO) <--- RC522(MOSI)
STM32 PB14(MOSI) ---> RC522(MISO)
STM32 PB13(CLK) ---> RC522(SCK)
STM32 PB12(CSS) ---> RC522(SDA)
unsigned char ReadRawRC(unsigned char addr);
void WriteRawRC(unsigned char addr,unsigned char val);
void ClearBitMask(unsigned char reg,unsigned char mask);
void SetBitMask(unsigned char reg,unsigned char mask);
void PcdAntennaOn(void);
void PcdAntennaOff(void);
char PcdReset(void);
char PcdComMF522(unsigned char Command,unsigned char *pInData,unsigned char InLenByte,unsigned char *pOutData,unsigned int *pOutLenBit);
void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData);
char PcdRequest(unsigned char req_code,unsigned char *pTagType);
char PcdAnticoll(unsigned char *pSnr);
char PcdSelect(unsigned char *pSnr);
char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr);
char PcdRead(unsigned char addr,unsigned char *pData);
char PcdWrite(unsigned char addr,unsigned char *pData);
char PcdHalt(void);
char PcdValue(unsigned char dd_mode,unsigned char addr,unsigned char *pValue);
char PcdBakValue(unsigned char sourceaddr, unsigned char goaladdr);
void RFID_Read_Data(uint8_t id);
void RFID_Write_Data(uint8_t id);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
printf("RFID RC522 test start!\r\n");
while (1)
{
RFID_Read_Data(0);
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);
HAL_Delay(1000);
}
}
编译无误下载到开发板,打开串口调试助手后,调用RFID_Read_Data(0) 时,读取M1卡块0的数据,即厂商段,包含了M1卡的序列号即厂商数据;调用RFID_Read_Data(3) 时,读取M1卡块3的数据,即区尾,包含A/B密钥以及访问控制位,该段出厂默认为:ff ff ff ff ff ff ff 07 80 69 ff ff ff ff ff ff
关注我的公众号,在公众号里发如下消息,即可获取相应的工程源代码:
基于RC522和S50的RFID开发实例