用STM32F103C8T6和RC522做个桌面小玩意:刷卡显示卡号到OLED屏幕(附完整代码)

张开发
2026/4/16 7:34:19 15 分钟阅读

分享文章

用STM32F103C8T6和RC522做个桌面小玩意:刷卡显示卡号到OLED屏幕(附完整代码)
STM32与RC522打造智能卡片信息显示器从零开始的趣味电子项目1. 项目构思与硬件准备在电子创客的世界里将日常物品智能化总能带来意想不到的乐趣。这次我们要用STM32F103C8T6开发板、RC522射频识别模块和OLED显示屏打造一个可以读取并显示卡片信息的桌面小装置。这个项目不仅能让你了解RFID技术的工作原理还能收获一个实用又有趣的桌面摆件。所需材料清单STM32F103C8T6最小系统板蓝色药丸开发板RC522 RFID读卡模块含S50白卡和钥匙扣卡0.96寸SPI接口OLED显示屏杜邦线若干建议使用母对母和公对母组合USB转TTL串口模块如CH340面包板或洞洞板可选用于固定元件微型螺丝刀套装用于调整电位器提示购买RC522模块时通常附带S50白卡和钥匙扣卡如果没有可以单独购买。OLED显示屏建议选择四针SPI接口的型号市面上常见的有SSD1306驱动芯片的版本。硬件连接是项目成功的第一步我们需要特别注意各模块之间的引脚对应关系。以下是详细的连接指南STM32引脚RC522模块OLED显示屏功能说明PB0RST-复位信号PA4SDA-数据线PA5SCKSCK时钟信号PA7MOSISDA主出从入PA6MISO-主入从出3.3V3.3VVCC电源正极GNDGNDGND电源地PB8-SCKOLED时钟PB9-SDAOLED数据2. 开发环境搭建与基础配置工欲善其事必先利其器。在开始编码前我们需要搭建合适的开发环境。对于STM32开发Keil MDK是经典选择但这里我推荐使用更现代的PlatformIO配合VS Code它能提供更好的代码管理和库支持。开发环境配置步骤安装VS Code并添加PlatformIO插件创建新的STM32F103C8T6项目在platformio.ini中添加必要的库依赖[env:bluepill_f103c8] platform ststm32 board bluepill_f103c8 framework libopencm3 lib_deps adafruit/Adafruit SSD1306^2.5.7 miguelbalboa/rfid^1.4.9配置串口调试工具如Putty或PlatformIO的串口监视器RFID模块的初始化是项目成功的关键。RC522模块通过SPI接口与STM32通信我们需要正确配置相关参数void MFRC522_Init(void) { // 初始化GPIO和SPI rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_GPIOB); // 配置RC522引脚 gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO4); // SDA gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO5); // SCK gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO7); // MOSI gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO6); // MISO // 复位RC522 gpio_set(GPIOB, GPIO0); // RST高电平 delay_ms(10); gpio_clear(GPIOB, GPIO0); // RST低电平 delay_ms(10); gpio_set(GPIOB, GPIO0); // RST高电平 delay_ms(10); MFRC522_Reset(); }3. RFID读取功能实现理解了硬件连接和基础配置后我们进入核心功能开发阶段——卡片信息的读取与处理。RC522模块支持ISO/IEC 14443 Type A协议能够读取MIFARE Classic系列的卡片。卡片读取流程发送寻卡指令0x26或0x52防冲突处理获取卡片序列号选择卡片进行通信验证卡片密钥如果需要访问数据块读取或写入数据块以下是实现卡片检测和序列号读取的关键代码uint8_t detect_card(uint8_t *serial) { uint8_t status; uint8_t buffer[2]; // 寻卡 status MFRC522_Request(PICC_REQIDL, buffer); if(status ! MI_OK) { return 0; // 未检测到卡片 } // 防冲突获取序列号 status MFRC522_Anticoll(serial); if(status ! MI_OK) { return 0; } // 检查序列号校验和 uint8_t checksum 0; for(uint8_t i0; i4; i) { checksum ^ serial[i]; } if(checksum ! serial[4]) { return 0; } return 1; // 成功读取卡片 }在实际应用中我们可能需要对不同类型的卡片进行区分。常见的MIFARE卡片类型可以通过ATQA和SAK响应来识别卡片类型ATQASAK容量MIFARE Classic 1K0x00040x081KBMIFARE Classic 4K0x00020x184KBMIFARE Ultralight0x00440x0064BMIFARE DESFire0x03440x20可变4. OLED显示界面设计有了卡片数据后我们需要一个直观的方式来展示这些信息。0.96寸OLED显示屏虽然小巧但足以清晰显示卡片的关键信息。我们将设计一个简洁明了的用户界面。显示布局规划----------------------- | RFID Card Reader | -- 标题栏 ----------------------- | Card Type: MIFARE 1K | -- 卡片类型 | UID: 12 34 56 78 | -- 卡片序列号 | Last Seen: 12:30:45 | -- 最后读取时间 ----------------------- | Place your card... | -- 状态提示 -----------------------实现这一界面需要OLED显示屏的驱动代码。我们使用Adafruit SSD1306库来简化开发void display_card_info(uint8_t *uid, uint8_t uid_len) { char buffer[20]; // 清屏 oled_clear(); // 显示标题 oled_draw_string(0, 0, RFID Card Reader, FONT_SIZE_LARGE, WHITE); // 显示卡片类型 oled_draw_string(0, 2, Card Type:, FONT_SIZE_SMALL, WHITE); sprintf(buffer, MIFARE %s, uid_len4?1K:4K); oled_draw_string(60, 2, buffer, FONT_SIZE_SMALL, WHITE); // 显示UID oled_draw_string(0, 3, UID:, FONT_SIZE_SMALL, WHITE); sprintf(buffer, %02X %02X %02X %02X, uid[0], uid[1], uid[2], uid[3]); oled_draw_string(30, 3, buffer, FONT_SIZE_SMALL, WHITE); // 显示时间 oled_draw_string(0, 4, Last Seen:, FONT_SIZE_SMALL, WHITE); sprintf(buffer, %02d:%02d:%02d, hours, minutes, seconds); oled_draw_string(70, 4, buffer, FONT_SIZE_SMALL, WHITE); // 状态提示 oled_draw_string(0, 6, Place your card..., FONT_SIZE_SMALL, WHITE); // 更新显示 oled_update(); }为了提升用户体验我们可以添加一些视觉反馈效果。例如当检测到卡片时让屏幕短暂反色显示void show_detection_effect() { // 反色显示 oled_invert_display(true); delay_ms(200); oled_invert_display(false); // 添加边框动画 for(uint8_t i0; i3; i) { oled_draw_rect(0, 0, 127, 63, WHITE); oled_update(); delay_ms(50); oled_draw_rect(0, 0, 127, 63, BLACK); oled_update(); delay_ms(50); } }5. 项目优化与功能扩展基础功能实现后我们可以考虑对项目进行优化和功能扩展使其更加实用和个性化。性能优化建议降低功耗在没有卡片靠近时让STM32进入低功耗模式增加防抖处理避免卡片短暂离开导致的频繁刷新优化显示刷新只更新变化的部分减少闪烁功能扩展思路卡片数据库存储多张卡片的UID和别名访问记录保存读取历史可通过串口导出声音反馈添加蜂鸣器不同卡片不同提示音外壳设计3D打印或激光切割定制外壳实现卡片数据库功能的代码示例#define MAX_CARDS 10 typedef struct { uint8_t uid[4]; char name[16]; } CardEntry; CardEntry card_db[MAX_CARDS]; uint8_t card_count 0; uint8_t find_card(uint8_t *uid) { for(uint8_t i0; icard_count; i) { if(memcmp(card_db[i].uid, uid, 4) 0) { return i; } } return 0xFF; // 未找到 } void add_card(uint8_t *uid, const char *name) { if(card_count MAX_CARDS) return; memcpy(card_db[card_count].uid, uid, 4); strncpy(card_db[card_count].name, name, 15); card_db[card_count].name[15] \0; card_count; }对于想要进一步挑战的开发者可以考虑添加无线通信功能将读取的卡片信息上传到服务器或手机APP。以下是使用ESP8266模块通过WiFi发送数据的示例void send_card_info(uint8_t *uid) { char url[128]; sprintf(url, http://yourserver.com/api/card?uid%02X%02X%02X%02X, uid[0], uid[1], uid[2], uid[3]); // 发送HTTP请求 uart_printf(ATCIPSTART\TCP\,\yourserver.com\,80\r\n); delay_ms(1000); uart_printf(ATCIPSEND%d\r\n, strlen(url)26); delay_ms(500); uart_printf(GET %s HTTP/1.1\r\nHost: yourserver.com\r\n\r\n, url); delay_ms(1000); }6. 常见问题排查与调试技巧即使按照指南操作项目开发中仍可能遇到各种问题。以下是几个常见问题及其解决方案问题1RC522模块无法检测到卡片检查天线连接是否良好调整RC522模块上的电位器增大读卡距离确认模块供电电压稳定3.3V检查SPI通信是否正常可以用逻辑分析仪抓取波形问题2OLED显示屏无显示确认供电电压有些OLED需要5V有些需要3.3V检查I2C/SPI接口配置是否正确尝试调整显示屏背面的对比度电位器确认初始化序列正确发送问题3系统运行不稳定在电源引脚添加滤波电容如100μF电解电容并联0.1μF陶瓷电容检查所有接地连接是否良好降低SPI通信速率测试添加适当的延时确保模块有足够时间响应调试时可以充分利用串口输出信息。以下是一个实用的调试函数void debug_print(const char *format, ...) { char buffer[128]; va_list args; va_start(args, format); vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); // 输出到串口 uart_puts(buffer); // 同时显示在OLED上如果初始化了 if(oled_initialized) { static uint8_t line 0; oled_draw_string(0, line, buffer, FONT_SIZE_SMALL, WHITE); oled_update(); line (line 1) % 8; } }对于更复杂的问题可以分段测试各模块功能单独测试OLED显示输出固定文本和图形单独测试RC522读卡通过串口输出卡片UID测试两者协同工作读卡后显示信息添加额外功能如数据库、网络通信等7. 项目应用与创意延伸这个基础的卡片信息显示器可以延伸出许多有趣的应用场景以下是一些创意方向家庭应用智能钥匙挂钩识别挂上的钥匙并显示所有者宠物喂食器识别宠物项圈上的RFID标签个人物品管理为贵重物品贴上标签记录最后出现位置教育用途电子签到系统学生卡识别记录考勤互动学习工具不同卡片触发不同的学习内容科学实验记录将实验数据与样品RFID关联创意展示互动艺术装置观众持卡触发不同视觉效果智能名片盒取出名片时显示联系人详情收藏品管理系统为每件收藏品建立电子档案实现一个简单的智能钥匙挂钩示例void key_hook_demo() { uint8_t uid[4]; while(1) { if(detect_card(uid)) { uint8_t index find_card(uid); if(index ! 0xFF) { oled_clear(); oled_draw_string(0, 2, Key Detected:, FONT_SIZE_MEDIUM, WHITE); oled_draw_string(0, 4, card_db[index].name, FONT_SIZE_LARGE, WHITE); oled_update(); // 播放提示音 beep(1000, 200); } delay_ms(1000); // 防抖延时 } delay_ms(100); } }对于想要更深入学习RFID技术的开发者可以探索以下进阶主题MIFARE Classic卡片的数据结构及分块管理使用AES加密保护RFID通信反向工程研究RFID协议细节设计多频段RFID读卡器支持125kHz和13.56MHz无论你是电子爱好者、学生还是创客这个项目都提供了一个很好的起点既能学习嵌入式开发技术又能创造实用的智能设备。当看到自己制作的装置成功识别并显示卡片信息时那种成就感是无可替代的。

更多文章