H36 红外防盗报警器接 4 路红外探头分路监测,用一个字节的位图锁存报警状态,4 个 LED 分路闪烁、一位共阳数码管显示最新报警线路号,只有按清除键才解除。和前三篇环境监测型不同,这篇是瞬时触发、锁存保持、人工清除的防盗模式,主循环只管记事、定时器中断专管闪灯。

01 设计任务
功能介绍:
使用51单片机设计一个红外防盗报警器,4 路探头分路监测、锁存报警、分路指示,要求如下:
1、4 路报警输入:P1.0~P1.3 各接一路红外防盗探头(仿真用按钮模拟),低电平触发——哪一路被人触发就记录哪一路;
2、报警锁存:人走过探头,信号只闪一下就消失——程序必须把这次报警记住,警灯持续闪、警铃持续响,直到按"报警清除"键才解除;
3、分路指示:4 个 LED 对应 4 路探头,报警路闪烁;一位共阳数码管显示最新报警的线路号 1~4;
4、多路同时报警互不覆盖:几路一起触发,每路的灯都闪,蜂鸣器响;
5、蜂鸣器联动:任一路报警即响,全部清除后静音。
特别注意:这是报警器系列的第四篇,但模式和前三篇都不一样——H22/H34/H35 是环境监测型(温度湿度浓度实时比较,信号消失自动恢复),这篇是防盗触发型(瞬时触发、锁存保持、人工清除)。"锁存"两个字是防盗报警的灵魂,02 节讲它怎么用一个字节的位图实现。
02 一个字节管四路:alarm_flag 位图锁存
定义一个报警标志字节,bit0~bit3 各代表一路探头:哪一路输入拉低,就把对应那位置 1、点亮该路灯、把线路号记进 alarm_num;四路判完再看这个字节,非零就开蜂鸣器,全零就关蜂鸣器、熄四盏灯、线路号清零。
三个看点:
· |= 置位:某路触发就把它对应的 bit 置 1。注意是"或上"而不是"等于"——alarm_flag = 0x01 会把其他路的报警冲掉,|= 只添不动;
· 锁存的意义:主循环没有任何地方把 alarm_flag 的位清 0(除了清除键),所以传感器信号消失,报警状态还在——红外探头是瞬时的,报警必须持久的,这就是"锁存"两个字的分量;
· 清除是唯一的出口:AlARM_CLEAR 按下(消抖后确认)执行 alarm_flag = 0,四路一起清——复位权在保安手里,不在传感器手里。
位图是嵌入式状态管理的通用手法:一个字节管 8 路状态,置位 |=、判位 &、清位 &=~,三个位运算走天下。和 H27 的 begin_flag(单个 bit 管一把锁)比,这是它的多路扩展版;以后学到操作系统里的事件标志组、网络协议里的状态字,全是这一套。
03 职责分离:主循环采集,中断闪烁
这期的定时器中断不干别的,专门让报警灯闪:
定时器中断里先重装 10ms 初值,然后逐位检查报警标志:哪一位是 1,就把对应那路的 LED 取反一次,四路各查各的。
主循环和中断的分工非常清楚:
· 主循环:采集 4 路输入、维护位图、处理清除键、驱动数码管——"记事";
· 中断:每 10ms 检查位图,报警路的 LED 取反——"闪灯"。
这个结构好在主循环再忙也不影响闪灯节奏:如果 LED 翻转放在主循环里,Delay_1ms(10) 和数码管刷新会让闪烁间隔忽长忽短;放进定时器中断,闪烁周期纹丝不动。这是"时间敏感的任务交给中断"的经典应用——H29 的三层时间片调度、H27 的时钟进位,都是同一思想的不同形态。
一个诚实的工程点评:10ms 翻转一次意味着闪烁频率 50Hz——人眼根本分辨不出来,看起来和常亮一样。想真正看到"闪",要在中断里加个计数器,比如累计到 50 次(500ms)才翻转一次。这个程序保留了 10ms 的写法,可能是给仿真演示留的余量,你们实际做项目时按需求改计数阈值即可(07 节排错第 3 条同步提醒)。
04 清除键消抖与宏封装
清除键是全系统唯一的"复位入口",处理得规矩:
检测到清除键为低先延时 10ms,再读一次确认仍是低电平,才把报警标志整体清 0。
两次检测间隔 10ms,滤掉机械触点的抖动脉冲——没有这一步,抖动毛刺会在人没按的时候把报警清了,防盗系统等于白装。这是 H21 以来第四次出现消抖,形态不同(这里是"清除动作"的防误触,之前是"采集动作"的防误判),意识是同一个:凡是机械触点,必有抖动;凡是抖动,必拦在动作之前。
三个宏把电平细节收起来:一个宏把四盏灯一起熄灭,一个宏开蜂鸣器,一个宏关蜂鸣器。
和 H35 的 ON/OFF 宏一脉相承:电平细节锁进宏,主逻辑只说人话——BUZZ_ON 到底是 0 还是 1,取决于蜂鸣器接 PNP 还是 NPN,换了硬件只改一行宏。四个灯的关闭写成一条宏,主循环里一行 ALL_LED_OFF 顶四行赋值,可读性立刻不一样。
05 一位数码管的"裁剪哲学"
显示部分只用了一位数码管(P0 经 RP1 排阻驱动,共阳段码表),显示最新报警的线路号:
显示函数拿线路号当查表下标,从共阳段码表里取出段码,直接写到数码管的数据口。
四路报警,一位管够——因为用户要的是"出事了看一眼哪儿出事",不是历史记录。多路同时报警时数码管只显示最后触发那路(alarm_num 会被覆盖),但 4 盏分路 LED 都闪着呢,路数信息由灯补齐:数码管给数字,LED 给状态,分工不重复。
这背后是个裁剪意识:显示资源按信息优先级分配,不做冗余。真要"逐路轮显"或"叠加显示 12/34",代价是代码复杂度翻倍、用户反而看不清——把有限的一位用在最该显示的信息上,这比堆资源更能体现设计功力。当然,如果需求真要历史记录,改进方向也很直接:alarm_flag 的 4 个 bit 轮流显示,或者上 LCD1602(H34 的模板直接抄)。
06 设计报告与视频讲解



