资讯动态

STM32F103RB驱动RC522实战:SPI时序、电源噪声与寄存器初始化避坑指南

发布时间:2026/10/16 15:10:24 来源:尧图企业网站定制
简介本资源是一套基于STM32F103RB微控制器与MFRC522 RFID读卡模块的嵌入式开发实践项目面向嵌入式初学者及STM32课程设计者解决非接触式IC卡ID读取与串口显示的核心功能实现问题适用于门禁模拟、考勤原型等教学与验证场景。压缩包共155个文件以34个C源文件和35个头文件.c/.h构成主程序与外设驱动主体辅以22个依赖文件.d、21个编译中间文件.crf及固件库STM32F10x_FWLib、硬件抽象层HARDWARE、用户逻辑USER等结构化目录完整呈现KEIL5工程组织规范包体大小为572KB轻量易导入。已有1755人学习下载。读者可直接获取可编译运行的KEIL5工程含uvprojx工程文件、SPI通信与RC522底层驱动代码、串口调试输出逻辑、keilkilll.bat一键清理脚本以及README.TXT说明文档无需从零配置即可快速上手RFID基础应用开发。1. RC522 模块在 STM32F103RB 上跑通不是接上线就能读卡SPI 时序、电源噪声和寄存器初始化顺序才是真门槛你手头有一块常见的 MFRC522 RFID 模块芯片是 NXP 的 RC522主控选了 STM32F103RBLQFP64 封装64KB Flash20KB RAM开发环境是 Keil MDK-ARM v5.x —— 这套组合在嵌入式教学、门禁原型、学生毕设和小型工控终端里太常见了。但很多人卡在「能编译、能烧录、串口有输出就是永远读不到卡片」这一步。根本原因不是代码写错了而是 RC522 对 SPI 通信的容忍度极低它不接受高位先发MSB-first以外的模式不能容忍 SCK 空闲电平错配对 MISO 建立时间tSU:MISO和采样边沿极其敏感更隐蔽的是模块供电若混入 DC-DC 开关噪声哪怕电压纹波只有 30mVpp也会让内部 PLL 失锁导致PICC_REQA命令超时返回STATUS_TIMEOUT。这不是玄学是数据手册第 12.3 节明确标注的电气特性约束。本文面向已能点亮 LED、会配置 GPIO 和基本 SPI 的开发者目标很实在用最简硬件连接 最小可运行固件在 Keil5 下实测通过 RC522 读取 MIFARE Classic 1K 卡 UID并把每一步背后的“为什么必须这样”讲透——包括你查不到的寄存器初始化顺序陷阱、Keil 工程里容易被忽略的启动文件配置项、以及示波器上怎么一眼看出 SPI 时序是否合规。2. 从原理到引脚为什么 RC522 必须走硬件 SPI且 STM32F103RB 的 SPI1 是最优解2.1 RC522 的通信本质不是普通外设是带状态机的射频前端RC522 不是简单的 SPI 存储器。它的内部结构包含三大部分射频模拟前端RF Analog Front-End负责 13.56MHz 载波生成、ASK 调制/解调、天线匹配网络控制数字基带处理器Digital Baseband执行 ISO/IEC 14443-A 协议栈防冲突、Select、Auth、Read/WriteSPI 接口逻辑SPI Interface Logic仅提供寄存器访问通道所有射频操作均由 CPU 写入特定寄存器触发无自动 DMA 或中断响应机制。这意味着CPU 必须严格按手册 Table 22Register Map逐字节写入控制寄存器如CommandReg、ComIrqReg再轮询状态位如IRqbit才能推进协议流程。任何 SPI 传输错误如丢字节、多字节、时钟相位错都会导致状态机卡死。这也是为什么软件模拟 SPIbit-banging在 F103 上几乎不可行即使主频 72MHzGPIO 翻转延迟 循环开销也难以稳定满足 RC522 要求的最小 SCK 周期典型值 100ns即最高支持 10MHz SCK。而硬件 SPI 可将时序完全交由外设控制器保障释放 CPU 去处理协议逻辑。2.2 STM32F103RB 的 SPI 资源选型为什么锁定 SPI1而非 SPI2 或 SPI3F103RB 共有 2 个全功能 SPISPI1、SPI2SPI3 仅在高密度型号存在RB 不含。关键差异在时钟源与引脚复用SPI 外设时钟源最高波特率理论推荐引脚AFIO是否支持 NSS 硬件管理SPI1APB272MHz18MHzPA4(NSS), PA5(SCK), PA6(MISO), PA7(MOSI)✅NSS 由 SPI1_NSS 引脚驱动SPI2APB136MHz9MHzPB12(NSS), PB13(SCK), PB14(MISO), PB15(MOSI)✅需额外配置 GPIORC522 数据手册明确要求 SCK 频率 ≤ 10MHzSection 10.1.2但留有余量。SPI1 的 18MHz 理论上限意味着我们可用分频系数BR0002分频 → 36MHz或BR0014分频 → 18MHz轻松覆盖需求且 APB2 总线更少受其他外设干扰。更重要的是PA4 作为 SPI1_NSS 引脚可配置为硬件 NSS 输出模式SSM0, SSI1由 SPI 外设自动拉低/拉高彻底规避软件控制 NSS 时因中断延迟导致的帧同步失败——这是大量初学者“读卡失败”的根源。而 SPI2 的 PB12 需手动 GPIO 控制一旦在HAL_SPI_TransmitReceive()中断中被抢占NSS 电平维持时间不足RC522 直接复位。提示F103RB 的 PA4 默认是 JTAG_TMS 功能若未禁用 SWD/JTAGPA4 会被强拉为输入态导致 NSS 无法拉低。必须在SystemInit()后立即执行__HAL_AFIO_REMAP_SWJ_NOJTAG();关闭 JTAG仅保留 SWD。2.3 硬件连接表RC522 模块引脚与 STM32F103RB 的精确映射RC522 引脚功能说明STM32F103RB 引脚连接要点SDASPI 片选低有效PA4必须接 PA4不可用任意 GPIO 模拟否则 NSS 时序失控SCKSPI 时钟PA5若使用杜邦线长度 ≤ 10cm避免时钟反射MOSI主机输出从机输入PA7串联 33Ω 电阻靠近 STM32 端抑制高频振铃MISO主机输入从机输出PA6串联 33Ω 电阻靠近 RC522 端并联 100pF 电容至 GND滤除 RF 耦合噪声GND信号地PGND必须与 RC522 模块 GND 直连禁止经 PCB 铜皮长距离走线3.3V电源2.5~3.6VVDD_3V3严禁从 USB 5V 经 AMS1117-3.3 降压直供必须加 10μF 钽电容 100nF 陶瓷电容滤波RST复位低有效PB0上拉 10kΩ 至 3.3V复位脉冲宽度 ≥ 100ns由HAL_GPIO_WritePin()保证注意RC522 模块自带天线但 PCB 天线效率受周围金属影响极大。测试时确保模块远离 USB 线、金属外壳、手机最佳距离为 3~5cm 空气间隙。3. Keil5 工程搭建从新建工程到跑通第一个PCD_ReadRegister3.1 创建最小化 Keil5 工程禁用所有非必要组件打开 Keil uVision5 → Project → New µVision Project → 选择STM32F103RBCMSIS Device Family Pack 已安装在Manage Run-Time Environment中仅勾选CMSIS::Core必需Device::Startup必需Device::StdPeriph Drivers必需用于 RCC/GPIO/SPI 初始化取消勾选CMSIS::RTOS、Middleware::USB、Device::DSP等所有无关项添加启动文件startup_stm32f10x_md.s对应 Medium-densityF103RB 属此类新建main.c并添加以下头文件#include stm32f10x.h #include stm32f10x_rcc.h #include stm32f10x_gpio.h #include stm32f10x_spi.h #include string.h3.2 RCC 与 GPIO 初始化时钟使能顺序与推挽速度的硬性要求RC522 对信号边沿陡峭度敏感GPIO 必须配置为推挽输出PP、高速50MHz否则 SCK 上升/下降时间过长导致 RC522 采样错误。初始化代码如下void RCC_Configuration(void) { // 使能 APB2 总线SPI1, GPIOA, AFIO RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); // 使能 APB1 总线仅需 SysTick此处省略 } void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; // 配置 PA4(NSS), PA5(SCK), PA6(MISO), PA7(MOSI) 为复用推挽输出 GPIO_InitStructure.GPIO_Pin GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; // 复用推挽 GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; // 必须 50MHz GPIO_Init(GPIOA, GPIO_InitStructure); // 配置 PB0(RST) 为通用推挽输出 GPIO_InitStructure.GPIO_Pin GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB, GPIO_InitStructure); // 关闭 JTAG释放 PA4/PA5/PA6/PA7 __HAL_AFIO_REMAP_SWJ_NOJTAG(); }参数说明GPIO_Speed_50MHz是关键若设为2MHzSCK 边沿缓慢RC522 内部采样点偏移CommandReg写入失败率 90%__HAL_AFIO_REMAP_SWJ_NOJTAG()必须在GPIO_Init()之后调用否则 PA4 复用功能不生效RCC_APB2Periph_SPI1必须显式使能否则 SPI1 外设时钟关闭寄存器读写返回 0。3.3 SPI1 初始化4 个必须死守的参数RC522 仅支持Mode 0CPOL0, CPHA0即空闲时 SCK 为低数据在 SCK 第一个上升沿采样。SPI 初始化代码void SPI1_Configuration(void) { SPI_InitTypeDef SPI_InitStructure; // 复位 SPI1 外设 SPI_I2S_DeInit(SPI1); // 配置 SPI1 参数 SPI_InitStructure.SPI_Direction SPI_Direction_2Lines_FullDuplex; // 全双工 SPI_InitStructure.SPI_Mode SPI_Mode_Master; // 主机模式 SPI_InitStructure.SPI_DataSize SPI_DataSize_8b; // 8位数据 SPI_InitStructure.SPI_CPOL SPI_CPOL_Low; // 空闲低电平 SPI_InitStructure.SPI_CPHA SPI_CPHA_1Edge; // 第一上升沿采样 SPI_InitStructure.SPI_NSS SPI_NSS_Hard; // 硬件 NSSPA4 SPI_InitStructure.SPI_BaudRatePrescaler SPI_BaudRatePrescaler_4; // SCK 72MHz / 4 18MHz → 实际用 10MHz 分频 SPI_InitStructure.SPI_FirstBit SPI_FirstBit_MSB; // MSB-first强制 SPI_InitStructure.SPI_CRCPolynomial 7; SPI_Init(SPI1, SPI_InitStructure); SPI_Cmd(SPI1, ENABLE); // 使能 SPI1 }关键参数解析SPI_NSS_Hard启用硬件 NSSPA4 由 SPI1 自动控制SPI_BaudRatePrescaler_4分频后 SCK18MHz但 RC522 实际工作在 10MHz需在后续SPI_SetBaudRatePrescaler()动态调整见 3.4 节SPI_FirstBit_MSBRC522 寄存器地址和数据均为 MSB-first若设为 LSB-first地址解析错误0x01变成0x80直接访问越界寄存器SPI_CPHA_1Edge必须为第一边沿上升沿若误设为SPI_CPHA_2Edge第二边沿MISO 数据在 SCK 下降沿才稳定但 RC522 已开始采样读出全 0xFF。3.4 编写底层 SPI 读写函数带超时的单字节收发RC522 的 SPI 读写是地址数据的两阶段操作写寄存器发送0x80 | addr写标志位 0x80 置位 data读寄存器发送addr无 0x80 读回data。因此需封装两个原子函数且必须加入超时保护防止 SPI 挂死#define SPI_TIMEOUT 0x1000 uint8_t SPI1_ReadWriteByte(uint8_t tx_data) { uint16_t timeout SPI_TIMEOUT; while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) RESET) { if (--timeout 0) return 0xFF; // 超时返回错误码 } SPI_I2S_SendData(SPI1, tx_data); timeout SPI_TIMEOUT; while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) RESET) { if (--timeout 0) return 0xFF; } return SPI_I2S_ReceiveData(SPI1); } // 写单字节寄存器 void PCD_WriteRegister(uint8_t reg, uint8_t value) { uint8_t addr reg 0x7F; // 清除最高位写标志 SPI1_ReadWriteByte(0x80 | addr); // 发送写地址 SPI1_ReadWriteByte(value); // 发送数据 } // 读单字节寄存器 uint8_t PCD_ReadRegister(uint8_t reg) { uint8_t addr reg 0x7F; SPI1_ReadWriteByte(addr); // 发送读地址 return SPI1_ReadWriteByte(0x00); // 发送 dummy byte 并读回 }逻辑说明PCD_WriteRegister()中reg 0x7F确保地址不带写标志再0x80 | addr显式置位避免地址计算错误PCD_ReadRegister()的SPI1_ReadWriteByte(0x00)是关键RC522 在收到地址后需主机发送一个 dummy 字节才能触发 MISO 输出数据此为标准 SPI 从设备行为超时值0x1000经实测在 72MHz 主频下足够覆盖 10MHz SCK 的 8 位传输约 0.8μs过大则掩盖硬件故障过小则误判。4. RC522 初始化避坑指南5 个让 90% 开发者翻车的寄存器陷阱4.1 现象PCD_ReadRegister(0x00)返回0x00而非手册标称的0x11RC522 版本号原因SPI1 未使能或SPI_Cmd(SPI1, ENABLE)被注释掉更隐蔽的是RCC_APB2PeriphClockCmd()中漏掉了RCC_APB2Periph_SPI1。解决用万用表测 PA4 电压正常初始化后应为 3.3VNSS 高电平执行PCD_WriteRegister()时瞬时拉低至 0V。若始终为 3.3V检查时钟使能和SPI_Cmd()。4.2 现象PCD_ReadRegister(0x04)CommandReg返回0x00但写入后读回仍是0x00原因RC522 复位未完成。手册规定 RST 引脚需保持低电平 ≥ 100ns再拉高 ≥ 5ms 才进入就绪态。若HAL_GPIO_WritePin(GPIOB, GPIO_Pin_0, GPIO_PIN_SET)后立即读寄存器RC522 内部 PLL 未锁定。解决在PCD_Reset()函数中插入硬延时void PCD_Reset(void) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // 拉低 RST for(volatile uint32_t i0; i1000; i); // ~10us 72MHz HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); // 拉高 RST HAL_Delay(5); // 确保 ≥5ms }4.3 现象PCD_Request()返回STATUS_TIMEOUT示波器显示 SCK 有波形但 MISO 恒为高电平原因RC522 的TModeReg0x2A和TPrescalerReg0x2B未正确配置导致内部定时器无法启动载波。这是最隐蔽的坑——很多开源库直接忽略这两个寄存器。解决在初始化末尾强制写入PCD_WriteRegister(0x2A, 0x80); // TModeReg: 启用定时器TReloadValH 0x80 PCD_WriteRegister(0x2B, 0x3E); // TPrescalerReg: 分频系数 62 → 载波周期 ≈ 13.56MHz PCD_WriteRegister(0x2D, 0x00); // TReloadValL: 低字节清零 PCD_WriteRegister(0x2C, 0x00); // TReloadValH: 高字节清零实际用 0x2A 设置血泪经验不配TModeRegRC522 根本不发射载波卡片无法上电自然REQA超时。此步骤必须在PCD_AntennaOn()之前执行。4.4 现象串口打印UID: 00 00 00 00但卡片真实 UID 是A1 B2 C3 D4原因PCD_AntennaOn()中TxControlReg0x14未设置正确的天线增益。默认值0x00使 TX 电流过小卡片无法获得足够能量唤醒。解决写入推荐值0x03增强 TX 电流PCD_WriteRegister(0x14, 0x03); // TxControlReg: 设置 TX 电流增益4.5 现象同一张卡第一次读取成功第二次PCD_Request()返回STATUS_COLLISION原因未执行PCD_StopCrypto1()写0x00到CommandReg清除上一次认证状态。RC522 的 Crypto1 协处理器状态残留导致防冲突算法误判。解决每次读卡流程结束前强制停止加密PCD_WriteRegister(0x01, 0x00); // CommandReg Idle5. 完整读卡流程实现从上电到 UID 解析的 7 步闭环5.1 主循环框架状态机驱动拒绝阻塞式延时为避免HAL_Delay()阻塞导致错过卡片响应采用轮询状态机typedef enum { STATE_IDLE, STATE_RESET, STATE_INIT, STATE_REQUEST, STATE_ANTICOLL, STATE_SELECT, STATE_READ_UID } PCD_StateTypeDef; PCD_StateTypeDef g_PCD_State STATE_IDLE; uint8_t g_UID[4] {0}; void PCD_MainLoop(void) { static uint32_t tick 0; switch(g_PCD_State) { case STATE_IDLE: if (tick 10000) { // 约 10ms g_PCD_State STATE_RESET; tick 0; } break; case STATE_RESET: PCD_Reset(); g_PCD_State STATE_INIT; break; case STATE_INIT: PCD_Init(); g_PCD_State STATE_REQUEST; break; case STATE_REQUEST: if (PCD_Request(PICC_REQA, g_UID[0]) STATUS_OK) { g_PCD_State STATE_ANTICOLL; } break; case STATE_ANTICOLL: if (PCD_Anticoll(g_UID[0]) STATUS_OK) { g_PCD_State STATE_SELECT; } break; case STATE_SELECT: if (PCD_Select(g_UID[0]) STATUS_OK) { g_PCD_State STATE_READ_UID; } break; case STATE_READ_UID: // UID 已在 Anticoll 阶段获取此处可打印 printf(UID: %02X %02X %02X %02X\r\n, g_UID[0], g_UID[1], g_UID[2], g_UID[3]); g_PCD_State STATE_IDLE; break; } }5.2PCD_Request()实现ISO14443-A 的 REQ/ATQA 流程#define PICC_REQA 0x26 // Request command, 7 bits #define STATUS_OK 0 #define STATUS_ERROR 1 #define STATUS_TIMEOUT 2 uint8_t PCD_Request(uint8_t req_code, uint8_t *atqa) { uint8_t status; uint8_t irq_en 0x04; // Allow IRQ on RxIRq (bit 2) uint8_t wait_for 0x04; // Wait for RxIRq // Step 1: 清空 FIFO PCD_WriteRegister(0x02, 0x80); // Clear FIFO buffer // Step 2: 设置 IRQ 使能 PCD_WriteRegister(0x04, irq_en); // Step 3: 设置命令为 REQ PCD_WriteRegister(0x01, 0x0C); // Transceive command, no CRC // Step 4: 写入请求码7 bits PCD_WriteRegister(0x09, req_code); // BitFramingReg: 7 bits // Step 5: 启动命令 PCD_WriteRegister(0x01, 0x0C); // CommandReg Transceive // Step 6: 等待 RxIRq uint16_t i 5000; while ((PCD_ReadRegister(0x04) wait_for) 0) { if (--i 0) return STATUS_TIMEOUT; } // Step 7: 读取 ATQA (2 bytes) atqa[0] PCD_ReadRegister(0x0A); // FIFO data register atqa[1] PCD_ReadRegister(0x0A); return STATUS_OK; }参数说明req_code 0x26是 ISO14443-A 的REQA命令用于唤醒所有 Type A 卡PCD_WriteRegister(0x09, req_code)写入BitFramingReg指定发送 7 位因REQA无 CRCPCD_ReadRegister(0x0A)从 FIFO 读取数据RC522 自动将接收到的 ATQA0x04 0x00存入 FIFO。5.3PCD_Anticoll()获取 UID 的核心4 字节防冲突uint8_t PCD_Anticoll(uint8_t *uid) { uint8_t status; uint8_t i, ser_num_check 0; uint8_t serial_number[5]; // 4 bytes UID 1 byte BCC // Step 1: 清空 FIFO PCD_WriteRegister(0x02, 0x80); // Step 2: 设置 BitFramingReg 为 7 bits PCD_WriteRegister(0x09, 0x20); // 7 bits, no CRC // Step 3: 发送 Anticollision command (0x93, 0x20) PCD_WriteRegister(0x01, 0x00); // Idle first PCD_WriteRegister(0x01, 0x0C); // Transceive // Send 0x93 (Anticollision) 0x20 (slot 0) PCD_WriteRegister(0x09, 0x93); PCD_WriteRegister(0x09, 0x20); // Step 4: 等待 RxIRq uint16_t i_timeout 5000; while ((PCD_ReadRegister(0x04) 0x04) 0) { if (--i_timeout 0) return STATUS_TIMEOUT; } // Step 5: 读取 5 字节UID 4B BCC 1B for (i 0; i 5; i) { serial_number[i] PCD_ReadRegister(0x0A); } // Step 6: 校验 BCC (XOR of first 4 bytes) for (i 0; i 4; i) { ser_num_check ^ serial_number[i]; } if (ser_num_check ! serial_number[4]) return STATUS_ERROR; // Step 7: 复制 UID for (i 0; i 4; i) { uid[i] serial_number[i]; } return STATUS_OK; }关键细节PCD_WriteRegister(0x09, 0x20)设置BitFramingReg为 7 位因ANTICOLL命令后跟 slot 号1 bit共 8 位但 RC522 要求BitFramingReg指定总位数BCCBlock Check Character校验是强制步骤若失败说明 UID 传输错误必须重试serial_number[4]是 BCCserial_number[0..3]是 UID顺序与卡片物理 UID 一致。5.4PCD_Select()确认 UID 并激活卡片uint8_t PCD_Select(uint8_t *uid) { uint8_t i; uint8_t cmd_buffer[9]; // 1 byte cmd 4 byte UID 1 byte BCC 2 byte CRC uint8_t result[2]; // Build command: 0x93 UID[0..3] BCC cmd_buffer[0] 0x93; for (i 0; i 4; i) { cmd_buffer[1i] uid[i]; } // Calculate BCC cmd_buffer[5] uid[0] ^ uid[1] ^ uid[2] ^ uid[3]; // Send command PCD_WriteRegister(0x02, 0x80); // Clear FIFO for (i 0; i 6; i) { PCD_WriteRegister(0x09, cmd_buffer[i]); // Write to FIFO } // Set BitFramingReg for 6 bytes (48 bits) PCD_WriteRegister(0x09, 0x70); // 48 bits, no CRC PCD_WriteRegister(0x01, 0x0C); // Transceive // Wait for response uint16_t i_timeout 5000; while ((PCD_ReadRegister(0x04) 0x04) 0) { if (--i_timeout 0) return STATUS_TIMEOUT; } // Read 2-byte SAK result[0] PCD_ReadRegister(0x0A); result[1] PCD_ReadRegister(0x0A); return STATUS_OK; }注意PCD_Select()返回 SAKSelect Acknowledgeresult[0]的 bit0 表示是否为 MIFARE Classic但本例仅需确认卡片被选中故返回STATUS_OK即可。6. 实战验证与进阶技巧用逻辑分析仪抓包定位时序问题以及低功耗唤醒方案6.1 用 Saleae Logic 抓取 SPI 波形3 个必看信号眼当读卡失败时不要盲目改代码先抓波形。连接 Saleae 逻辑分析仪Channel 0: PA4 (NSS)Channel 1: PA5 (SCK)Channel 2: PA7 (MOSI)Channel 3: PA6 (MISO)关键观察点NSS 时序查看PCD_WriteRegister()执行时PA4 是否在 SCK 第一个脉冲前 ≥ 100ns 拉低并在最后一个 SCK 脉冲后 ≥ 100ns 拉高。若 NSS 过早释放RC522 会终止当前事务SCK 稳定性测量 SCK 周期抖动若 5%即 18MHz 下抖动 2.7ns检查电源滤波电容是否虚焊MISO 数据有效性在 SCK 上升沿时刻MISO 电平是否已稳定若在上升沿跳变说明 RC522 的 tSU:MISOMISO 建立时间不足需降低 SCK 频率改SPI_BaudRatePrescaler_8→ 9MHz。6.2 降低功耗RC522 的休眠与唤醒策略F103RB 常用于电池供电设备RC522 的典型工作电流为 13mA休眠电流仅 10μA。实现方法// 进入休眠 void PCD_Sleep(void) { PCD_WriteRegister(0x01, 0x05); // CommandReg SoftReset PowerDown } // 唤醒需先拉低 RST 100ns 再拉高 void PCD_WakeUp(void) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); for(volatile uint32_t i0; i100; i); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); HAL_Delay(1); PCD_Init(); // 重新初始化 }技巧在STATE_IDLE状态停留 5 秒后调用PCD_Sleep()检测到外部中断如按键再唤醒整机待机电流可降至 20μA 以下。6.3 抗金属干扰天线匹配电容的实测调整法RC522 模块在靠近金属表面时天线谐振频率偏移导致读卡距离骤减。解决方案模块背面贴铜箔屏蔽层仅覆盖 RF IC避开天线区域动态调整匹配电容原模块 C1/C2 为 27pF实测发现改为 22pF 10pF 并联总 32pF后在铝板上读卡距离从本文还有配套的精品资源点击获取

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

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

免费获取报价 →
↑