ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Proteus仿真PM2.5检测系统:单片机数据采集与显示设计

Proteus仿真PM2.5检测系统:单片机数据采集与显示设计 简介基于单片机Proteus仿真的空气质量PM2.5检测系统资源包面向单片机初、中级学习者和电子设计人员主要用于课程设计、毕业设计及环境监测类项目验证。系统集成PM2.5粉尘检测与温湿度采集具备空气质量等级判断、历史数据查询、超限报警、断电保存等功能测量范围覆盖0~999ug/m^3可满足家庭、办公室及小型工厂等场景的监测需求。压缩包共55个文件内含C语言源码、Proteus仿真工程DSN、原理图SchDoc、HEX固件、仿真截图及元件清单等整体仅807KB文件类型覆盖程序设计、电路仿真、文档说明等多个维度便于直接打开工程进行学习、修改与二次开发。目前已有132人学习下载适合希望通过完整仿真案例快速理解单片机软硬件协同设计的读者。1. 单片机Proteus仿真的PM2.5检测系统到底在仿什么先说结论仿真环境里没有真实的粉尘颗粒只有传感器输出到单片机引脚的电压因此这个基于单片机Proteusprotues仿真的PM2.5检测系统真正仿的是采集链路而不是空气本身。把一路可调电压当作PM2.5浓度由单片机ADC量化后换算成µg/m³再叠加DHT11温湿度结果路由到LCD和报警电路这套流程就叫protues仿真里的空气质量检测。它的价值在于在没有硬件、没有风洞的条件下把模拟量输入、单总线时序、串口打印和阈值报警全部跑通并且这些逻辑转移到实物后仍然成立。常见做法是AT89C51作为主控Proteus中放电位器模拟粉尘信号DHT11模型读温湿度LM016L显示。这套内容适合课程设计、毕设也适合准备蓝桥杯单片机笔试的人用来理解传感器数据流。2. PM2.5检测系统方案与传感器仿真模型选型2.1 粉尘传感器用电压节点模拟GP2Y1010的输出实物项目里最常见的粉尘传感器是夏普GP2Y1010AU内部红外LED照射空气光敏二极管把散射光强度换成电压输出。输出电压与粉尘浓度近似线性越脏电压越高典型关系是0.5V对应50µg/m³0.9V对应100µg/m³。Proteus元件库里没有GP2Y1010也不可能有真正的颗粒散射模型所以比较省事的替代方案是放一个电位器POT-HG中心抽头输出0到5V可调电压接在ADC输入引脚。电位器滑条往上调等效粉尘浓度升高整条链路的表现和真实传感器一致。在程序里做映射时需要先决定满量程关系。这里用ADC0809做8位量化参考电压5V数字0对应0V数字255对应5V。把PM2.5浓度范围设为0到500µg/m³电压0V对应05V对应500换算公式写成#define PM25_FS 500.0f /* 满量程浓度 500ug/m3 */ #define ADC_VREF 5.0f /* 参考电压 5V */ float pm25_volt adc_raw * ADC_VREF / 255.0f; float pm25 pm25_volt / ADC_VREF * PM25_FS;逻辑说明先把ADC原始值还原成电压这一步避免以后调整量程时弄混量纲再按线性比例转成浓度。这样在Proteus里把电位器电压调到3.3V屏幕显示约为330µg/m³可以和直流电压表读数互相印证排查是哪一段转换出错。参数说明ADC_VREF必须和Proteus中ADC0809的VREF引脚一致否则会看到电压表数值和LCD显示值系统性偏差PM25_FS在实物移植时要按照传感器数据手册里的灵敏度重新标定仿真里先给500只作为默认满量程。2.2 温湿度传感器为什么选DHT11而不是DS18B20温度部分用DS18B20也能测但PM2.5检测系统一般要求同时读湿度和温度DS18B20没有湿度所以选DHT11更合适。Proteus自带DHT11模型数据引脚通过单总线连接单片机P1.0内部包含NTC和电容式湿度传感器。需要留意的是Proteus对DHT11时序判断比较严格起始信号低电平时间要维持在18ms左右读每一位时的延时也要卡准。如果当前Proteus版本里的DHT11模型不稳定一个变通做法是把温度、湿度做成两路电压源再走两个ADC通道程序里直接按电压映射成工程单位。这种方案能绕过时序问题但练不到单总线协议所以在LCD调试阶段临时用可以最终代码必须回到标准DHT11时序。2.3 元件选型表与Proteus使用注意为避免在protues仿真画图时逐个翻库常用器件清单如下功能元件/库名参数与作用仿真注意主控AT89C518位单片机双击后把Clock Frequency设为12MHz粉尘模拟POT-HG电位器分压输出0~5V滑条调节要缓慢避免仿真发散ADCADC08098位逐次逼近ADCVREF接5VVREF-接地温湿度DHT11单总线数字温湿度数据脚加10k上拉显示LM016L两行16字符LCD可加对比度电位器串口VIRTUAL TERMINAL虚拟终端RX接单片机TXDTX接RXDProteus版本建议使用8.9以上老版本在ADC0809和DHT11同时仿真时容易出现总线不释放尤其是DHT11模型需要反复复位才能读到数据。如果打开工程后元件引脚乱飞右键元件选择“分解”再重新连线。电位器POT-HG在仿真运行时拖动滑条偶尔会触发“仿真发散”报错原因是步进电压跳变太快解决方法是把仿真步长减小或者改用键盘方向键慢慢调整。3. 在Proteus里搭出PM2.5采集与显示电路的关键参数3.1 单片机最小系统晶振、复位和P0上拉别抄错AT89C51的时钟电路用12MHz晶振晶振两端各接22pF电容到地。复位电路使用10µF电解电容和10kΩ电阻串联上电瞬间RST为高电平随后被电容下拉到低电平实现上电复位手动复位按键并联在电容两端。P0口内部是开漏结构输出高电平能力很弱所以LCD数据总线接在P0上时必须加8个10kΩ上拉电阻到5V否则仿真图里看着正常实物的高电平可能只有2VLCD直接花屏。晶振频率还影响串口波特率。如果后面要用虚拟终端打印ADC电压建议把晶振设成11.0592MHz而不是12MHz因为11.0592MHz能够被4800和9600整除串口帧才不会累积误差。DHT11的延时函数按12MHz计算结果也兼容差异在微秒级不影响读取位宽。3.2 ADC0809的信号输入和启动时序ADC0809的8个通道可以扩展多路模拟量这里只用IN0接电位器中心抽头IN1留作备用以后想加甲醛传感器时不用重画图。通道地址线A、B、C分别接单片机P1.0、P1.1、P1.2。ALE与START合成一个控制脚由单片机输出正脉冲启动转换EOC接P1.3转换结束后输出低电平单片机查询电平变化OE接P1.4置高电平时打开数据输出。CLK引脚必须送一路方波典型频率范围在10kHz到1280kHz之间Proteus里可以用信号发生器输出500kHz方波。接线关系整理如下ADC0809引脚接到说明VREF5V参考电压决定满量程VREF-GND参考地IN0POT-HG中心抽头模拟PM2.5粉尘电压A/B/CP1.0~P1.2通道地址ALE/STARTP1.5启动转换脉冲EOCP1.3转换结束标志OEP1.4输出使能CLK500kHz方波转换时钟D0~D7P0口经上拉8位数据总线这里特别提醒不要直接拿单片机ALE引脚作为ADC0809的CLK。ALE频率是晶振的六分之一12MHz下为2MHz超过ADC0809最大允许值1280kHz转换结果会乱跳。Proteus里放一个信号发生器最省事参数设为500kHz、5V方波DC Offset设2.5V或0V都行只要高低电平满足TTL阈值。3.3 LCD1602、按键和报警电路LCD1602数据线D0到D7接P0口RS接P2.0RW接P2.1E接P2.2。RW接地可以只写不读省下一个引脚但没法读取忙标志所以每次写指令前必须做固定延时仿真里如此实物也一样可用。VEE通过10k电位器调整对比度Proteus中调到约1V时显示最清晰。报警部分用PNP三极管驱动有源蜂鸣器单片机P2.3经1kΩ电阻接到三极管基极。Proteus的有源蜂鸣器模型不一定每台电脑都能发声我通常在蜂鸣器两端并联一个LED灯光闪烁表示报警已经触发。三个按键分别接P2.4到P2.6按下拉低用来调整PM2.5浓度报警阈值按键消抖在仿真里可以省略但代码里仍然保留10ms延时方便之后移植到真实板子。ADC0809的启动脉冲用代码控制比较干净初始化后执行一段短脉冲void adc_start(void) { AD_ALE 0; AD_START 0; AD_ALE 1; AD_START 1; /* 高电平有效持续10us */ AD_ALE 0; AD_START 0; }逻辑说明ADC0809要求ALE下降沿锁存通道地址START上升沿复位内部逐次逼近寄存器下降沿启动转换。上面的顺序把地址稳定、锁存和启动合并在一起可以避免单独控制ALE时出现通道窜位。参数说明启动脉冲高电平时间建议大于200ns这里用两条空语句延时的宽度在微秒级足够可靠。如果仿真中ADC不启动先用虚拟示波器看ALE和START引脚波形确认确实出现正脉冲而不是程序运行到了某个死循环。4. 单片机C程序、DHT11时序和PM2.5浓度换算4.1 主循环与ADC0809多通道读取主程序流程放在while循环里启动ADC转换等待EOC变低读取8位数据换算PM2.5浓度再读DHT11得到温湿度最后刷新LCD并扫描键盘。ADC0809的多通道切换靠地址线读取IN0时地址必须是000。如果忘记切换ADC可能保持上一次通道的数据仿真中表现为调整电位器但显示值不变。unsigned char adc_read(unsigned char ch) { unsigned char result; P1 0xF8; /* 清低三位地址 */ P1 | (ch 0x07); /* 写入通道号 */ AD_ALE 0; AD_START 0; delay10us(); AD_ALE 1; AD_START 1; delay10us(); AD_ALE 0; AD_START 0; while (AD_EOC 0); /* 等待转换完成 */ AD_OE 1; result P0; /* 从P0口读回8位结果 */ AD_OE 0; return result; }逻辑说明读取前清P1低三位再写通道号可以有效防止其他引脚上的旧状态干扰通道选择。转换结束后OE置高才能打开输出锁存器否则数据线仍然处于高阻状态P0口会读到0xFF。参数说明ch的取值范围是0到7对应IN0到IN7。本设计只用ch0以后扩展DHT11后备模拟方案时可以把ch改为1。ADC结果和电压的关系是电压 adc_result * 5 / 255参考电压变化时该比例必须同步修改。4.2 DHT11读取函数的起始信号和位判断DHT11单总线协议比较啰嗦。主机先把数据线拉低至少18ms再释放并延时20µs随后DHT11会拉低响应信号之后连续输出40位数据湿度整数、湿度小数、温度整数、温度小数和校验和。每一位的区分不在低电平而在高电平宽度高电平约50µs是0约70µs是1。unsigned char dht11_read_byte(void) { unsigned char i, value 0; for (i 0; i 8; i) { while (DHT11_PIN 0); /* 等待低电平结束 */ delay_us(40); /* 跳过0位的高电平前半段 */ if (DHT11_PIN 1) /* 40us后仍为高表示1 */ { value | (0x80 i); while (DHT11_PIN 1); /* 等待该位结束 */ } } return value; }逻辑说明每一位起始都是50µs低电平之后高电平宽度是区别位值的关键。程序先等低电平结束然后延时40µs此时如果是0位高电平已经结束读到低电平如果是1位高电平还在读到高电平。这种写法比反复测量脉宽更稳定尤其适合Proteus模型。参数说明delay_us(40)要按晶振频率实际调整。Keil C51在高优化等级下可能把空循环延时函数优化掉导致DHT11永远读不到数据。解决办法是用关键字volatile修饰循环变量或者在函数前使用#pragma NOINLINE避免内联保证延时真实执行。读取40位数据后主程序需要校验湿度高位加湿度低位加温度高位加温度低位低8位必须等于校验字节。如果校验失败显示上一次成功读数比显示乱码更有实际意义。我在实物调试时会连续读3次取中间值确保偶发错误不会让LCD上的数据跳变。4.3 用虚拟终端观察ADC原始值和浓度换算仿真阶段建议不要只盯LCD而是同时打开Proteus的Virtual Terminal把ADC原始值、电压值和PM2.5浓度都用串口打出来。这样每拨一次电位器能立刻看到哪一步换算发生变化排查问题比来回刷新LCD快得多。printf(raw%03d, volt%.2f, pm25%.1f\r\n, adc_raw, pm25_volt, pm25);逻辑说明Keil C51的printf默认走串口0因此这条代码在仿真里就是在往单片机TXD引脚发送数据。虚拟终端必须和单片机的TXD、RXD交叉连接波特率设成9600、8位数据、1位停止位、无校验。如果虚拟终端只显示空白先检查串口初始化函数是否调用过再检查晶振频率是否设置成11.0592MHz。参数说明%.2f和%.1f在Keil C51中需要开启浮点格式支持如果不希望引入浮点库可以把电压和浓度都放大10倍用整型发送接收端再除以10这样能省不少代码空间。5. 仿真发散后的排查阈值迟滞与虚拟标定5.1 给报警阈值加迟滞避免临界抖动常见的报警逻辑是PM2.5浓度超过阈值就报警低于阈值就关闭。仿真中电位器滑条在阈值附近微调时ADC数值会来回跳蜂鸣器和报警灯跟着忽闪忽闪。给阈值设置两个边界是最直接的办法。设报警阈值为100µg/m³当浓度超过100时报警低于90时解除中间10µg/m³是迟滞区间if (pm25 alarm_threshold) { alarm_enabled 1; } else if (pm25 (alarm_threshold - 10)) { alarm_enabled 0; }逻辑说明两个条件之间留出间隙让系统在100到90之间保持之前的报警状态从而消除边界抖动。10µg/m³这个值不是固定不变的传感器噪声大时适当加大到15或20。参数说明报警阈值由三个按键调节键值需要放全局变量里保存。仿真中可以通过虚拟终端打印报警标志来判断是否进入迟滞区间而不必观察蜂鸣器能不能听到声音。5.2 用电压表做虚拟标定PM2.5浓度和电压的线性关系来自数据手册但Proteus里电位器输出电压不一定精确到小数点后三位。比较稳妥的验证方法是在电位器中心抽头处放一个DC Voltmeter读取当前电压再对照虚拟终端输出的pm25字段。例如电压表显示2.5V终端应该输出约250µg/m³如果偏差超过5%优先检查ADC_VREF宏定义和VREF引脚接线。实际温度湿度同理DHT11在Proteus中给出的读数默认为环境仿真值为了主动模拟高温高湿环境可以断开DHT11的数据脚用两个电位器分别接ADC通道临时顶替。定标完成后记得把DHT11的数据脚重新连回P1.0并把通道地址改回0。5.3 从仿真到实物移植时的验证参数仿真能验证逻辑但传感器差异必须靠实物修正。GP2Y1010数据手册里的输出电压并不是完美直线低浓度段灵敏度高高浓度段趋于饱和所以实物里建议用两段折线查表而不是单一满量程乘系数。第一段0到100µg/m³用斜率较大的公式第二段100到500µg/m³降低斜率。将这个分段表写入常量数组后再在Proteus里把电位器电压按分段节点回扫一遍确认LCD显示值与预期值误差小于5µg/m³就能收工。本文还有配套的精品资源点击获取
返回列表