资讯动态

STM8S105驱动RC522读卡:硬件接线、SPI通信与多卡调试详解

发布时间:2026/9/8 23:43:03 来源:尧图企业网站定制
简介面向嵌入式开发者的RC522射频模块测试程序基于STM8S105微控制器实现M1非接触式IC卡的ID读取并利用UART串口将卡片信息发送至上位机方便调试与监控。整个工程基于IAR Embedded Workbench环境构建代码注释较为详细并附带参考原理图能够帮助初学者快速理解RC522与STM8S105之间的硬件连接以及RFID寻卡、防碰撞、选卡、读卡等关键流程。资源包共120个文件以C源文件、头文件、链接配置文件、工程文件、十六进制固件等类型为主大小约2.04MB同时包含多个STM8S标准外设驱动模块覆盖定时器、串口等常用功能整体结构清晰便于直接导入IAR工程进行编译烧录。已有236人学习/下载对于希望入门STM8单片机与RFID应用或需要搭建RC522读写样例的开发者来说是一份兼具学习参考与实战价值的实用资料。 前两天整理开发资料库翻出一个RC522测试程序用的芯片是STM8S105整个工程打包成RC522测试程序-采用STM8S105.rar放在文件夹里快两年了。这个包当初是我做门禁读头样品时留的底子后来陆陆续续发过好几次给别人都是刚接触RC522模块、想先把卡号读出来的开发者。今天不藏私把里面的硬件接线、驱动逻辑、多卡识别处理和调试心得从头到尾捋一遍有需要的可以直接拿去做参考。1. 测试程序的功能边界为什么用STM8S105做RC522验证1.1 最小化验证从读卡号到读写块RC522是市面上最常见的13.56MHz RFID读写芯片支持ISO14443A协议Mifare S50、S70这类卡都能操作。STM8S105是意法半导体的8位MCU主频不高RAM和Flash都算不上宽裕但跑RC522这种轻量级读写协议绰绰有余。这套测试程序解决的核心问题只有一个让开发者在最短时间内确认“单片机能不能稳定读到卡号”。听起来很简单但实际要做到上电就出卡号、连续读不丢、串口输出可观测背后涉及到SPI通信、寄存器时序、防碰撞算法状态机好几个环节。很多人喜欢直接在STM32开发板上调RC522确实库多资料多但8位机上如果能把底层驱动写干净说明代码没有过度依赖高级外设库。测试程序设计上就是一个最小化验证工程主循环不断寻卡读到UID就通过串口打印同时点一个LED指示。硬件链路完整跑通之后再往上面加读块、写块、金额操作都顺理成章。1.2 代码目录设计与模块划分rar包里解压之后源码结构建议保持这几块平台初始化部分负责时钟、GPIO、UART调试口和SPI外设RC522底层驱动负责寄存器读写、PCD命令收发、软复位和天线开关卡片操作层负责寻卡、防碰撞、选卡、读取卡号主循环做业务调度也就是轮询寻卡和超时处理。这样分层的意义在于出了问题能快速定位是芯片级还是卡片级。我以前见过有人直接把网上STM32的RC522库整个粘到STM8工程里结果引脚定义对不上寄存器地址也因为芯片封装差异出现编译错误。测试程序虽然是工程压缩包但本质上更重要的是一套驱动逻辑。把SPI读写函数抽象出来把RC522寄存器和命令字用宏定义后续换MCU、换板子都能少踩一半的坑。2. 硬件连接与SPI通信原理先让板子说话2.1 RC522模块引脚与STM8S105的映射RC522模块常见引脚有8个SDA、SCK、MOSI、MISO、IRQ、RST、VCC、GND默认工作在SPI模式。这里SDA其实承担的就是片选CS功能。STM8S105的SPI1引脚会因为封装不同有差异我这里用过的板子是把PD2作为CS、PD3作为SCK、PD4作为MOSI、PD5作为MISO、PD6作为IRQ、PD7作为RSTVCC接3.3VGND共地。注意不同PCB设计完全可能不一样动手前一定要先查芯片数据手册和板子原理图别照着我的表直接乱接。SPI通信可以理解成一条带片选的生产线。NSS决定哪台设备在线上干活SCK是节拍器MOSI和MISO分别是两条方向相反的传送带。RC522作为从机只有在CS拉低的时候才响应主机的时钟和数据。STM8S105作为主机所有SCK、MOSI的操作都必须配合CS信号完成。2.2 SPI模式与电平匹配的取舍RC522的SPI支持模式0和模式3测试程序里我用的是模式0即CPOL0、CPHA0SCK空闲时低电平数据在第一个沿采样。对于8位MCU来说模式0的时序最简单逻辑分析仪抓波形也容易看懂。SPI时钟频率一开始不要贪高我用的是系统时钟16分频约1MHz。RC522本身支持10MHz的时钟但杜邦线下拉个1MHz最稳后面做产品再根据板子布线去提频。电平问题是新手最容易忽略的。RC522模块基本都是3.3V供电和3.3V逻辑有些STM8S105最小系统板虽然MCU是3.3V但板上带了5V转3.3V的稳压电路这时候如果再把5V接到RC522的VCC模块很可能直接烧掉。反过来如果MCU是5V供电且IO口不是容忍5V的那RC522的3.3V引脚可能被反向灌电流。稳妥做法是确认两边都是3.3V逻辑不给模块供电超过3.6V。3. 核心代码逐段拆解寻卡、防碰撞、多卡识别3.1 硬件SPI初始化与GPIO配置STM8S105的硬件SPI1初始化代码不长要点在软件NSS模式。我不用硬件自动片选而是把CS引脚当普通GPIO拉低拉高这样切换RC522和别的SPI设备更顺手也不会因为软件管理NSS没配置好出现时序错乱。初始化代码大概是void SPI1_Init(void) { SPI1_CR1 0x02; // 主模式CPOL0 SPI1_CR2 0x06; // 软件NSS8位数据 SPI1_CR1 | 0x10; // 使能SPI }这里要特别注意GPIO的模式。SCK和MOSI必须配置成推挽输出MISO配置成上拉输入。我之前在一个板子上把MOSI接到了开漏输出的引脚结果波形不对读卡时好时坏查了很久才发现是引脚复用模式的问题。测试程序里最好把每个引脚模式和复用功能写清楚不然换一块板子就抓瞎。3.2 RC522初始化寄存器时序RC522初始化做过的人都知道寄存器播放列表看着像天书实际上就是三件事复位芯片配置定时器打开天线。硬复位时RST引脚先拉低再拉高等一段时间再写软复位命令。然后是定时器配置TMode、TPrescaler、TReload这几个寄存器负责生成超时时间后续发送命令如果卡没响应不会像死循环一样卡住。天线控制寄存器TxControlReg要写0x83打开发射电路。很多测试程序跑不起来最后发现是天线没开信号根本发不出去。初始化完成后可以读VersionReg寄存器正常会返回0x92或0x91这个值是很好的自检点。我习惯在测试程序里加一个版本号读取如果读不到0x92大概率是SPI通信或者复位时序出了问题。3.3 读卡号主流程与多卡处理逻辑读卡号的核心三连是寻卡、防碰撞、选卡。寻卡命令用0x52或0x26卡片进入天线场区后会返回ATQA应答防碰撞命令是0x93加参数能拿到卡的4字节UID和一个校验字节选卡成功后卡片进入Active状态后面才能读写数据块。测试程序主循环里跑的也就是这套流程if (PcdRequest(0x52, atqa) OK) { if (PcdAnticoll(uid) OK) { PcdSelect(uid); UART_SendString(UID: ); for (i 0; i 4; i) UART_SendHex(uid[i]); } else { PcdReset(); } }这个代码里最容易被忽略的是PcdReset()。实测中防碰撞失败后RC522内部状态可能没清理干净如果直接发下一次命令会连续失败好几次甚至进入假死状态。做测试程序时宁可在失败分支里多花一点时间做复位也不要图省事跳过。多卡识别算是RC522应用里一个被反复问的问题。两张卡同时放在天线上面的时候RC522的防碰撞算法通过位帧检测来区分不同卡。但这不代表调用一次防碰撞就能连续把两张卡都读完。我的处理办法是每轮检测只拿一张卡拿到后可以对该卡执行Halt让其暂时离开场区然后继续下一轮寻卡或者干脆在每轮之间加20毫秒延时让用户把卡片拿开再放新卡。测试程序里真正的目标不是做一拖多读写器而是验证硬件在多卡场景下不崩溃能稳定回到寻卡状态。4. 调试现场实录读不到卡、乱码、多卡异常的排查4.1 三个高频问题和排查顺序先动手调RC522的时候遇到最多的是三种现象第一种是串口完全没反应寻卡永远失败第二种是偶尔能读出卡号但卡号里出现乱码第三种是两张卡放在一起时要么只能读一张要么直接死机。遇到这些问题我从来不去博客下面复制别人的答案而是按这个顺序排查先量电压确认RC522的VCC在3.3V附近RST引脚不是悬空状态再看SPI波形用逻辑分析仪抓SCK和MOSI确认主机确实把命令发出去了最后才怀疑卡片本身换一张S50白卡试。有段时间我的测试程序一直报寻卡超时折腾半天发现是手边那张门禁卡根本不是ISO14443A协议RC522压根不认识它。所以测试卡一定用标签初始的Mifare S50白卡别拿电梯卡、门禁卡来试。4.2 SPI不稳定与电源干扰的实战心得读卡偶尔成功偶尔失败先不要怀疑算法多半是物理层面的干扰。杜邦线超过15厘米SPI时钟再提到4MHz波形就已经畸变得没法看了。把SPI分频调低线束缩短到10厘米以内两个地连在一起问题马上缓解。另一个容易被忽略的是电源。RC522天线发射瞬间电流不小如果模块供电靠的是单片机板子上的线性稳压器电流不足时电压会跌落卡片应答信号就会忽强忽弱。我是直接在模块VCC和GND之间并了一个10uF电解电容和一个0.1uF陶瓷电容效果好很多。读卡号出现乱码还有一个细节STM8S105的SPI接收数据后如果没及时读取硬件会产生溢出错误后续数据全乱。测试程序里每次SPI读写完都检查一下SPI_SR的OVR标志被发现溢出就清理掉。这个坑在寄存器手册里写得很含蓄但实际非常常见。4.3 常见问题速查表这里把我在调试过程中积累的排查经验整理成一个表格方便直接对照处理。现象可能原因解决办法寻卡一直超时卡片不在场区、天线未打开、卡类型不兼容确认用S50白卡、读VersionReg、检查RST时序偶尔读到卡号且乱码SPI速率过高、接线过长、电源纹波大降低SPI分频、缩短杜邦线、模块电源并电容两张卡同时放只能读一张天线场区能量不足、防碰撞后状态未清理卡片分开放置、失败后PcdReset、加延时重试程序跑一段时间死机RC522内部状态错乱、SPI溢出未处理失败分支做软复位、每次SPI通信后清OVR标志5. 工程环境搭建与跨芯片移植5.1 把rar里的工程跑起来拿到RC522测试程序-采用STM8S105.rar之后第一步不是双击工程文件而是先确认自己的编译环境。我当时用的是IAR for STM8也有用STVD的老项目。打开工程后先检查芯片型号是不是自己的具体封装比如STM8S105K6和STM8S105C6的Flash、RAM一样但引脚映射不同编译出来烧进去效果也会不一样。头文件路径里如果看不到stm8s.h说明环境没有配置好。编译通过后下载建议直接用ST-Link便宜稳定。没有ST-Link的话串口ISP也可以但需要板子出厂带Bootloader。第一次跑测试程序不要急着看读卡先把一个GPIO翻转的例程烧进去点上LED确认编译器、下载器、烧录链路全通再接RC522模块。这样可以把“环境问题”和“硬件问题”隔离开。5.2 从STM8S105移植到STM32的底层替换这个测试程序虽然是给STM8S105写的但网上搜“rc522读写卡程序stm32”的人非常多其实移植也很简单。上层的PcdRequest、PcdAnticoll、PcdSelect全部不用动要换的只有SPI底层读写函数和引脚宏定义。只要把原来操作SPI1_DR的代码换成STM32的HAL库或标准库的SPI发送接收函数再把CS、RST这些引脚对应到STM32的GPIO口编译就能跑。我自己从STM8S105迁到STM32F103只改了一个底层文件半小时点亮串口。移植的时候我建议把所有片选引脚、RST引脚、SPI外设都用宏定义包起来比如#define RC522_CS_LOW() GPIO_ResetBits(GPIOB, GPIO_Pin_12) #define RC522_CS_HIGH() GPIO_SetBits(GPIOB, GPIO_Pin_12) #define RC522_RST_LOW() GPIO_ResetBits(GPIOB, GPIO_Pin_13) #define RC522_RST_HIGH() GPIO_SetBits(GPIOB, GPIO_Pin_13)这样后面换任何一个引脚只改宏定义不用动函数内部逻辑。5.3 扩展方向与个人体会如果你不满足于只读卡号这个工程可以继续加东西。RC522支持对Mifare卡进行KeyA/KeyB鉴权鉴权通过后可以读整个扇区、写数据块甚至可以做一个简易的电子钱包逻辑。我后来把读卡号改成了中断触发用RC522的IRQ引脚唤醒STM8S105平时单片机睡在低功耗模式卡片靠近才醒来处理。测试程序的轮询逻辑换成中断驱动也只是一层壳的问题。调试RC522这类射频模块最忌心急。很多时候程序没问题是天线位置压着了或者隔壁桌开关电源在干扰。我的经验是先在干净的环境下把卡片垂直放在模块正上方读出稳定卡号之后再测试多卡、远近、角度这些变量。射频的东西硬件状态对结果的影响远大于那几行代码。顺便说一句如果用的是那种小板载天线的一体化RC522模块测试时千万别把它贴在金属桌面上否则读卡距离会从五厘米直接缩水到一厘米。这个细节我吃了两次亏提醒一下后来人。本文还有配套的精品资源点击获取

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

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

免费获取报价