本设计配套资料齐全(H 系列标准四件套):
· Proteus 仿真:51 单片机 + 4 路报警输入 + 报警清除键 + 4 LED 分路指示 + 一位共阳数码管 + PNP 蜂鸣器,模块分区标注清晰;
· Keil 程序:单文件工程(alarm),编译 0 Error 0 Warning(code=356),全系列最精简的一份;
· 设计报告:系统框图、位图锁存原理、程序流程与源码;
· 视频讲解:原理图讲解 + 程序讲解两段。

07 排错清单
1、按了探头不报警 → 先确认输入是低电平有效(探头动作拉低 P1.x),再用示波器/逻辑笔看引脚电平有没有变化;4 路输入宏定义是 P1.0~P1.3,别接去 P1.4 以后;
2、报警信号消失后警铃跟着停 → 锁存被破坏了——检查主循环里是不是误加了 alarm_flag=0 之类的清除语句;合法的清除入口只有一个:清除键确认按下;
3、报警灯"闪"效果看不出来 → 中断里 10ms 翻转一次 = 50Hz,人眼看是常亮;想真闪,中断里加计数器,累计 50 次(500ms)再翻转;
4、按清除键没反应/一下清两回 → 消抖的两次检测和 10ms 延时不能省;还有个源码小瑕疵顺便提:Time0_init() 里注释写"模式2,8位定时器",实际 TMOD=0x01 是模式 1(16 位),注释错了代码没错——看代码别看注释猜配置;另外 init 时装的是 50ms 初值、中断里重装 10ms,两处不一致,实为 10ms 周期;
5、多路同时报警时数码管数字跳 → 这是"显示最新一路"的设计行为(后触发覆盖前触发),路数信息看 LED;想轮显改 alarm_flag 的位循环即可;
6、蜂鸣器不响 → 这期是 PNP 管 Q1 驱动,BUZZ_ON 宏是 BUZZ=0(低电平导通);如果你的硬件是 NPN 高电平触发,只改宏定义,主逻辑不用动;
7、数码管段码乱 → 共阳段码表(0xc0 开头)别和共阴混用——H26 刚考过这个点,阴阳性是段码表选型的第一步。
08 系列回顾
报警器四部曲到这儿集齐了四种模式:
· H22 家用烟雾报警器:三条件实时比较,入门框架;
· H34 火焰烟雾温度报警器:模块化 + 数据质量三招(滤波/过滤/保守取整);
· H35 烟雾温湿度报警器:传感器换代 + 五条件区间管理 + 分帧刷新;
· H36 红外防盗报警器:瞬时触发 + 位图锁存 + 人工清除,防盗模式。
两条路线的本质区别一句话说清:环境监测型"信号消失自动恢复",防盗触发型"锁存保持人工清除"——选哪种取决于业务:温度超了降温就撤警,人闯进来撤警得保安说了算。位图锁存这个手法,将来在多任务事件标志、按键组合键、协议状态机里还会反复遇到,这 148 行就是它最干净的教材。
需要本设计的仿真 + 程序 + 报告 + 视频全套资料,公众号回复 H36 免费领取。下期见!
09 文件日期修改
如果你想把文件修改为最新的日期,又不想新建工程,那么你可以参考下面的文章。
"如何不打开程序的情况下更改proteus和keil程序的日期?"
工具和仿真文件在一起,见下面的下载链接。
10 资料下载
全套资料包含 Keil 工程(C 语言源码 + hex 文件)、Proteus 仿真工程、设计报告、程序流程图、讲解视频,以及编译截图和仿真截图。下载后可直接打开运行,也可用于课程设计、毕业设计参考。
也可以关注公众号「单片机仿真」,回复 H36 获取下载入口。公众号内还有 A / T / H 全系列 400 多个单片机仿真实例,回复「目录」可查看完整清单。

