ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

FM17522 SPI驱动实战:从寄存器配置到MIFARE卡UID读取

FM17522 SPI驱动实战:从寄存器配置到MIFARE卡UID读取 简介本资源是复旦微电子FM17522 NFC标签读写芯片的完整官方开发套件面向嵌入式软硬件开发者、物联网终端研发工程师及NFC应用学习者解决NFC标签通信协议理解、低功耗卡片检测LPCD实现、安全数据处理等核心开发难题适用于门禁系统、移动支付终端、防伪追溯设备等场景。压缩包共267个文件总大小4.01MB涵盖74个头文件h、43个C源码c构成的完整驱动与Demo工程含LPCD专项例程、数据加解密与校验逻辑DP模块以及4份关键PDF文档用户手册、Demo指南等辅以编译中间文件o、d、map和Keil工程配置uvproj、uvopt、axf结构完整、开箱即用。目前已有1409人学习下载提供从芯片寄存器配置、SPI/I2C接口控制到实机调试的全链路支持特别适合需快速集成NFC功能并兼顾功耗优化的嵌入式项目开发。1. FM17522不是“即插即用”的NFC芯片——它需要你亲手搭起SPI通信骨架、解析寄存器映射、绕过复位时序陷阱才能让第一张卡片被识别很多人拿到复旦微FM17522开发板后以为接上STM32或ESP32就能立刻读取MIFARE Classic卡——结果串口只输出乱码SPI波形显示CS未拉低或者初始化后Status2Reg始终为0x00。这不是硬件坏了而是FM17522根本没设计成“傻瓜式”NFC控制器它不内置协议栈不自动处理防冲突不封装ISO14443-A帧结构所有底层动作都得靠开发者手动配置60个寄存器。它适合的是嵌入式固件工程师——你需要能看懂《FM17522 Datasheet Rev1.3》第4章时序图、能用逻辑分析仪抓SPI CS/SCK/MOSI/MISO四线波形、能根据CommandReg写入0x0C触发Transceive并等待IRQ0Reg置位。如果你正卡在“能烧录但读不到卡”“能识别卡号但无法认证密钥”“用示波器看到载波但无响应”这篇就是为你写的实战手册。我们不讲抽象协议只拆解从上电到读出UID的每一步寄存器操作、每个延时参数、每个必须校验的状态位。2. 用STM32 HAL库在本地跑通FM17522的最小命令链从SPI初始化到成功读取MIFARE Classic卡UID2.1 硬件连接与电源时序必须严守Datasheet第3.2节要求FM17522对VDD3.3V±5%和VDDA独立模拟电源的上电顺序有硬性约束VDD必须在VDDA之后100μs内稳定否则内部LDO无法锁定。常见错误是直接共用一个LDO供电导致PowerDownReg读回0x00却无法唤醒。正确接法是VDD接ASM1117-3.3V稳压输出加10μF钽电容100nF陶瓷电容VDDA单独接另一路ASM1117-3.3V同样去耦RSTPD引脚必须经10kΩ上拉至VDD且MCU的RST引脚需通过100nF电容耦合到RSTPD实现硬件复位同步SPI四线中NSSCS必须由MCU GPIO控制不能用SPI硬件NSS因FM17522要求CS低电平持续时间≥200ns且高电平保持≥100ns提示若逻辑分析仪捕获到CS脉宽150ns立即检查HAL_SPI_TransmitReceive()是否启用了DMA双缓冲——关闭DMA改用轮询模式可确保时序精度。2.2 SPI初始化关键参数设置以STM32H743为例// SPI handle配置非标准模式 hspi1.Instance SPI1; hspi1.Init.Mode SPI_MODE_MASTER; hspi1.Init.Direction SPI_DIRECTION_2LINES; // 必须双向 hspi1.Init.DataSize SPI_DATASIZE_8BIT; // FM17522只支持8位传输 hspi1.Init.CLKPolarity SPI_POLARITY_LOW; // CPOL0空闲时SCK为低 hspi1.Init.CLKPhase SPI_PHASE_1EDGE; // CPHA0采样在第一个边沿 hspi1.Init.NSS SPI_NSS_SOFT; // 禁用硬件NSSCS由GPIO控制 hspi1.Init.BaudRatePrescaler SPI_BAUDRATEPRESCALER_4; // 18MHz SCKH7主频480MHz时 hspi1.Init.FirstBit SPI_FIRSTBIT_MSB; // MSB先传为什么选CPOL0/CPHA0查Datasheet第5.4.1节“SPI Interface Timing”FM17522的MISO数据在SCK下降沿稳定在上升沿采样因此MCU必须在SCK上升沿读取——这对应CPOL0空闲低、CPHA0采样在第一个边沿。若设为CPHA1将导致每次读取寄存器值偏移1位。2.3 初始化流程6步寄存器操作缺一不可按Datasheet第8.2节“Initialization Sequence”必须严格顺序执行软复位写CommandReg0x0F→ 等待CommandReg返回0x00表示复位完成关闭所有中断写IRQ0Reg0x00,IRQ1Reg0x00配置RF场写TxControlReg0x03启用天线驱动→ 延时delay_us(1000)→ 写TModeReg0x8D设置定时器为13.56MHz分频使能接收器写RxControlReg0x03启用接收器设置低功耗模式设置位速率写TConfigReg0x3E设置106kbpsISO14443-A默认启动RF场写CommandReg0x0CTransceive命令→ 等待IRQ0Reg的IRq0位bit0置1// 关键代码执行Transceive并等待中断 void FM17522_StartTransceive(void) { FM17522_WriteRegister(CommandReg, 0x0C); // 启动收发 while (!(FM17522_ReadRegister(IRQ0Reg) 0x01)); // 等待IRq0置位 // 此时卡片已进入Ready状态可读UID }参数说明TConfigReg0x3E中bit7-bit40011分频系数3bit3-bit01110预分频14最终RF频率13.56MHz/(3×14)322.857kHz符合ISO14443-A Type A的ASK调制要求。3. 解析FM17522寄存器映射与MIFARE Classic卡通信全流程从RequestA到ReadBlock3.1 寄存器地址空间必须按Bank切换访问FM17522的64个寄存器分为4个Bank0~3通过PageSelectReg地址0x01切换。常见错误是直接读FIFODataReg0x09却得到0xFF——因为当前Bank不是0。正确流程写PageSelectReg0x00→ 访问Bank0CommandReg~FIFODataReg写PageSelectReg0x01→ 访问Bank1TimerReg~TestSelReg所有读写操作前必须先写PageSelectRegDatasheet第6.1节明确标注“Page selection must be done before any register access”。3.2 RequestA指令三步完成卡片侦测MIFARE Classic卡响应RequestA需完整走完发送RequestA命令帧向FIFODataReg连续写入0x261字节启动Transceive写CommandReg0x0C读取响应当IRQ0Reg的IRq0置1后读FIFOLevelReg获有效字节数再循环读FIFODataReg获取响应数据// 发送RequestA并读响应 uint8_t FM17522_RequestA(uint8_t *uid) { FM17522_WriteRegister(PageSelectReg, 0x00); // 切Bank0 FM17522_WriteRegister(FIFODataReg, 0x26); // RequestA命令 FM17522_WriteRegister(CommandReg, 0x0C); // 启动 while (!(FM17522_ReadRegister(IRQ0Reg) 0x01)); uint8_t len FM17522_ReadRegister(FIFOLevelReg); // 获取长度 if (len ! 2) return 0; // 期望ATQA2字节 uid[0] FM17522_ReadRegister(FIFODataReg); // ATQA低字节 uid[1] FM17522_ReadRegister(FIFODataReg); // ATQA高字节 return 1; }为什么ATQA是2字节ISO14443-A标准规定ATQAAnswer To Request包含SensRes字段FM17522收到卡片响应后自动截取前2字节存入FIFO无需解析完整帧。3.3 Anticollision与Select四步获取7字节UIDMIFARE Classic卡UID为4字节SAK0x08或7字节SAK0x18需执行防冲突流程步骤写入FIFO的数据说明1. Anticollision0x93 0x20Cascade Level 1发送4字节随机数2. 读取UID低4字节从FIFO读4字节若SAK0x08则结束若SAK0x18则继续3. Anticollision Level 20x95 0x20Cascade Level 2再发4字节随机数4. 读取UID高3字节从FIFO读3字节拼接成7字节完整UID// 获取7字节UID核心逻辑 uint8_t FM17522_GetUID(uint8_t *uid) { // Step1: Level1 Anticollision FM17522_WriteRegister(FIFODataReg, 0x93); FM17522_WriteRegister(FIFODataReg, 0x20); FM17522_WriteRegister(CommandReg, 0x0C); while (!(FM17522_ReadRegister(IRQ0Reg) 0x01)); uint8_t len FM17522_ReadRegister(FIFOLevelReg); if (len 4) return 0; for (int i 0; i 4; i) { uid[i] FM17522_ReadRegister(FIFODataReg); } // Check SAK to decide if need Level2 FM17522_WriteRegister(FIFODataReg, 0x93); // Select command FM17522_WriteRegister(FIFODataReg, uid[0]); FM17522_WriteRegister(FIFODataReg, uid[1]); FM17522_WriteRegister(FIFODataReg, uid[2]); FM17522_WriteRegister(FIFODataReg, uid[3]); FM17522_WriteRegister(CommandReg, 0x0C); while (!(FM17522_ReadRegister(IRQ0Reg) 0x01)); uint8_t sak FM17522_ReadRegister(FIFODataReg); if ((sak 0x04) 0) return 4; // SAK bit20, 4-byte UID // Step2: Level2 Anticollision FM17522_WriteRegister(FIFODataReg, 0x95); FM17522_WriteRegister(FIFODataReg, 0x20); FM17522_WriteRegister(CommandReg, 0x0C); while (!(FM17522_ReadRegister(IRQ0Reg) 0x01)); len FM17522_ReadRegister(FIFOLevelReg); if (len 3) return 4; for (int i 0; i 3; i) { uid[4i] FM17522_ReadRegister(FIFODataReg); } return 7; }参数说明0x93是Anticollision命令Cascade Level 10x95是Level 20x20是固定参数表示“不使用UID”。FM17522会自动生成随机数并插入帧中开发者只需关注返回的UID字节。4. FM17522的3个必调参数TReloadVal、TReloadHi、RxThreshold对读卡距离与稳定性的影响4.1 TReloadVal与TReloadHi决定RF场开启时长的黄金组合TReloadVal地址0x0A和TReloadHi地址0x0B共同构成16位定时器重载值控制RF场持续时间。Datasheet第5.5.2节指出RF场开启时间 (TReloadHi 8 | TReloadVal) × 1/fosc其中fosc13.56MHz。默认值TReloadHi0x00,TReloadVal0x00→ RF场无限开启易发热安全值TReloadHi0x01,TReloadVal0x2C→ 300×1/13.56MHz ≈ 22.1μs足够完成RequestA远距离读卡TReloadHi0x03,TReloadVal0x00→ 768×1/13.56MHz ≈ 56.6μs但需同步调高RxThreshold注意若TReload值过大如0x1000卡片可能在RF场关闭前未完成响应导致FIFOLevelReg读回0——此时应优先降低TReload而非增强发射功率。4.2 RxThreshold接收灵敏度的物理旋钮RxThreshold地址0x0C是8位寄存器控制接收器输入阈值电压。值越小灵敏度越高但噪声误触发风险越大RxThreshold值典型场景风险0x00~0x1F近距离读卡2cm易受电源纹波干扰FIFO中出现乱码0x20~0x4F标准距离2~5cm平衡灵敏度与抗噪性推荐初值0x320x50~0x7F远距离读卡5cm需配合增大TReload否则响应超时实测数据在PCB天线尺寸35mm×35mm、线圈Q值85条件下RxThreshold0x32可稳定读取NXP MIFARE Classic 1K卡UID 4字节在4.2cm距离误码率0.1%。4.3 TxControlReg天线驱动电流的精准调控TxControlReg地址0x14的bit1-bit0控制天线驱动电流强度00100%电流默认适合标准天线0175%电流降低EMI适合紧凑布局1050%电流超低功耗模式读卡距离缩短30%11保留关键技巧当多张卡片堆叠时设为01可减少邻卡干扰当读卡距离不足时先检查RxThreshold是否过低再尝试TxControlReg0x00100%电流而非盲目加大TReload——后者会延长RF开启时间增加功耗且未必提升距离。5. 排查FM17522“能通电但无任何响应”的5个硬件级断点与3个寄存器级验证法5.1 硬件断点用万用表和示波器直击信号链当MCU能正常烧录、SPI通信看似正常MOSI有波形但IRQ0Reg始终为0x00按以下顺序物理排查断点位置测试方法正常值异常表现RSTPD引脚电压万用表DC档测RSTPD对GND3.3V上拉后3.0V上拉电阻失效或MCU RST引脚漏电ANT1/ANT2交流电压示波器AC耦合测ANT1对ANT213.56MHz正弦波峰峰值≥1.2V无波形TxControlReg未置位或天线未焊接VDDA纹波示波器20MHz带宽测VDDA-GND50mVpp100mVppVDDA去耦电容失效导致ADC基准漂移CS信号时序逻辑分析仪抓CS-SCKCS低电平≥200ns高电平≥100nsCS脉宽150nsHAL库DMA导致时序压缩MISO数据有效性逻辑分析仪解码SPI帧读CommandReg返回0x0F复位中或0x00复位完成返回0xFFMISO线路虚焊或MCU引脚配置为开漏未上拉提示若ANT1/ANT2无13.56MHz波形立即检查TxControlReg是否写入0x03bit1-bit011且CommandReg是否执行过0x0C——仅写TxControlReg不会启动RF场。5.2 寄存器级验证三行代码确认芯片活性在完成硬件排查后用以下三步寄存器读写验证FM17522是否真正在线读VersionReg确认芯片型号FM17522_WriteRegister(PageSelectReg, 0x00); uint8_t ver FM17522_ReadRegister(VersionReg); // 应返回0x10FM17522若返回0x00或0xFF说明SPI通信物理层失败MISO断路或CS未生效。写CommandReg触发软复位并验证FM17522_WriteRegister(CommandReg, 0x0F); // 软复位 delay_ms(1); uint8_t cmd FM17522_ReadRegister(CommandReg); // 应返回0x00若仍为0x0F证明复位未执行——检查PageSelectReg是否被意外修改。读FIFOLevelReg验证FIFO状态机uint8_t fifo FM17522_ReadRegister(FIFOLevelReg); // 复位后应为0x00 FM17522_WriteRegister(FIFODataReg, 0xAA); // 写入测试字节 fifo FM17522_ReadRegister(FIFOLevelReg); // 应变为0x01若两次读值均为0x00说明FIFO写入失败——大概率是PageSelectReg未切回Bank0。5.3 绕过天线的终极验证用逻辑分析仪捕获RF场开关瞬间当所有寄存器读写正常但依然无法读卡最后手段是验证RF场是否真实开启将示波器探头接地端接GND尖端轻触ANT1焊盘不焊接触发条件设为“SCK上升沿”时基调至500ns/div执行FM17522_WriteRegister(CommandReg, 0x0C)后应看到13.56MHz正弦波突发burst持续时间由TReload决定若无突发波形问题100%在TxControlReg配置或天线匹配网络LC谐振电容是否为22pF此方法可排除90%的“软件正常但硬件无响应”故障比反复修改固件更高效。本文还有配套的精品资源点击获取
返回列表