用STM32F103C8T6和OLED屏做个密码锁,从硬件接线到代码烧录保姆级教程

张开发
2026/4/21 4:35:09 15 分钟阅读

分享文章

用STM32F103C8T6和OLED屏做个密码锁,从硬件接线到代码烧录保姆级教程
STM32F103C8T6与OLED屏打造智能密码锁全流程实战第一次拿到STM32开发板时很多人会陷入从何入手的困惑。本文将带你从零开始用最常见的STM32F103C8T6最小系统板和0.96寸OLED屏打造一个具备掉电保存功能的智能密码锁。不同于简单的代码演示我们会重点解决实际制作中遇到的硬件兼容、Flash存储稳定性等真实问题。1. 硬件选型与电路设计1.1 核心器件选择选择Blue Pill开发板STM32F103C8T6核心主要考虑三点价格亲民约15-25元丰富的外设接口37个GPIO内置128KB Flash满足密码存储需求OLED屏建议选用SSD1306驱动的0.96寸I2C接口版本其优势在于仅需4根连线VCC/GND/SCL/SDA功耗低全亮时约20mA自带显存刷新效率高继电器模块选择需要注意两个关键参数控制电压需匹配STM32的3.3V电平负载能力要大于电磁锁工作电流建议10A以上1.2 关键电路设计典型的连接方案如下表所示模块STM32引脚连接说明OLED SCLPB6需配置为开漏输出模式OLED SDAPB7需配置为开漏输出模式继电器控制端PA1需增加电平转换电路矩阵键盘行线PB12-PB15配置为上拉输入模式矩阵键盘列线PB8-PB11配置为推挽输出模式特别注意直接使用STM32的3.3V GPIO驱动5V继电器可能导致吸合不可靠建议采用以下NPN三极管驱动电路5V | [继电器线圈] | [2N3904集电极] | GPIO ---[基极 10K电阻] | GND2. 开发环境搭建2.1 工具链配置推荐使用STM32CubeIDE作为开发环境其优势在于集成STM32CubeMX图形化配置自动生成HAL库初始化代码支持在线调试和Flash烧录安装后需要额外准备SSD1306的HAL库驱动GitHub有开源实现STM32 Flash操作库内置在标准外设库中串口调试工具如Putty或Tera Term2.2 工程创建步骤# 新建STM32CubeIDE工程流程 1. File → New → STM32 Project 2. 选择MCU型号STM32F103C8Tx 3. 配置SYS→Debug为Serial Wire 4. 配置RCC→HSE为Crystal/Ceramic Resonator 5. 配置I2C1为I2C模式OLED使用 6. 配置GPIO引脚功能键盘、继电器等 7. 生成代码前勾选Generate peripheral initialization as a pair of .c/.h files3. 核心功能实现3.1 OLED显示驱动采用分层设计架构底层硬件抽象层HAL_I2C接口封装中间驱动层SSD1306命令处理应用层用户界面实现关键显示函数示例// 在指定位置显示字符串 void OLED_ShowString(uint8_t x, uint8_t y, char *str, FontSize size) { while(*str) { OLED_ShowChar(x, y, *str, size); x (size FONT_6x8) ? 6 : 8; str; } } // 密码输入显示效果 void ShowPasswordDots(uint8_t count) { for(uint8_t i0; i6; i) { if(i count) OLED_DrawCircle(20i*10, 30, 3, FILLED); else OLED_DrawCircle(20i*10, 30, 3, UNFILLED); } }3.2 密码存储机制利用STM32内部Flash实现掉电保存需要注意必须擦除整个扇区才能写入写入地址必须对齐到半字2字节建议保留多个备份存储位置Flash操作关键代码#define PWD_SECTOR_ADDR 0x0801F000 // 使用最后一个扇区 #define PWD_SIZE 6 // 6位密码 void SavePassword(uint8_t *pwd) { FLASH_EraseInitTypeDef erase; erase.TypeErase FLASH_TYPEERASE_PAGES; erase.PageAddress PWD_SECTOR_ADDR; erase.NbPages 1; HAL_FLASH_Unlock(); uint32_t error; HAL_FLASHEx_Erase(erase, error); for(uint8_t i0; iPWD_SIZE; i2) { uint16_t data (pwd[i1]8) | pwd[i]; HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PWD_SECTOR_ADDRi, data); } HAL_FLASH_Lock(); }4. 系统整合与调试4.1 状态机设计采用有限状态机(FSM)管理密码锁工作流程graph TD A[待机界面] --|按下*键| B[输入密码] B --|密码正确| C[开锁状态] B --|密码错误| A A --|按下#键| D[修改密码] D --|确认新密码| A对应的代码实现框架typedef enum { MODE_IDLE, MODE_INPUT, MODE_CHANGE, MODE_UNLOCK } LockMode; void HandleKeyInput(LockMode *mode, uint8_t key) { static uint8_t inputCount 0; static uint8_t newPwd[6]; switch(*mode) { case MODE_IDLE: if(key *) { ClearInputBuffer(); *mode MODE_INPUT; } else if(key #) { *mode MODE_CHANGE; } break; case MODE_INPUT: if(key 0 key 9) { if(inputCount 6) { inputBuffer[inputCount] key - 0; } } else if(key A) { // 退格 if(inputCount 0) inputCount--; } else if(key B) { // 确认 if(CheckPassword(inputBuffer)) { UnlockDoor(); *mode MODE_UNLOCK; } else { ShowError(); *mode MODE_IDLE; } } break; // 其他模式处理省略... } }4.2 常见问题排查实际开发中可能遇到的问题及解决方案OLED显示异常检查I2C地址通常0x3C或0x3D确认上拉电阻4.7KΩ已接测量电源电压3.3V-5V继电器无法吸合用万用表测量控制端电压检查续流二极管是否反接尝试降低继电器线圈电压测试Flash写入失败确保写入前已擦除扇区检查地址是否越界STM32F103C8T6只有64KB Flash验证编程电压需2.7V-3.6V矩阵键盘响应不稳定增加去抖动延时20-50ms检查上拉电阻建议10KΩ用逻辑分析仪捕获扫描时序5. 功能扩展建议基础功能实现后可以考虑以下增强功能安全增强输入错误次数限制蜂鸣器报警提示密码加密存储简单XOR运算用户体验优化增加震动马达反馈背光自动熄灭功能通过串口修改密码远程控制添加蓝牙模块HC-05手机APP控制接口开锁记录查询功能实际项目中我在继电器控制端增加了光耦隔离有效解决了MCU复位时继电器误动作的问题。另外发现SSD1306在低温环境下可能出现显示残影通过增加初始化时的重置脉冲可以改善。

更多文章