H35 烟雾温湿度报警器用 SHT15 数字温湿度传感器两线制,ADC0832 采烟雾浓度换百分制,五项阈值做上下限区间报警,5 个 LED 分路指示越界位置。相比 H34 把 DS18B20 换成 SHT15,报警从三或条件变五条件区间,设定项从 3 个变 5 个,界面刷新改成分帧状态机。

01 设计任务
功能介绍:
使用51单片机设计一个烟雾温湿度报警器,SHT15 测温湿度 + ADC0832 测烟雾浓度,五条件区间报警,要求如下:
1、SHT15 温湿度监测:两线制(DATA/SCK)数字温湿度传感器,一颗芯片同时出温度和相对湿度,LCD 显示 "RH: xx%, SC: xx%" 和 "T: xx℃";
2、烟雾浓度监测:ADC0832 采集模拟烟雾传感器,(x<<1)/5 换算百分制——H22/H34 同款公式,直接复用;
3、五条件区间报警:温度超上限 / 温度低于下限 / 湿度超上限 / 湿度低于下限 / 烟雾超限——注意温度湿度都是双向管,低了也报;
4、5 个 LED 分路指示:烟雾报警、温度上限、温度下限、湿度上限、湿度下限各一盏,蜂鸣器总报警——看哪盏灯亮就知道哪儿越界;
5、五项阈值独立设定:K1 循环切换设定项(湿度下限→湿度上限→烟雾→温度下限→温度上限),K2 加 K3 减 K4 确认,光标闪烁定位,全部限幅防误设。
特别注意:和 H34 比,最大的变化是传感器换代——DS18B20(单总线)换成 SHT15(两线制),温度单值变温湿度双值;报警逻辑从"三或条件"变五条件区间。框架(按键/限幅/双定时器/模块化)沿用 H34,这期的新货是 02 节的两线时序、03 节的共用体+浮点标定、04 节的区间报警结构。
02 SHT15 两线制时序:不是 I2C 的"两根线"
SHT15 用 DATA + SCK 两根线通信,长得像 I2C 但不是——它的时序是 Sensirion 私有协议,关键动作有三个:
先把 DATA 置 1、SCK 拉低做准备,然后 SCK 拉高的同时把 DATA 拉低、SCK 落一拍;再把 SCK 拉高的同时把 DATA 拉高、再落一拍,用两次方向相反的跳变拼出起始波形。
DATA 在 SCK 高电平期间先低后高,打出一个"两脉冲"的独有波形——I2C 的起始条件是"SCK 高时 DATA 下跳",这里要连续打两个方向相反的跳变,协议差异就在这种细节里。
写字节 + 应答检查:高位在前(for(i=0x80;i>0;i/=2) 移位发送),第 9 个时钟释放数据线读从机应答,error=DATA 记录——应答是低有效,非 0 就是通讯异常。
启动测量后进一个上限 65535 次的空循环,盯着 DATA 等它变低,一低就跳出;循环走完 DATA 还是高,说明超时没响应,error 计数加一。
SHT15 收到测量命令后要转换几百毫秒,转换完主动把 DATA 拉低——单片机轮询等待即可,超时判定 error。
三种数字传感器接口到这儿凑齐了:DS18B20 单总线(1 根线、靠精确延时挖时隙)→ SHT15 两线(2 根线、私有协议双脉冲起始)→ AT24C02 的 I2C(2 根线、标准协议)。线越少时序越"抠",读时序图的能力比背代码重要。
容错一招:主循环里 if(error!=0) SHTXX_Init();——通讯出错就发 9 个时钟的连接复位,把总线救回来。传感器通讯加自恢复,这是工程程序和玩具程序的分水岭。
03 共用体 + 浮点标定:union 的教科书用例
SHT15 返回的是原始码值,要经过标度变换才是真实温湿度。先看数据怎么接:
定义一个共用体,里面一个无符号整数和一个浮点变量共用同一块内存;先按整数成员把 SHT15 的原始码值写进去,再按浮点成员把它读出来送去标定。
union 共用体:i 和 f 共享同一块 4 字节内存,同一份数据两种解读——接传感器原始整数时用 .i,做浮点标定时用 .f。这不是炫技,是省一次强制类型转换的歧义、让"数据在不同阶段的形态"显式化,Sensirion 官方例程就这么写。
标度变换函数 SHTXX_calc() 是数据手册公式的代码化:
温度按一次线性公式直接换算;湿度先算二次非线性项,再除以 33 做分段经验修正,修正值落进 26 / 33 / 40 几个区间就逐级加偏移,最后上夹 100、下夹 0.1。
三个看点:
· 温度是线性的(一次公式直接换),湿度是非线性的——湿敏电容在高湿段响应弯曲,必须二次项修正,不然 90% 湿度能给你读出 105%;
· 分段修正:在非线性补偿基础上再按湿度区间加经验偏移,这是仿真里"凑真实曲线"的常用手法——真传感器有手册公式,仿真的 SHT15 模型简单,就人工补几段;
· 夹限保护:结果超 100 按回 100、小于 0.1 按 0.1,物理量有物理边界,输出前夹住,防止后续显示和比较出妖怪值。
浮点运算在 51 上又慢又占空间(这期 code=4602,比 H34 的 2392 翻了近一倍,多出来的基本都是 float 库),但换算清晰——仿真阶段用浮点换可读性,量产再换定点,是合理的取舍顺序。
04 五条件区间报警:从"超限报"到"区间管"
报警判断把烟雾超限、温度超上限、湿度超上限、温度低于下限、湿度低于下限五个条件用或运算串在同一个判断里,任一成立就打开总报警。
总报警之外,5 盏灯各判各的:温度超上限点亮 LED2,温度低于下限点亮 LED3,湿度超上限点亮 LED4,湿度低于下限点亮 LED5,四路各自独立判断,互不干扰。
这个结构的价值在于区分"报警"和"定位":蜂鸣器只说"出事了",5 盏灯说"哪儿出事"——机房温控、仓库保管、大棚监控,环境量从来不是"越低越好",低温低湿同样是事故(冷凝、干燥起静电),所以上下限都要管。
工程细节两个:
· real_tempure = temp_val.f + 1:浮点结果 +1 后取整赋给 int——实质就是 H34 说的"向上取整"保守策略的极简实现,温度比较永远偏严一档;
· ON=0 / OFF=1 宏:LED 低电平点亮(灌电流驱动),用宏把"逻辑开"和"电平低"解耦,程序里到处写 LED1=0 既难读又容易在换硬件时改漏。
05 五项设定交互:双状态机刷新界面
设定项从 3 个变 5 个,界面刷新出了新形态——circle_num / dis_list 双状态机:
· 设定模式(mode=1):circle_num 0→5 循环,case 0 先铺 "H: __%~__%; T: __C~__C" 的界面骨架,case 1~5 每轮只刷新一个设定项的数字——5 个值不是一帧刷完,而是每轮主循环刷一个,转一圈全部就位;
· 正常模式(mode=0):dis_list 两拍走——case 0 打显示模板,case 1 填温湿度和烟雾数值,然后停住(dis_list++ 只走一次到底);
· 光标跟随:K1 每按一次 set_position++(1~5 循环),cursor_position 换到对应数字位(第一行 4/9/14、第二行 4/9 + 0x40),write_com(0x0e) 开光标闪烁——改哪个值,光标就蹲在哪。
为什么设定界面要"分帧刷"?一次刷 5 个值,主循环单轮耗时长,按键响应和光标闪烁都会卡;拆成每轮一项,每轮主循环都很快,交互跟手。这个"界面刷新分帧"的思想,往大了说就是 GUI 框架里 partial refresh 的雏形。
06 设计报告与视频讲解



