1314 字
7 分钟
页面浏览--访问次数--
RFID 读写器程序

工程文件结构#

  • Devices 硬件驱动
    • display 数码管驱动
    • fm17xx 读写器芯片驱动
    • spi SPI接口驱动
    • uart 串口驱动
  • List
    • RFID.m51 自动生成的文件,记录了单片机存储器的使用情况,以及每个变量包括局部变量的位置1
  • Output 输出文件
    • RFID 用于软件仿真的编译后文件
    • RFID.hex 用于下载程序的十六进制文件
    • RFID.plg 编译日志文件
  • Prject 项目文件夹
    • RFID.uvgui Keil用户界面
    • RFID.uvopt 工程配置文件
    • RFID.uvproj 工程主题文件
    • STARTUP.A51 项目初始化文件2
  • User 用户代码
    • INCLUDE.H 头文件
    • main.c 主函数
    • stc_it.c 中断处理函数
    • STC11.H STC11芯片驱动

/Devices/display/display.c#

// 共阳数码管编码
uchar code table[12] =
{
0xc0, 0xf9, 0xa4, 0xb0, // 0, 1, 2, 3
0x99, 0x92, 0x82, 0xf8, // 4, 5, 6, 7
0x80, 0x90, 0x7f, 0xbf // 8, 9, ., -
};
// 显示当前值到数码管上
void disp(void)
{
// 动态扫描显示
}

/User/fm17xx.c#

// FM17xx 初始化
void init_FM17xx(void)
{
// 可用于初始化 FM1702SL FM1715SL FM1722SL RC522 RC531 等
}
// 卡处理函数,参数 cmd 为指令字段
int rfid_card(uchar cmd)
{
uchar status;
switch (cmd)
{
case _FM17XX_Halt_: // 卡片停止工作
break;
case _FM17XX_Request_: // 获取当前卡片类型
break;
case _FM17XX_Anticoll_: // 防冲突
break;
case _FM17XX_Select_: // 选择卡
break;
case _FM17XX_Cmp_Key2_: // 密钥校验与密钥解析
break;
case _FM17XX_Read_: // 读取某一地址内容
break;
case _FM17XX_Write_: // 写某一地址内容
break;
}
return 0;
}
// 伪代码
// 根据串口命令解析数据
void rfid_deal(uchar cmd, uchar *buf)
{
uchar status, i; //临时变量
uchar sector; //扇区
uchar block; //块
uchar key[6]; //密钥
uchar rev_Data[16]; //块内容
static uchar UID1[4] = {0, 0, 0, 0};
static uchar beep_timer_flag;
switch (cmd)
{
case 0x08: // 读取卡号 显示当前金额依据第二块内容
status = rfid_card(_FM17XX_Request_);
status = rfid_card(_FM17XX_Anticoll_);
break;
case 0x09: // 读取卡信息
// 从 buf 中读区块信息
status = rfid_card(_FM17XX_Request_); // 识别卡类型
status = rfid_card(_FM17XX_Anticoll_); // 防碰撞
if (!enable_Rfid)
{
// 使用上位机的处理函数
// 调用 LED 与蜂鸣器
// 通过串口发送卡号到上位机
status = rfid_card(_FM17XX_Select_); // 选卡
status = rfid_card(_FM17XX_Cmp_Key2_); // 密钥校验与密钥解析
fm1702sl.buffer[0] = _FM17XX_Read_; // 读卡
fm1702sl.buffer[1] = block;
if (!status)
{
status = rfid_card(_FM17XX_Read_); // 读卡
// 协议缓冲与其它处理
}
}
else
{
// 不使用上位机的处理函数
// 调用 LED 与蜂鸣器
status = rfid_card(_FM17XX_Select_); // 选卡
status = rfid_card(_FM17XX_Cmp_Key2_); //密钥校验与密钥解析
fm1702sl.buffer[0] = _FM17XX_Read_; // 读卡
fm1702sl.buffer[1] = block;
// 其它处理
}
break;
case 0x10: //写入块地址内容 上位机无法修改 4*SEN+3 地址内容
status = rfid_card(_FM17XX_Request_); // 识别卡类型
status = rfid_card(_FM17XX_Anticoll_); // 防碰撞
status = rfid_card(_FM17XX_Select_); // 选卡
status = rfid_card(_FM17XX_Cmp_Key2_); //密钥校验与密钥解析
if (!status)
{
status = rfid_card(_FM17XX_Write_); // 写卡
}
break;
case 0x11: //修改密钥
status = rfid_card(_FM17XX_Request_); // 识别卡类型
status = rfid_card(_FM17XX_Anticoll_); // 防碰撞
status = rfid_card(_FM17XX_Select_); // 选卡
status = rfid_card(_FM17XX_Cmp_Key2_); //密钥校验与密钥解析
if (!status)
{
status = rfid_card(_FM17XX_Write_); // 写卡
}
break;
case 0x12: //已注册卡
while (1)
{
status = rfid_card(_FM17XX_Request_); // 识别卡类型
status = rfid_card(_FM17XX_Anticoll_); // 防碰撞
// 调用 LED
}
break;
}
}

