1. 项目概述
这个基于STM32单片机的人数流量统计系统,是我最近完成的一个实用嵌入式项目。它通过简单的按键操作实现场所人流量统计,比如图书馆、会议室等需要控制人数的场景。系统核心功能包括:
- 两个独立按键分别实现人数增减(+1/-1)
- 清零按键可重置统计数值
- 4位数码管实时显示当前人数
作为一个经常需要统计实验室人次的助研,我发现市面上商用计数器价格昂贵且功能冗余。于是决定用最基础的STM32F103C8T6开发板搭配外围器件,自己搭建一个成本不足50元但完全够用的解决方案。
2. 硬件设计详解
2.1 核心器件选型
主控芯片选用STM32F103C8T6,原因有三:
- 72MHz主频完全满足扫描数码管和检测按键的需求
- 内置64KB Flash足以容纳本项目的程序代码
- 价格仅10元左右,性价比极高
显示模块采用4位共阳数码管(型号:3641AS),其优势在于:
- 驱动电流小(每段约10mA)
- 亮度高且视角广
- 价格低廉(约3元/个)
按键电路设计时特别注意:
- 采用10KΩ上拉电阻(防止浮空输入)
- 并联104电容消除抖动(硬件消抖)
- 按键引脚配置为内部上拉输入模式
2.2 电路连接原理
数码管驱动采用经典的位选+段选方式:
- PC1-PC4连接位选控制线
- PC5-PC12连接段选信号(含小数点)
- 通过74HC245缓冲器增强驱动能力
按键接口设计:
- PB13-PB15连接三个轻触开关
- 按键状态检测采用扫描方式而非中断
- 软件实现10ms消抖延时
实际搭建时发现:若直接驱动多位数码管,STM32的IO口输出电流可能不足。建议增加ULN2003达林顿管或使用74HC595进行扩展。
3. 软件实现解析
3.1 主程序框架
程序采用轮询架构,主循环包含三个关键任务:
c复制while(1) {
key_scan(); // 按键扫描
counter_update();// 计数器处理
display_show(); // 数码管显示
}
这种设计保证了:
- 实时响应按键操作(检测周期<20ms)
- 显示刷新率稳定在100Hz以上(无闪烁)
- 代码结构清晰易于维护
3.2 数码管驱动实现
动态扫描显示的核心代码如下:
c复制void Show_num(u16 num) {
static u8 pos = 0;
SEG1=0; SEG2=0; SEG3=0; SEG4=0; // 位消隐
switch(pos) {
case 0: // 千位
Drv_SEG(CAseg_table[num/1000]);
SEG1=1; break;
case 1: // 百位
Drv_SEG(CAseg_table[num%1000/100]);
SEG2=1; break;
// ...省略十位和个位处理
}
pos = (pos+1)%4;
Delay_ms(5); // 每位显示5ms
}
注意事项:
- 消隐时间要足够(至少1ms)
- 扫描周期控制在20ms以内
- 段码表需根据数码管类型(共阳/共阴)调整
3.3 按键处理优化
原始代码中的按键检测存在"长按连发"问题,改进方案:
c复制u8 Get_key() {
static u32 last_time = 0;
if(HAL_GetTick() - last_time < 200) return 0; // 防抖+防连按
if(K1==0) { last_time = HAL_GetTick(); return 1; }
if(K2==0) { last_time = HAL_GetTick(); return 2; }
if(K3==0) { last_time = HAL_GetTick(); return 3; }
return 0;
}
这样实现了:
- 200ms按键间隔防止误触发
- 兼容快速连续点击
- 资源占用低的优点
4. Proteus仿真要点
4.1 仿真模型配置
关键器件参数设置:
- STM32F103C8: 时钟频率设为8MHz(外部晶振)
- 数码管: 修改为Common Anode类型
- 按键: 添加10k上拉电阻
常见仿真问题解决:
- 数码管不亮:检查共阳/共阴配置
- 按键无反应:确认上拉电阻值
- 显示乱码:核对段码表定义
4.2 性能优化技巧
通过仿真发现两个重要改进点:
- 显示扫描周期从10ms降至5ms后,亮度提升且无闪烁
- 按键消抖延时从20ms调整为10ms后,响应更灵敏
仿真与实物的差异处理:
- 实物数码管需要限流电阻(220Ω)
- 实际按键触感与仿真不同,需调整消抖参数
- 电源稳定性影响显示效果
5. 项目进阶建议
5.1 功能扩展方向
- 数据存储:增加EEPROM保存历史数据
c复制void Save_Count() {
HAL_I2C_Mem_Write(&hi2c1, 0xA0, 0x00, 1, &count, 1, 100);
}
- 无线传输:通过ESP8266上传数据到服务器
- 声光提示:人数超限时触发蜂鸣器报警
5.2 生产注意事项
批量生产时需要:
- 改用贴片元件缩小PCB尺寸
- 数码管更换为TM1637模块降低成本
- 添加电源指示灯和状态LED
实测发现:使用外部8MHz晶振时,系统稳定性比内部RC振荡器提高30%以上。