概述
我的测试为RC522的读写模块和S50的射频卡:
一.S50的射频卡有如下特点:
1. 分为16个扇区,每个扇区为4块,每块16个字节,以块为存取单位
2. 每个扇区有独立的一组密码及访问控制
3. 每张卡有唯一序列号,为32位
二.射频卡的介绍
1、M1卡分为16个扇区,每个扇区由4块(块0、块1、块2、块3)组成,(我们也将16个扇区的64个块按绝对地址编号为0~63,存贮结构如下图所示:
|
|
|
|
|
| 块0 |
| 数据块 | 0 |
扇区0 | 块1 |
| 数据块 | 1 |
| 块2 |
| 数据块 | 2 |
| 块3 | 密码A 存取控制 密码B | 控制块 | 3 |
| 块0 |
| 数据块 | 4 |
扇区1 | 块1 |
| 数据块 | 5 |
| 块2 |
| 数据块 | 6 |
| 块3 | 密码A 存取控制 密码B | 控制块 | 7 |
|
|
∶ ∶ ∶
|
|
|
| 0 |
| 数据块 | 60 |
扇区15 | 1 |
| 数据块 | 61 |
| 2 |
| 数据块 | 62 |
| 3 | 密码A 存取控制 密码B | 控制块 | 63 |
2、第0扇区的块0(即绝对地址0块),它用于存放厂商代码,已经固化,不可更改。
3、每个扇区的块0、块1、块2为数据块,可用于存贮数据。
数据块可作两种应用:
★ 用作一般的数据保存,可以进行读、写操作。
★ 用作数据值,可以进行初始化值、加值、减值、读值操作。
4、每个扇区的块3为控制块,包括了密码A、存取控制、密码B。具体结构如下:
|
密码A(6字节) 存取控制(4字节) 密码B(6字节)
5、每个扇区的密码和存取控制都是独立的,可以根据实际需要设定各自的密码及存取控制。存取控制为4个字节,共32位,扇区中的每个块(包括数据块和控制块)的存取条件是由密码和存取控制共同决定的,在存取控制中每个块都有相应的三个控制位,定义如下:
块0: C10 C20 C30
块1: C11 C21 C31
块2: C12 C22 C32
块3: C13 C23 C33
三个控制位以正和反两种形式存在于存取控制字节中,决定了该块的访问权限(如
进行减值操作必须验证KEY A,进行加值操作必须验证KEY B,等等)。三个控制
位在存取控制字节中的位置如下:
bit 7 6 5 4 3 2 1 0
字节6 | C23_b | C22_b | C21_b | C20_b1 | C13_b | C12_b | C11_b | C10_b1 |
字节7 | C13 | C12 | C11 | C10 0 | C33_b | C32_b | C31_b | C30_b1 |
字节8 | C33 | C32 | C31 | C30 0 | C23 | C22 | C21 | C20 0 |
字节9 |
|
|
|
|
|
|
|
|
( 注: cn.x表示块x的第n个值,_b表示取反 )
6、数据块(块0、块1、块2)的存取控制如下:
控制位(X=0..2)
| 访 问 条 件 (对数据块 0、1、2) | |||||
C1X | C2X | C3X | Read | Write | Increment | Decrement, transfer, Restore |
0 | 0 | 0 | KeyA|B | KeyA|B | KeyA|B | KeyA|B |
0 | 1 | 0 | KeyA|B | Never | Never | Never |
1 | 0 | 0 | KeyA|B | KeyB | Never | Never |
1 | 1 | 0 | KeyA|B | KeyB | KeyB | KeyA|B |
0 | 0 | 1 | KeyA|B | Never | Never | KeyA|B |
0 | 1 | 1 | KeyB | KeyB | Never | Never |
1 | 0 | 1 | KeyB | Never | Never | Never |
1 | 1 | 1 | Never | Never | Never | Never |
(KeyA|B 表示密码A或密码B,Never表示任何条件下不能实现)
例如:当块0的存取控制位C10C20C30=1 0 0时,验证密码A或密码B正确后可读;
验证密码B正确后可写;不能进行加值、减值操作。
7、控制块块3的存取控制与数据块(块0、1、2)不同,它的存取控制如下:
|
|
| 密码A | 存取控制 | 密码B | |||
C13 | C23 | C33 | Read | Write | Read | Write | Read | Write |
0 | 0 | 0 | Never | KeyA|B | KeyA|B | Never | KeyA|B | KeyA|B |
0 | 1 | 0 | Never | Never | KeyA|B | Never | KeyA|B | Never |
1 | 0 | 0 | Never | KeyB | KeyA|B | Never | Never | KeyB |
1 | 1 | 0 | Never | Never | KeyA|B | Never | Never | Never |
0 | 0 | 1 | Never | KeyA|B | KeyA|B | KeyA|B | KeyA|B | KeyA|B |
0 | 1 | 1 | Never | KeyB | KeyA|B | KeyB | Never | KeyB |
1 | 0 | 1 | Never | Never | KeyA|B | KeyB | Never | Never |
1 | 1 | 1 | Never | Never | KeyA|B | Never | Never | Never |
例如:当块3的存取控制位C13 C23C33=1 0 0时,表示:
密码A:不可读,验证KEYA或KEYB正确后,可写(更改)。
存取控制:验证KEYA或KEYB正确后,可读、可写。
密码B:验证KEYA或KEYB正确后,可读、可写。
三.程序访问
在程序中我们首先要获得卡序列号:
status = MFRC522_Anticoll(str);
str里的数据就是卡序列号,status的值可以判断得到结果是否成功;
每次进行读写时都需要进行验证,这里以读写第一扇区的第1块为例:
status = MFRC522_Auth(PICC_AUTHENT1A, 4, sectorKeyA[1], serNum);
这里的块4为扇区11的第1块,sectorKeyA[1]为6个0xFF,是因为卡的密码A初始密码就是6个oxFF,serNum为卡序列号。
uchar sectorKeyA[16][16] = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
};
uchar MFRC522_Auth(uchar authMode, uchar BlockAddr, uchar *Sectorkey,uchar *serNum)
函 数 名:MFRC522_Auth
* 功能描述:验证卡片密码
* 输入参数:authMode--密码验证模式
0x60 = 验证A密钥
0x61 = 验证B密钥
BlockAddr--块地址
Sectorkey--扇区密码
serNum--卡片序列号,4字节
当验证成功后,会返回相应的值给status;
验证成功后就可以写数据了:
status = MFRC522_Write(4, writeDate);
当要进行读操作时,仍然还需要进行验证:
status = MFRC522_Auth(PICC_AUTHENT1A, 4, sectorKeyA[1], serNum);
验证成功后就可以读数据了:
status = MFRC522_Read(4, str);
以上就是读写操作,新手!多多指教.......
最后
以上就是整齐猫咪为你收集整理的射频RC522一些知识的全部内容,希望文章能够帮你解决射频RC522一些知识所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复