)
用51单片机和红外传感器DIY智能客流统计系统每次走进常去的自习室总会遇到人满为患却不知具体人数的尴尬。作为电子爱好者我决定用最基础的51单片机和红外传感器打造一个低成本客流统计器解决这个小烦恼。这个项目不仅能用于小型商铺、图书馆还能改装成家庭入口的访客记录仪核心在于如何用两个传感器准确判断进出方向。1. 硬件选型与电路设计选择STC89C52作为主控芯片主要看中其稳定性和丰富的IO口资源。红外传感器选用E18-D80NK这款光电开关有效探测距离3-80cm可调自带灵敏度调节旋钮能有效避免误触发。显示模块采用经典的LCD1602液晶屏性价比高且驱动简单。提示E18-D80NK的工作电压为5V与51单片机完全兼容无需额外电平转换电路传感器安装位置直接影响计数准确性。我的实测方案是入口传感器距地面15cm倾斜15度朝向外侧出口传感器与入口对称安装倾斜方向相反间距要求两个传感器中心距≥25cm防止同时遮挡电路连接关键点模块连接引脚备注LCD1602P0口需接10K上拉电阻红外传感器AP3.2(INT0)入口检测下降沿触发红外传感器BP3.3(INT1)出口检测下降沿触发蜂鸣器P2.0接NPN三极管驱动// 硬件初始化代码片段 void hardware_init() { P0 0xFF; // LCD数据口置高 P2 0xFE; // 蜂鸣器初始关闭 IT0 1; // 设置INT0边沿触发 IT1 1; // 设置INT1边沿触发 EX0 1; // 使能INT0中断 EX1 1; // 使能INT1中断 EA 1; // 全局中断使能 }2. 方向判断逻辑实现核心难点在于区分进出方向。通过实验发现人体经过两个传感器时会形成特定的触发序列进入触发序列传感器A→传感器B间隔300-800ms离开触发序列传感器B→传感器A间隔300-800msvolatile bit flag_A 0, flag_B 0; volatile unsigned int timestamp_A 0, timestamp_B 0; // INT0中断服务函数传感器A void SensorA_ISR() interrupt 0 { flag_A 1; timestamp_A sys_ticks; // 获取系统时间戳 if(flag_B (timestamp_A - timestamp_B 1000)) { person_enter; // 进入计数 flag_A flag_B 0; } } // INT1中断服务函数传感器B void SensorB_ISR() interrupt 2 { flag_B 1; timestamp_B sys_ticks; if(flag_A (timestamp_B - timestamp_A 1000)) { person_exit; // 离开计数 flag_A flag_B 0; } }实际调试中发现三个常见问题及解决方案误触发问题调整传感器灵敏度旋钮至中间档位并在代码中添加去抖动延时同时遮挡优化安装位置确保无法同时遮挡两个传感器快速通过在中断函数中添加时间窗口判断300-1000ms3. 报警功能与交互设计系统设置人数上限报警功能当实时人数达到预设值时触发声光报警。采用三个按键实现设置交互SET键进入/退出设置模式UP键上限值增加/计数清零长按3秒DOWN键上限值减少void check_alarm() { if(current_count limit_count) { buzzer_on(); // 蜂鸣器鸣响 lcd_set_cursor(1, 0); lcd_write_string(ALERT! OVERFLOW ); } else { buzzer_off(); } } // 按键处理代码片段 void key_handle() { if(SET_pressed()) { setting_mode !setting_mode; if(!setting_mode) save_limit_to_eeprom(); } if(setting_mode UP_pressed()) { limit_count; if(limit_count 9999) limit_count 0; } if(UP_long_pressed()) { // 长按清零 current_count 0; person_enter person_exit 0; } }LCD显示界面设计为两行人数:023 上限:050 进入:015 离开:0124. 系统优化与扩展基础功能实现后我做了以下优化提升实用性数据持久化添加AT24C02 EEPROM存储上限设置值断电不丢失抗干扰设计所有IO口添加104瓷片电容滤波传感器信号线使用双绞线电源输入端加入470μF电解电容低功耗模式当5分钟无人员进出时关闭LCD背光按任意键唤醒// 低功耗处理代码 void power_manage() { static unsigned int idle_counter 0; if(last_count ! current_count) { idle_counter 0; lcd_backlight(ON); } else if(idle_counter 30000) { // 约5分钟 lcd_backlight(OFF); } last_count current_count; }进阶改进方向增加WiFi模块上传数据到云端改用OLED显示屏提升可视角度添加温度传感器实现环境监测开发手机APP实时查看数据5. 常见问题排查指南在面包板搭建阶段遇到几个典型问题LCD显示乱码检查对比度调节电位器通常10KΩ确认初始化时序满足说明书要求测试电源电压稳定在5V±0.2V传感器响应不稳定# 用示波器检测信号波形时应观察到 # 无遮挡时稳定的3.3V高电平 # 遮挡时清晰的低电平脉冲100ms蜂鸣器不发声测量驱动三极管基极电压应有0.7V左右检查蜂鸣器极性有源蜂鸣器分正负测试单独供电时能否发声调试小技巧使用LED指示灯辅助调试每个传感器配一个状态灯在关键代码处添加调试输出分段测试先验证传感器单独工作再测试联动逻辑这个项目最让我惊喜的是用基础元件就能实现实用的日常解决方案。记得第一次成功区分进出方向时那种成就感远超预期。建议初学者先从面包板搭建开始逐步优化最后再设计PCB做成完整设备。