本设计配套资料齐全(H 系列标准四件套):
· Proteus 仿真:51 单片机 + LCD1602 + SHT15 温湿度模块 + ADC0832 烟雾 + 5 LED 报警指示 + 蜂鸣器,模块分区标注;
· Keil 程序:三模块工程(main + lcd1602 + adc0832),编译 0 Error 0 Warning(code=4602);
· 设计报告:系统框图、SHT15 协议分析、标定公式推导与源码;
· 视频讲解:原理图讲解 + 程序讲解两段,重点看两线时序和标定函数两段。

07 排错清单
1、温湿度永远显示初始值/怪数字 → 先查 SHT15 接线(DATA=P2.5、SCK=P2.4 别接反),再在测量等待循环确认 DATA 有没有被拉低——一直为高说明传感器没响应,检查 error 分支是否走了 SHTXX_Init() 复位;
2、湿度显示 105% 或负数 → 标定函数的夹限(>100 回 100、<0.1 回 0.1)或分段修正被删了;SHT15 仿真模型的原始值偏大,分段修正是给仿真"补真实感"的,不能省;
3、改了湿度下限不生效 → 五项设定全部按 K4 确认后才参与比较(mode 回 0),且看准光标在哪一位——K1 按 5 次才轮到温度上限,别改错项;
4、蜂鸣器一直响 → 五条件是"或"关系,任一越界都响;把 LCD 实时值和五个设定值逐个对一遍,5 盏 LED 哪盏亮就是哪路越界,这是分路指示的价值;
5、设定界面数字显示不全 → circle_num 状态机的 case 0(铺界面骨架)被跳过或 circle_num=1 的回卷写错——骨架没铺就填数,空白模板就不在;
6、烟雾浓度差一位 → 同 H22/H34:data_to_hex 十进制转 BCD 别动,浓度按 BCD 位写给液晶;(x<<1)/5 换算和 >127 补 50 的分段逻辑配套,单独改一半必错;
7、程序编译后 code 巨大/仿真卡 → 浮点库正常体积(这期 4602),但若还嫌慢,可把 SHTXX_calc 换成定点运算(×100 放大取整),换完记得把 real_tempure 的 +1 修正逻辑一起迁移。
08 系列回顾
环境监测这条线,三期正好是三级台阶:
· H22 家用烟雾报警器:三条件或报警,单文件入门;
· H34 火焰烟雾温度报警器:模块化工程 + 数据质量三招(滤波/过滤/保守取整);
· H35 烟雾温湿度报警器:传感器换代(DS18B20→SHT15)+ 区间报警 + 双状态机界面,物理量从"单值越限"升级到"双向区间管理"。
数字传感器接口三连也集齐了:DS18B20 单总线、SHT15 两线私有协议、AT24C02 标准 I2C——面试被问"几种通信接口",把这三期的时序差异讲出来就是满分答案。环境监测类设计到这儿封顶,下期见。
需要本设计的仿真 + 程序 + 报告 + 视频全套资料,公众号回复 H35 免费领取。
09 文件日期修改
如果你想把文件修改为最新的日期,又不想新建工程,那么你可以参考下面的文章。
"如何不打开程序的情况下更改proteus和keil程序的日期?"
工具和仿真文件在一起,见下面的下载链接。
10 资料下载
全套资料包含 Keil 工程(C 语言源码 + hex 文件)、Proteus 仿真工程、设计报告、程序流程图、讲解视频,以及编译截图和仿真截图。下载后可直接打开运行,也可用于课程设计、毕业设计参考。
也可以关注公众号「单片机仿真」,回复 H35 获取下载入口。公众号内还有 A / T / H 全系列 400 多个单片机仿真实例,回复「目录」可查看完整清单。