/User/main.c#

// 系统初始化
void sys_init(void)
{
// 初始化 MCU-port UART-int fm17xx-spi
}
// 延迟函数
void delay1(uint dlength)
{
uint i;
for (i = 0; i < dlength; i++)
{
_nop_();
_nop_();
_nop_();
}
}
// 主函数
void main(void)
{
uchar data Aread[8] = {0x01, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
uchar status;
sys_init(); // 系统初始化:MCU-port UART-int fm17xx-spi
while (1)
{
if (enable_Rfid) // 按照上位机发送的命令和数据处理卡片
{
P1 = H5;
P2 = table[0]; // 点亮数码管最低位,显示数字'0'
rfid_deal(fm1702sl.cmd, fm1702sl.rev_Data);
enable_Rfid = FALSE;
fm1702sl.read_one = 1;
sys_init(); // 系统重新初始化
}
else
{
// 只通过读写器读卡,没有使用上位机,只读一次卡的内容
if (fm1702sl.read_one == 1)
{
disp(); // 如果读过一次,则显示卡余额
if (fm1702sl.reading > 20)
{
status = rfid_card(_FM17XX_Request_);
if (status != 0)
{
fm1702sl.read_one = 0;
}
fm1702sl.reading = 0;
}
}
//如果还没读卡,则发送 0x09 命令读取卡上信息
else
{
ET0 = 0;
rfid_deal(0x09, Aread);
P1 = H5;
P2 = table[0];
}
}
}
}

编译程序#

  1. 在 Keil C51 中打开工程RFID.uvproj
  1. 打开 Target Options...,转到Output,确认勾选Create HEX File并确认,以在编译时输出hex 文件
  1. 点击编译按钮,或使用快捷键F7开始编译,编译输出窗口中显示Creating hex file from "..OutputRFID"...及0 Error(s),即表示编译输出成功

下载程序#

  1. 使用Prolific PL2303 RS232 - USB 接口转换器连接主板与计算机,打开设备管理器检查端口号并记录备用

  2. 启动STC-ISP,单片机型号选择STC11F60XE系列 - STC11F32XE,端口号选择步骤 1 中记录的端口号,点击打开程序文件,选择到工程根目录下的OutputRFID.hex,点击下载/编程,此时关闭并开启单片机电源,即可开始下载程序。

功能测试#

启动专用调试工具,选择上一节步骤 1 中记录的端口号,打开串口,即可测试充值、消费、余额查询等功能。执行各项操作时,也可以观察实际收发的指令信息。

参考#

RFID 读写器程序
https://gehongyan.cn/posts/iot/rfid-coding/
作者
戈小荷
发布于
2020-09-22
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。

继续阅读

沿着主题读

基于共同的标签与分类

换条路线

从其他文章中稳定抽取

评论

正在加载评论...

最后更新于 ,距今已过 2222 天

部分内容可能已过时