概述
基础资料
基于Air103开发板:???? Air103 - LuatOS 文档
上手:开发上手 - LuatOS 文档
探讨重点
对官方社区库接口RC522模块库调用及示例进行复现及分析,了解RDIF及非接触式IC卡的原理及操作方法。
实现功能
利用已知的A,B密钥,进行标准和异型IC卡的数据处理及读写;
硬件准备
Air103开发板1块,面包板1块,RC522读写器模块,标准、异型IC卡各1张,导线若干。
接线
标准SPI接口,可参考博文:
合宙Air105|摄像头|capture|SPI|Serial 串口|TFTLCD|Micro SD卡|GC032A|USB转TTL|官方demo|学习(2-1):摄像头camera-capture_Medlar_CN的博客
除丝印为IRQ的端子无作用(应为NC)外,其他参照开发板功能定义正常接入方式(使用)。
SPI接线设置:
spi_rc522 = spi.setup(0,nil,0,0,8,10*1000*1000,spi.MSB,1,1)
result=rc522.init(0,pin.PB04,pin.PB01) --spi_id, cs, rst
软件版本
AIR103:LuatOS@AIR103 base 22.10 bsp V0013
软件使用
接口文档可参考:rc522 非接触式读写卡驱动
RFID与IC卡
RFID一般指射频识别技术。 射频识别(RFID)是 Radio Frequency Identification 的缩写。其原理为阅读器与标签之间进行非接触式的数据通信,达到识别目标的目的。
而IC卡 (Integrated Circuit Card,集成电路卡),也称智能卡(Smart card)、智慧卡(Intelligent card)、微电路卡(Microcircuit card)或微芯片卡等。
IC卡由于其固有的信息安全、便于携带、比较完善的标准化等优点。IC卡属于使用RFID技术的一个卡片种类。
本文主要介绍Mifare1 S50IC卡,有标准和异型两种类别。
S50IC卡的编码格式
产品简介
S50非接触式IC卡性能简介(M1)
一、 主要指标
容量为8K位EEPROM
分为16个扇区,每个扇区为4块,每块16个字节,以块为存取单位
每个扇区有独立的一组密码及访问控制
每张卡有唯一序列号,为32位
具有防冲突机制,支持多卡操作
无电源,自带天线,内含加密控制逻辑和通讯逻辑电路
数据保存期为10年,可改写10万次,读无限次
工作温度:-20℃~50℃(湿度为90%)
工作频率:13.56MHZ
通信速率:106 KBPS
读写距离:10 cm以内(与读写器有关)
二、存储结构
M1卡分为16个扇区,每个扇区由4块(块0、块1、块2、块3)组成(16个扇区的64个块按绝对地址编号为0~63。
PHILIPS原始芯片的卡片,控制字为:FF078069。
A、B密钥是重要的访问参数,即为操作库代码中的Key_A、Key_B。
local Key_A = string.char(0x00,0x00,0x00,0x00,0x00,0x0)
local Key_B = string.char(0xff,0xff,0xff,0xff,0xff,0xff)
三、特别提醒
测试时最好使用空白卡或者无重要作用的测试卡。
读写操作如果密钥错误或不知道密钥,有加密区块被锁定,而导致该区块整体无法访问和使用的风险。
RC522读写驱动使用及分析
Main.lua
(官方代码库只有RC22库和基础用法。为测试方便,增加了主文件:main.lua):
操作:
1、正常初始化
2、写扇区2-数据块8为:0100000000000000
3、顺序读扇区数据:(0-63)
PROJECT = "rc522-air103"
VERSION = "1.0.0"
sys = require("sys")
local rc522 = require "rc522"
sys.taskInit(function()
spi_rc522 = spi.setup(0,nil,0,0,8,10*1000*1000,spi.MSB,1,1)
--spi_id, cs, rst
rc522.init(0,pin.PB04,pin.PB01)
wdata = {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
local n=8
while 1 do
result=rc522.write_datablock(n,wdata)
if result then
log.info("rc522_write:"..tostring(n), "OK!", result)
else
log.info("rc522_write:"..tostring(n), "Error!", result)
end
for i=0,63 do
local a,b = rc522.read_datablock(i)
if a then
log.info("read",i,b:toHex()) --字节流转换为16进制显示
end
end
sys.wait(500)
end
end)
sys.run()
rc522.lua(驱动程序,主要代码分析,完整代码见官方gitee)
操作库定义:
local rc522 = {}
local sys = require "sys"
local rc522_spi,rc522_rst,rc522_irq,rc522_cs
A,B密钥:
local Key_A = string.char(0x00,0x00,0x00,0x00,0xff,0x0)
local Key_B = string.char(0xff,0xff,0xff,0xff,0xff,0xff)
读写器初始化:
--[[
rc522 初始化
@api rc522.init(spi_id, cs, rst)
@number spi_id spi端口号
@number cs cs引脚
@number rst rst引脚
@return bool 初始化结果
@usage
spi_rc522 = spi.setup(0,nil,0,0,8,10*1000*1000,spi.MSB,1,1)
rc522.init(0,pin.PB04,pin.PB01)
]]
function rc522.init(spi_id,cs,rst)
rc522_spi = spi_id
rc522_cs = gpio.setup(cs, 0, gpio.PULLUP)
rc522_cs(1)
rc522_rst = gpio.setup(rst, 0, gpio.PULLUP)
rc522_rst(1)
rc522.reset()
rc522_config_isotype()
print("rc522.version",rc522.version())
return true
end
读块内容:
--[[
按照rc522操作流程读取块
@api rc522.read_datablock(addr)
@number addr 任意块地址.M1卡总共有16个扇区(每个扇区有:3个数据块+1个控制块),共64个块
@return bool string 结果 数据
@usage
for i=0,63 do
local a,b = rc522.read_datablock(i)
if a then
print("read",i,b:toHex())
end
end
]]
function rc522.read_datablock(addr)
local status,array_id = rc522.request(rc522.reqall)
if status ~= true then
status,array_id = rc522.request(rc522.reqall)
end
if status == true then
local status,uid = rc522.anticoll(array_id)
if status == true then
rc522.select(uid)
status = authstate( rc522_authent1b, addr,Key_B,uid )
if status == true then
local status,data = read(addr)
if status == true then
return true, data
end
rc522.halt()
end
end
end
return false
end
写块内容:
--[[
按照rc522操作流程写入16字节数据到块
@api rc522.write_datablock(addr,data)
@number addr 任意块地址.M1卡总共有16个扇区(每个扇区有:3个数据块+1个控制块),共64个块
@table data 指向要写入的数据,必须为16个字符
@return bool 结果
@usage
rc522.write_datablock(addr,data)
]]
function rc522.write_datablock(addr,data)
if #data ~= 16 then
return false
end
local status,array_id = rc522.request(rc522.reqall)
if status ~= true then
status,array_id = rc522.request(rc522.reqall)
end
if status == true then
local status,uid = rc522.anticoll(array_id)
if status == true then
rc522.select(uid)
status = authstate( rc522_authent1b, addr,Key_B,uid )
if status == true then
status = rc522.write(addr,data)
rc522.halt()
return status
end
end
end
return false
end
日志log文件示例:
最后
以上就是光亮樱桃为你收集整理的合宙Air103|射频读写器|RC522|RDIF|Mifare1 S50|非接触式IC卡|AB密钥|社区库接口|官方demo|学习(9):RC522-射频读写器的全部内容,希望文章能够帮你解决合宙Air103|射频读写器|RC522|RDIF|Mifare1 S50|非接触式IC卡|AB密钥|社区库接口|官方demo|学习(9):RC522-射频读写器所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复