
一、项目概述1.1 项目功能基于 STM32F10x 单片机,结合4 独立按键、8 位共阴极数码管、AT24C02 IIC EEPROM、串口 1 打印实现带掉电保存的数值调节器:上电自动读取 EEPROM 中存储的 0~255 数值,数码管百位、十位、个位实时显示;KEY1:进入设置模式;KEY2:数值 + 1;KEY3:数值 - 1;KEY4:退出设置模式;数值限制区间0 ~ 255,超出边界串口提示;每次修改数值自动写入 AT24C02,断电数据不丢失;串口 9600 波特实时打印按键操作、数值、硬件检测状态;硬件自检:上电循环检测 AT24C02,硬件异常持续打印报错,正常后进入主逻辑;数码管动态消隐驱动,消除数字拖影,仅前 3 位显示 0~255,后 5 位熄灭。1.2 硬件资源清单表格外设模块功能引脚资源SysTick毫秒 / 微秒延时、系统时钟 72M内核定时器4 独立按键模式切换、加减、确认退出GPIOA 上拉输入8 位共阴极数码管动态扫描显示 0~255PB0~PB7 段选;PA4/PA5/PA6 位选译码USART1串口调试打印PA9(TX)、PA10(RX)AT24C02掉电存储数值,IIC 通信自定义 SCL/SDA 引脚,软件模拟 IICNVIC中断优先级分组 2系统中断配置1.3 核心技术点软件模拟标准 IIC 通信时序,兼容 AT24CXX 系列 EEPROM;数码管动态扫描 + 段码消隐算法,解决残影问题;独立按键松手检测 + 20ms 软件消抖,支持长按阻塞;EEPROM 上电自检、单字节读写,数据持久化;状态机区分正常显示模式 / 参数设置模式;宏常量统一管理硬件地址、阈值、延时,便于移植修改。二、工程文件分层说明plaintext工程根目录 ├─ main.c 主业务逻辑(按键交互、显示、EEPROM读写、模式控制) ├─ key.h/.c 4路独立按键底层驱动 ├─ smg.h/.c 8位共阴极数码管动态扫描驱动 ├─ iic.h/.c 软件模拟IIC底层时序驱动 ├─ 24cxx.h 基于IIC封装AT24C02读写接口 ├─ SysTick.h 系统滴答定时器延时函数(ms/us) ├─ usart.h USART1串口初始化、printf重定向 └─ public.h 公共类型定义(u8/u16/u32)、硬件引脚宏定义三、各模块详细功能文档模块 1:公共业务宏与常量定义(main.c 顶部)3.1 业务宏说明表格宏名数值作用EEPROM_STORE_ADDR0AT24C02 内部存储地址,数值存在 0 号字节DATA_MAX_VAL255计数最大值,单字节无符号上限DATA_MIN_VAL0计数最小值SCAN_DELAY_MS10主循环周期延时,控制按键扫描、刷新帧率3.2 工具函数Num_To_Buf(u16 num, u8 buf[8])功能:将 0~255 数字拆解为百位、十位、个位,填充数码管显示缓存,其余 5 位清零熄灭入参:num待转换数字;buf[8]8 位数码管显示缓存数组执行逻辑:全部 8 位缓存置 0,默认熄灭;buf[2] = num / 100百位;buf[1] = (num%100)/10十位;buf[0] = num%10个位;仅前 3 位存储有效数字,动态显示时只扫描前 3 位。3.3 硬件初始化函数Hardware_Init()统一初始化所有外设,集中管理硬件启动流程:SysTick 滴答定时器初始化(72MHz 系统时钟);NVIC 中断优先级分组 2 配置;数码管硬件初始化SMG_Init();USART1 9600 波特串口初始化;按键 GPIO 初始化KEY_Init();IIC 总线 + AT24C02 硬件初始化AT24CXX_Init()。3.4 EEPROM 硬件自检EEPROM_DeviceCheck()阻塞式硬件检测,防止 EEPROM 接线异常导致程序卡死:循环调用AT24CXX_CheckDevice()检测从机应答;无应答:串口打印报错,500ms 重试;检测通过:打印正常提示,退出自检进入业务循环。3.5 Main 主函数逻辑流程flowchart TD A[外设统一初始化] -- B[循环检测AT24C02硬件] B -- C[上电读取EEPROM保存数值num_val] C -- D[进入while(1)死循环] D -- E[按键扫描key_scan(0)] E -- F{是否有按键按下} F --无-- G[填充显示缓存+刷新数码管] F --有-- H[switch按键分支处理] H -- H1[KEY1:set_mode=1 进入设置模式] H -- H2[KEY2:设置模式下数值+1,上限255,自动写EEPROM] H -- H3[KEY3:设置模式下数值-1,下限0,自动写EEPROM] H -- H4[KEY4:set_mode=0 退出设置模式] H1H2H3H4 -- G G -- I[延时10ms,循环刷新] I -- D变量说明disp_buf[8]:数码管显示缓存数组;keyVal:按键扫描返回值,无按键 = 0;num_val:全局计数值,0~255,与 EEPROM 实时同步;set_mode:模式状态标记,0 = 正常只读显示,1 = 可修改数值设置模式。模块 2:按键驱动 key.c2.1KEY_Init(void)时钟:开启 KEY_PORT (GPIOA) 外设时钟;引脚配置:KEY1/2/3/4 引脚配置为上拉输入 GPIO_Mode_IPU;硬件逻辑:无按键时引脚高电平,按键按下拉低电平触发。2.2u8 key_scan(u8 mode)独立按键扫描函数参数:mode=0重置按键状态机;mode=1保持状态返回值:KEY_UNPRESS(0)无按键;KEY1_PRESS/KEY2_PRESS/KEY3_PRESS/KEY4_PRESS对应按键标识核心机制:状态机 + 松手阻塞消抖静态变量key_state:1 = 空闲可检测按键,0 = 按键消抖锁定;检测到低电平按键信号 → 20ms 软件消抖;判断具体按键,进入while(KEYx==0)阻塞循环,必须松手才退出;松手后再延时 20ms 消抖,恢复空闲检测状态;多按键同时按下仅识别优先级靠前按键(KEY1KEY2KEY3KEY4)。模块 3:数码管驱动 smg.c3.1 段码数组gsmg_code[17]适配共阴极数码管标准段码,下标对应数字 0~15:0x3f(0),0x06(1),0x5b(2),0x4f(3),0x66(4),0x6d(5),0x7d(6),0x07(7),0x7f(8),0x6f(9)...3.2SMG_Init(void)数码管硬件初始化段选 PB0~PB7:推挽输出 50MHz,上电段码全 0(熄灭);位选 PA4/PA5/PA6 (LSA/LSB/LSC):推挽输出,译码选择 8 位数码管;初始化关闭所有位选,数码管全部熄灭,防止上电乱码。3.3smg_display(u8 dat[],u8 scan_num)动态扫描显示函数入参:dat[]显示缓存;scan_num需要扫描的数码管位数(本项目传入 2,扫描前 3 位 0/1/2)消隐核心逻辑(解决动态扫描残影):切换当前数码管位选;先清空段码输出 0x00(消隐);