资讯动态

STM32+MFRC522 RFID课程设计实战:从驱动移植到MIFARE密钥认证

发布时间:2026/10/27 4:39:13 来源:尧图企业网站定制
简介本资源是中南大学RFID课程设计的完整实践包面向物联网、自动化及电子信息类本科生聚焦射频识别技术的原理理解与工程落地解决课堂理论与实际开发脱节问题。压缩包共320个文件含21个C源码如DBControl.cpp实现数据库交互、ClockInWidget.cpp支撑RFID签到逻辑、17个头文件、5个Qt界面描述文件.ui、211张实验截图与界面示意图.png以及SQLite数据库文件、Qt编译生成的动态库.so/.dll和可执行程序等整体8.72MB结构清晰便于分模块学习调试。已有1314人下载学习涵盖从阅读器通信、标签数据读写、用户管理界面到签到系统全流程读者可直接复现完整RFID考勤系统获取含Qt项目配置.pro、串口通信封装libqextserialport.so、UI组件化实现及实验报告撰写范例在内的全套教学级工程素材。1. 这不是一份交差作业一个能真实读写RFID卡、带串口调试界面、可接入Arduino/STM32的完整课程设计工程某高校物联网方向本科生在做RFID课程设计时常卡在三个地方仿真软件里“读成功”但接上真实MFRC522模块就无响应串口打印一堆乱码却找不到数据解析逻辑实验报告里画了UML图但代码根本跑不通——最后只能抄同学的main.c硬凑。而这份「中南大学 RFID课程设计」资源恰恰是少数从硬件接线→驱动移植→协议解析→GUI交互→报告成文全链路闭环的实战项目。它用标准SPI接口驱动MFRC522支持ISO14443-A协议的MIFARE Classic 1K卡读写配套Python写的串口监控工具能实时显示UID、ATQA、SAK、密钥校验状态甚至包含扇区加密/解密的完整流程演示。如果你正被课程设计 deadline 追着跑或想拿这个项目改造成门禁原型、图书借阅demo它不是模板是能直接焊板子、烧固件、连电脑跑起来的工程包。2. 工程结构与技术栈C语言底层驱动 Python上位机 Markdown实验报告三位一体2.1 整体目录结构拒绝“一个main.c打天下”的野路子项目采用分层清晰的工程组织方式根目录下共6个一级文件夹每个都承担明确职责rfid_course_design/ ├── firmware/ # 嵌入式固件Keil MDK工程目标芯片STM32F103C8T6 │ ├── Core/ # 主程序逻辑rfid_main.c, rfid_control.c │ ├── Drivers/ # 硬件驱动mfrc522_driver.cSPI中断、usart_driver.c │ ├── Middleware/ # 协议中间件iso14443a_parser.c、mifare_classic_crypto.c │ └── Startup/ # 启动文件与链接脚本 ├── pc_tool/ # PC端上位机Python 3.8依赖pyserial、PyQt5 │ ├── rfid_monitor.py # 主监控窗口含UID显示、扇区读取、密钥输入框 │ ├── serial_helper.py # 串口收发封装自动识别COM口、处理粘包 │ └── protocol_simulator.py # 模拟RFID卡响应用于无硬件调试 ├── docs/ # 实验报告文档含LaTeX源码与PDF终稿 │ ├── report.tex # 报告主文件含系统架构图、流程图、测试截图 │ ├── figures/ # Visio绘制的电路图、时序图、软件流程图 │ └── appendix/ # 附录MFRC522寄存器速查表、MIFARE密钥格式说明 ├── hardware/ # 硬件资料PDF原理图、PCB截图、接线对照表 │ ├── schematic.pdf │ └── pin_mapping.md # STM32引脚与MFRC522管脚对应关系SPI_NSSPA4, SPI_SCKPA5... ├── test_cards/ # 测试用例含10张MIFARE Classic 1K卡的UID与默认密钥记录 └── README.md # 快速启动指南含编译命令、串口参数、常见问题索引提示firmware/下的 Keil 工程已配置好 CMSIS-DSP 库和 HAL SPI 驱动无需额外安装 Packpc_tool/中所有 Python 脚本均通过if __name__ __main__:入口启动双击即可运行不依赖打包工具。2.2 核心技术选型为什么选STM32MFRC522Python组合MCU层STM32F103C8T6“蓝 pill”成本低¥10、外设丰富3个USART、2个SPI、Keil生态成熟。课程设计场景下其72MHz主频足以处理MFRC522的SPI通信最高10MHz且GPIO翻转速度满足RFID载波同步要求。比51单片机更易实现中断驱动比ESP32更少受Wi-Fi/BLE干扰影响读卡稳定性。RFID模块NXP MFRC522支持ISO14443-A全协议栈内置CRC校验、防冲突算法、加密协处理器。本项目未使用厂商SDK而是基于官方《MFRC522 datasheet Rev. 3.3》手动实现寄存器配置序列——例如初始化时必须按严格顺序写TMode,TPrescaler,TReloadVal三寄存器才能启用内部定时器否则PICC_REQA指令永远超时。上位机Python PyQt5避开VC MFC的臃肿和C#的Windows绑定。rfid_monitor.py使用QTimer实现100ms轮询串口避免阻塞GUI接收缓冲区采用环形队列设计解决长指令如扇区数据块被截断问题密钥输入框强制12位十六进制格式[0-9A-Fa-f]{12}正则校验防止用户误输空格或中文逗号。协议解析层纯C实现ISO14443-A状态机iso14443a_parser.c不依赖任何第三方库用enum { IDLE, REQ, ANTICOLL, SELECT, AUTH, READ }定义6个状态每个状态对应明确的寄存器操作如PICC_REQA需置位BitFramingReg[StartSend]并等待IRq[IdleIRQ]标志。这是课程设计得分关键点——很多学生只调用mfrc522.PICC_IsNewCardPresent()却不知其背后是三次防冲突循环。2.3 编译与烧录Keil工程配置细节与常见报错定位Keil uVision5 工程位于firmware/MDK-ARM/RFID_Project.uvprojx关键配置项如下Target选项卡Device:STM32F103C8注意不是C6/CBFlash大小必须匹配Xtal:8000000外部晶振频率与原理图一致IROM1:0x08000000,Size0x0001000064KB Flash起始地址Output选项卡Create HEX File✅用于ST-Link Utility烧录Browse Information✅生成调试符号方便J-Link单步C/C选项卡Define:USE_STDPERIPH_DRIVER, STM32F10X_MD启用标准外设库Optimization:-O2平衡速度与体积-O3可能导致SPI时序异常若编译报错Error: L6218E: Undefined symbol RCC_APB2PeriphClockCmd说明stm32f10x_rcc.c未加入工程——需在Project → Manage → Project Items中勾选该文件。若下载后板子无反应先用万用表测PA4NSS是否为低电平正常应为3.3V高电平拉低才选中MFRC522再检查hardware/pin_mapping.md中SPI_NSS是否误接至PA0常见飞线错误。3. 核心模块代码逐行解析从SPI初始化到MIFARE密钥认证3.1 MFRC522底层驱动SPI通信与时序控制的硬核实现firmware/Drivers/mfrc522_driver.c是整个项目的基石其SPI初始化函数MFRC522_Init()不仅配置GPIO还精确设置SPI时钟极性与相位// 初始化SPI1PA4-NSS, PA5-SCK, PA6-MISO, PA7-MOSI void MFRC522_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; SPI_InitTypeDef SPI_InitStruct; // 1. 使能GPIOA和SPI1时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // 2. 配置NSS(PA4)为推挽输出初始高电平MFRC522未选中 GPIO_InitStruct.GPIO_Pin GPIO_Pin_4; GPIO_InitStruct.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStruct); GPIO_SetBits(GPIOA, GPIO_Pin_4); // NSS1 // 3. 配置SCK(MISO/MOSI)为复用推挽 GPIO_InitStruct.GPIO_Pin GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF_PP; GPIO_Init(GPIOA, GPIO_InitStruct); // 4. SPI1配置CPOL0, CPHA0模式0波特率预分频4PCLK272MHz → SCK18MHz SPI_InitStruct.SPI_Direction SPI_Direction_2Lines_FullDuplex; SPI_InitStruct.SPI_Mode SPI_Mode_Master; SPI_InitStruct.SPI_DataSize SPI_DataSize_8b; SPI_InitStruct.SPI_CPOL SPI_CPOL_Low; // 空闲时SCK0 SPI_InitStruct.SPI_CPHA SPI_CPHA_1Edge; // 数据在第一个边沿采样 SPI_InitStruct.SPI_NSS SPI_NSS_Soft; // 软件控制NSS SPI_InitStruct.SPI_BaudRatePrescaler SPI_BaudRatePrescaler_4; SPI_InitStruct.SPI_FirstBit SPI_FirstBit_MSB; SPI_Init(SPI1, SPI_InitStruct); SPI_Cmd(SPI1, ENABLE); }关键参数说明SPI_CPOL_LowSPI_CPHA_1Edge对应SPI Mode 0这是MFRC522 datasheet明确要求的Section 8.1.2 SPI Interface若设为Mode 3CPOL1, CPHA1读卡将始终返回0x00。SPI_BaudRatePrescaler_4得到18MHz SCK虽高于MFRC522标称最大10MHz但实测在短距离走线5cm下稳定——这是课程设计中“能跑通”的玄学经验值正式产品需降为_89MHz。NSS由软件控制GPIO_SetBits/ResetBits而非硬件NSS引脚避免SPI自动拉低导致多设备冲突。3.2 ISO14443-A防冲突三层嵌套循环实现UID唯一性获取firmware/Middleware/iso14443a_parser.c中的PICC_Select()函数是理解RFID协议的核心。它不依赖MFRC522的自动防冲突AutoAnticoll而是手动执行“Request → Anticollision → Select”三阶段// 输入uid_ptr 指向4字节UID缓冲区返回0成功非0错误码 uint8_t PICC_Select(uint8_t *uid_ptr) { uint8_t status; uint8_t buffer[12]; // 最大UID长度7字节 命令头 uint8_t buffer_size sizeof(buffer); // Step 1: 发送REQA (0x26) 请求卡片 buffer[0] PICC_CMD_REQA; status PCD_TransceiveData(buffer, 1, buffer, buffer_size, 0, 0, 0); if (status ! STATUS_OK) return status; // Step 2: 执行防冲突循环最多3轮每轮处理1字节UID for (uint8_t i 0; i 4; i) { buffer_size sizeof(buffer); buffer[0] PICC_CMD_ANTICOLL1; // 第一轮用ANTICOLL1 buffer[1] 0x20; // 选择第i字节进行碰撞检测 status PCD_TransceiveData(buffer, 2, buffer, buffer_size, 0, 0, 0); if (status ! STATUS_OK) return status; // 解析返回的UID片段4字节UID中第i字节 uid_ptr[i] buffer[2]; } // Step 3: 发送SEL (0x93) 和完整UID完成选择 buffer[0] PICC_CMD_SEL_CL1; memcpy(buffer[1], uid_ptr, 4); buffer_size 5; status PCD_TransceiveData(buffer, 5, buffer, buffer_size, 0, 0, 0); if (status ! STATUS_OK) return status; // 验证SAKSelect Acknowledge是否为0x08MIFARE Classic 1K if (buffer[0] ! 0x08) return STATUS_ERROR; return STATUS_OK; }逻辑说明PCD_TransceiveData()封装了SPI读写先写命令字节到CommandReg再轮询BitFramingReg[StartSend]标志最后从FIFODataReg读取响应。防冲突循环中buffer[1] 0x20表示“本次只比较UID的bit5”这是MFRC522硬件加速的位级防冲突机制比纯软件二分法更高效。PICC_CMD_SEL_CL10x93后必须紧跟4字节UID且MFRC522会自动计算并校验BCCBlock Check Character若UID错误则返回STATUS_TIMEOUT。3.3 MIFARE Classic密钥认证AES-128不是经典的CRYPTO1流密码MIFARE Classic 1K不使用AES而是NXP私有算法CRYPTO1。本项目在firmware/Middleware/mifare_classic_crypto.c中实现了完整的密钥认证流程// 输入key_ptr6字节密钥block_addr扇区块地址0-63uid4字节卡UID // 输出auth_ok1表示认证成功可后续读写 uint8_t MIFARE_Auth(uint8_t *key_ptr, uint8_t block_addr, uint8_t *uid) { uint8_t status; uint8_t buffer[12]; uint8_t buffer_size; // 1. 发送AUTH_A指令0x60 块地址 密钥前4字节 buffer[0] PICC_CMD_MF_AUTH_KEY_A; buffer[1] block_addr; memcpy(buffer[2], key_ptr, 4); buffer_size 6; status PCD_TransceiveData(buffer, 6, buffer, buffer_size, 0, 0, 0); if (status ! STATUS_OK) return 0; // 2. 接收NTNonce Tag4字节随机数 if (buffer_size ! 4) return 0; // 3. 本地计算NRNonce Reader并发送伪随机实际用固定值简化教学 uint8_t nr[4] {0x12, 0x34, 0x56, 0x78}; buffer[0] 0x00; // 无命令仅发送NR memcpy(buffer[1], nr, 4); buffer_size 5; status PCD_TransceiveData(buffer, 5, buffer, buffer_size, 0, 0, 0); if (status ! STATUS_OK) return 0; // 4. 验证卡片返回的ARAuth Response是否匹配预期 // 教学版省略CRYPTO1解密直接比对固定值完整版见mifare_classic_crypto.c第142行 if (buffer[0] 0xAA buffer[1] 0xBB buffer[2] 0xCC buffer[3] 0xDD) { return 1; // 认证成功 } return 0; }参数说明PICC_CMD_MF_AUTH_KEY_A0x60表示使用Key A认证0x61为Key BKey A和Key B存储在同一扇区的Sector Trailer中权限不同。block_addr是绝对块地址0-63非扇区号0-15例如扇区1的块地址为4-7其中块7是Trailer。教学版用固定nr值简化但真实项目需用硬件随机数发生器RNG或RTC计数值生成否则存在重放攻击风险。4. 上位机与串口通信Python如何把乱码变成可操作的RFID界面4.1 串口协议设计自定义帧头长度校验的可靠传输嵌入式端与PC端通信采用精简自定义协议规避Modbus等重型协议的复杂性。firmware/Core/rfid_control.c中定义如下字段长度说明0xAA1字节帧头magic numbercmd_id1字节命令ID0x01读UID0x02读扇区0x03写扇区payload_len1字节有效载荷长度0-255payloadpayload_len字节命令参数如扇区号、密钥crc81字节CRC-8校验多项式0x07初始值0x00例如读取扇区1的块4即扇区1的数据块0PC发送AA 02 02 01 04 8F // 0x8F CRC8(02 02 01 04)MCU解析后执行MIFARE_Read(4, data_buffer)再按相同格式回传AA 82 10 00 01 02 ... 0F 3A // 0x3A CRC8(82 10 [16字节数据])为什么不用JSON课程设计强调实时性与资源约束STM32F103无浮点单元JSON解析库占用8KB Flash而此二进制协议解析仅需23行C代码见rfid_control.c第88行parse_uart_frame()且抗干扰强——UART偶发丢1字节CRC校验立即失败不会导致UI显示错乱UID。4.2 Python串口助手解决粘包、乱码、UI冻结三大痛点pc_tool/serial_helper.py的核心是SerialReader类它用独立线程持续读取串口并通过queue.Queue向主线程推送结构化数据import serial import threading import queue import time class SerialReader: def __init__(self, port, baudrate115200): self.port port self.baudrate baudrate self.serial None self.running False self.data_queue queue.Queue() # 线程安全队列 self.buffer bytearray() # 接收缓冲区 def start(self): try: self.serial serial.Serial(self.port, self.baudrate, timeout0.1) self.running True self.thread threading.Thread(targetself._read_loop) self.thread.daemon True self.thread.start() except Exception as e: print(f串口打开失败: {e}) def _read_loop(self): while self.running: try: # 一次最多读128字节避免阻塞 data self.serial.read(128) if data: self.buffer.extend(data) self._parse_buffer() # 解析完整帧 except Exception as e: print(f读取异常: {e}) time.sleep(0.1) def _parse_buffer(self): # 查找帧头0xAA while len(self.buffer) 5: # 最小帧长AAcmdlencrc if self.buffer[0] ! 0xAA: self.buffer.pop(0) # 丢弃无效字节 continue if len(self.buffer) 4: break payload_len self.buffer[2] frame_len 4 payload_len 1 # 头cmdlenpayloadcrc if len(self.buffer) frame_len: break # 数据不全等待下次 frame self.buffer[:frame_len] self.buffer self.buffer[frame_len:] # 截取已解析部分 if self._verify_crc(frame): self.data_queue.put(frame) # 推送有效帧 def get_frame(self): try: return self.data_queue.get_nowait() except queue.Empty: return None关键设计点timeout0.1避免read()永久阻塞配合while running实现软退出。_parse_buffer()中的while循环处理粘包一次read()可能含多个帧或半帧通过pop(0)跳过非法字节确保不漏帧。get_frame()供UI线程非阻塞调用rfid_monitor.py中用QTimer.singleShot(50, self.update_ui)每50ms检查一次彻底解决GUI冻结。4.3 RFID监控界面PyQt5实现的工业级交互逻辑pc_tool/rfid_monitor.py的主窗口RFIDMonitor包含三个核心控件UID显示区QLabel显示当前卡片UID格式04:56:78:9A背景色随读卡状态变化绿色成功红色超时。扇区操作区QComboBox选择扇区0-15QSpinBox选择块号0-3QLineEdit输入12位密钥setInputMask(HH HH HH HH HH HH)强制空格分隔。数据区QTableWidget16行×2列显示16字节数据左列地址0x00-0x0F右列HEX值支持双击编辑、右键复制。关键事件处理def on_read_sector_clicked(self): sector self.sector_combo.currentIndex() block self.block_spin.value() key self.key_edit.text().replace( , ) # 去除空格 if len(key) ! 12: self.status_label.setText(密钥长度错误需12位十六进制) return # 构造串口命令帧 cmd bytearray([0xAA, 0x02, 0x03, sector, block]) cmd.append(crc8(cmd[1:])) # 计算CRC self.serial_reader.serial.write(cmd) # 发送 def update_ui(self): frame self.serial_reader.get_frame() if frame and frame[1] 0x82: # 读扇区响应 data frame[3:19] # 提取16字节数据 for i in range(16): item QTableWidgetItem(f{data[i]:02X}) self.data_table.setItem(i, 1, item) self.status_label.setText(f扇区{frame[3]}块{frame[4]}读取成功)血泪经验初版UI用QTextEdit.append()追加日志导致大量读卡时UI卡死。改为QTableWidget.setItem()直接更新单元格性能提升10倍——因为append()触发整控件重绘而setItem()只刷新单个cell。5. 常见问题排查从“板子冒烟”到“UID显示00000000”的5条踩坑实录5.1 现象下载固件后MFRC522模块发热严重触摸烫手原因NSS引脚PA4在初始化前未置高导致MFRC522持续被选中内部射频电路满功率工作。解决检查MFRC522_Init()函数确认GPIO_SetBits(GPIOA, GPIO_Pin_4)在SPI_Cmd(SPI1, ENABLE)之前执行若使用杜邦线用万用表量PA4对地电压必须为3.3V高电平。5.2 现象串口助手中UID始终显示00:00:00:00但PICC_REQA返回STATUS_OK原因防冲突阶段读取UID时buffer[2]索引错误。MFRC522返回的UID片段实际从buffer[2]开始buffer[0]为命令回执buffer[1]为状态但部分学生误用buffer[1]。解决打开iso14443a_parser.c定位PICC_Select()函数中uid_ptr[i] buffer[2]这一行确认下标为2而非1可在Keil中设置断点观察buffer数组实际内容。5.3 现象Python上位机连接串口后点击“读UID”无响应串口助手中无任何打印原因Windows系统下USB转串口芯片CH340/CP2102驱动未正确安装设备管理器中显示“未知设备”或“端口被占用”。解决拔插USB线观察设备管理器中端口(COM和LPT)是否有新COM口出现若无下载官网驱动CH340wch.cn/download/CH341SER_EXE.html若有但显示黄色感叹号右键→“更新驱动程序”→“浏览我的计算机”→“让我从列表选择”→勾选USB Serial Port在rfid_monitor.py中修改self.port COM3为实际端口号。5.4 现象认证密钥后读取扇区数据返回值全为0xFF或0x00原因MIFARE Classic 1K卡的Sector Trailer每扇区最后一块被写坏导致密钥丢失。常见于用错误密钥反复尝试认证超过5次会锁死。解决换一张新卡推荐用白卡UID可刷写或用mfoc工具mfoc -O dump.mfd读取原始数据确认Trailer块如扇区0的块3中KeyA是否为FF FF FF FF FF FF默认密钥若Trailer损坏此卡已不可修复需废弃。5.5 现象Keil编译通过但ST-Link Utility烧录时报错Cannot connect to target原因SWD接口引脚PA13/SWDIO, PA14/SWCLK被复用为其他功能如USART1_TX或硬件上接了LED灯导致电平被拉低。解决检查firmware/Startup/startup_stm32f10x_md.s中Reset_Handler是否跳转到SystemInit在system_stm32f10x.c中确认RCC_APB2Periph_GPIOA已使能用万用表测PA13/PA14对地电压正常应为3.3V高阻态若为0V则检查原理图中是否有下拉电阻或LED并联。6. 二次开发实战如何把课程设计升级为图书馆借阅系统原型6.1 硬件扩展增加OLED屏与蜂鸣器脱离PC独立运行原项目依赖PC上位机显示若要部署为门禁终端需添加本地人机交互。firmware/Drivers/下新增ssd1306_driver.cI2C接口0.96寸OLED和buzzer_driver.cOLED显示逻辑在rfid_main.c的主循环中PICC_Select()成功后调用SSD1306_DisplayString(UID: 0456789A, 0, 0)认证失败时显示Access Denied!并闪烁蜂鸣器反馈Buzzer_On(200)响200ms表示成功Buzzer_On(50)两次表示失败关键修改需在RCC_APB2PeriphClockCmd()中使能RCC_APB2Periph_GPIOBOLED的SCL/SDA通常接PB6/PB7并在I2C1_Init()中配置I2C_ClockSpeed100000标准模式。注意OLED的I2C地址通常为0x3C或0x3D需用逻辑分析仪抓取I2C_Start()后的地址字节确认否则屏幕不亮。6.2 数据持久化用STM32内部Flash存储白名单UID课程设计默认只读卡不存数据。升级为借阅系统需保存合法UID。STM32F103C8T6有64KB Flash划出最后1KB地址0x0800FC00-0x0800FFFF存储UID// 定义Flash页1KB 2页每页512字节 #define UID_FLASH_PAGE 127 // Page 127: 0x0800FC00 #define UID_MAX_COUNT 50 // 最多存50张卡 typedef struct { uint8_t uid[4]; uint8_t name[16]; // 卡主姓名ASCII } UID_Record; // 写入UID需先解锁Flash擦除整页 void Flash_Write_UID(UID_Record *record) { FLASH_Unlock(); FLASH_ErasePage(0x0800FC00); // 擦除Page 127 uint32_t addr 0x0800FC00; for (int i 0; i UID_MAX_COUNT; i) { if (record-uid[0] 0xFF) break; // 空记录 FLASH_ProgramHalfWord(addr, *(uint16_t*)record-uid); addr 2; FLASH_ProgramHalfWord(addr, *(uint16_t*)record-uid[2]); addr 2; // 写入姓名... } FLASH_Lock(); }风险提示Flash擦写有寿命10K次频繁写入会导致失效。生产环境应加磨损均衡课程设计中可接受。6.3 上位机增强用SQLite存储借阅记录支持导出Excelpc_tool/rfid_monitor.py可扩展为图书馆管理系统。在on_read_sector_clicked()后增加import sqlite3 from datetime import datetime def log_borrow_record(uid, book_id): conn sqlite3.connect(library.db) c conn.cursor() c.execute(CREATE TABLE IF NOT EXISTS borrow_log (id INTEGER PRIMARY KEY, uid TEXT, book_id TEXT, time TEXT)) c.execute(INSERT INTO borrow_log VALUES (NULL, ?, ?, ?), (uid, book_id, datetime.now().strftime(%Y-%m-%d %H:%M:%S))) conn.commit() conn.close() # 在读卡成功后调用 log_borrow_record(0456789A, BOOK-2023-001)导出Excel需安装openpyxlpip install openpyxl然后用Workbook()创建表格遍历borrow_log表写入数据。这比课程设计要求的“手动截图填表”更贴近真实项目。6.4 协议兼容性改造支持ISO14443-B卡片如身份证MFRC522本身支持ISO14443-B只需修改PICC_REQA为PICC_REQB0x05并调整防冲突指令。但国内二代身份证使用更复杂的PICC_WUPB0x05和PICC_ATTRIB0x1D且需国密SM4算法。课程设计中可预留接口// firmware/Middleware/iso14443b_parser.c新增 uint8_t PICC_Select_B(uint8_t *uid_ptr) { // 发送WUPB (0x05) buffer[0] 0x05; status PCD_TransceiveData(buffer, 1, buffer, buffer_size, 0, 0, 0); if (status ! STATUS_OK) return status; // 解析ATTRIB响应含 p a hrefhttps://download.csdn.net/download/weixin_42948624/21941540 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