STM32单片机PM2.5空气净化器毕业设计:采集、调速与上位机监控
简介:这份资源是面向电气工程、自动化及嵌入式相关专业学生的STM32空气净化器毕业设计完整文档,围绕PM2.5居高不下的室内空气治理需求,给出一套办公室用空气净化器控制系统的软硬件设计方案,适合正在选题、撰写论文或复现同类项目的读者参考。压缩包内为1个docx文件,大小约2.19MB,内容涵盖中英文摘要、绪论、控制器总体方案与方案论证、硬件电路设计、软件子程序设计及整体测试等章节,并附有传感器、开发板选型与功能验证的设计论述。资源已有4245人学习下载,说明其在同类毕业设计选题中认可度较高。读者可从中获取STM32最小系统、TFT_LCD显示、L298N驱动、DHT11温湿度与SDS011激光传感器的电路连接思路,以及主程序、PWM输出、数据采集、上位机控制台等模块化编程框架和触屏控制、档位选择、无线通信的测试结论,便于对照搭建硬件平台、梳理论文结构与排查调试问题。
1. 从办公室的PM2.5说起:这套基于STM32单片机的空气净化器毕业设计要解决什么
办公室里的空气问题很具体:门窗常闭、人员密集、打印机持续吐出细微颗粒,PM2.5 常年在一个不上不下的区间浮动。成品净化器要么只给一个红黄绿的指示灯,要么档位切换逻辑像个黑匣子,说不清它什么时候该提速。这份基于STM32单片机的空气净化器毕业设计,做的就是"测—判—调—显"这条完整链路:SDS011 激光传感器测颗粒物、DHT11 测温湿度、STM32F103ZET6 做决策、L298N 驱动风机、TFT_LCD 带触屏做交互,再通过无线模块把数据送进上位机控制台。它适合两类人:一是要交一份硬件、软件、上位机三件套齐全的毕设,需要能开机演示、能对着表格讲数据的同学;二是要把课程设计做成一台可调速、可触屏、可远程看数的样机,后面还能改造成别的控制项目的从业者。这篇不聊概念,只讲这套方案怎么搭、坑在哪、怎么验收。
2. 总体方案与技术选型:六个模块的职责划分与四组对比论证
方案设计这块最容易写成"我选了STM32因为STM32好"的流水账。真正决定后面三个月的返工量的,是模块边界划得清不清、选型理由站不站得住。这一章把系统的六个组成部分、职责边界,以及四组关键器件的取舍讲透,后面画图和写代码都是照着这张骨架来的。
2.1 系统总体架构与六个模块的职责边界
整体由供电电路、数据采集电路、驱动电路、按键电路、显示电路、上位机控制电路六部分组成。架构上分三层来看更清楚:底层是供电与执行,中间层是主控与采集,上层是人机交互与上位机。
供电层给出两路电压,一路直接给风机用的较高电压轨,另一路降压到 5V 给显示、传感器和驱动模块的逻辑侧供电,再由板上稳压出 3.3V 给主控和触摸芯片。执行层就是风机回路加 L298N,接受 PWM 占空比控制。中间层以 STM32F103ZET6 为核心,向下通过串口读 SDS011、通过单总线读 DHT11,向上通过并口或 SPI 刷 TFT_LCD,同时留一路串口给无线透传模块,把实时数据推给上位机。交互层就是触屏加少量物理按键,负责开关机、档位、模式切换。
这里有个容易被忽略的边界问题:数据采集和显示如果耦合在一起,屏幕一刷新就可能拖慢采集节奏,串口就会丢包。所以设计时采集走中断或独立缓冲,显示走主循环定时刷新,两者只通过一个全局数据结构交换数据。这个约定我在方案阶段就写进文档里,后面调试能省下大把时间。
提示:模块划分不只是画图好看,它决定了变量归属和中断优先级。采集相关的缓冲归采集模块所有,显示模块只读不写,这条规则定死了,调试期就少一类玄学问题。
2.2 主控与显示:为什么 STC12 撑不住、LCD12864 不够用
主控对比的是两套方案。一套是 STC12 系列,工作方式和传统 51 内核相仿,通过分频可以跑到较高主频,通用 I/O 口多、封装有贴片和直插两种、带 PCA 高速输出,做基础控制够用。但它资源有限、处理速度相对 32 位内核偏慢,最关键的是带不动 TFT_LCD 这种 320×240 的彩屏刷新,触屏功能更谈不上。另一套是 STM32 系列,主频到 72MHz,内部集成 FLASH 和 64K SRAM,带 RTC 时钟电路,有多个串行通讯端,能同时对接 PM2.5 传感器和上位机,还能驱动并口彩屏。本设计选 STM32F103ZET6,基于 Cortex-M3 内核,引脚资源足以支撑触屏、串口、PWM 同时工作。
显示对比的是 LCD12864 和 TFT_LCD。前者是 128×64 点阵,多线串行接口,能显示字符和汉字,但可显示字数有限、时序位置操作繁琐、显示效果简陋,且不支持触控。后者分辨率 320×240、16 位真彩、字号和颜色可编程,能分行分段显示批量数据,配合触摸控制芯片就能实现触屏。控制方式确实更复杂,但换来的交互能力是这个方案的核心卖点。
| 对比项 | STC12 系列 | STM32F103ZET6 | LCD12864 | TFT_LCD(320×240) |
|---|---|---|---|---|
| 主频 | 分频后最高约 35MHz | 72MHz | — | — |
| 存储 | 资源有限 | 片内 FLASH + 64K SRAM | 无 | 无 |
| 串口数量 | 少,难并行 | 多路,可同时接传感器与上位机 | — | — |
| 显示能力 | 无法驱动彩屏 | 可驱动并口彩屏 | 128×64 点阵,字数受限 | 16 位真彩,可自定义字号 |
| 触控 | 不支持 | 支持外接触摸芯片 | 不支持 | 支持 |
| 结论 | 力不从心 | 选用 | 不满足 | 选用 |
2.3 驱动与传感器:电压可调怎么实现,PM2.5 怎么测准
"电压可调式"这个说法听起来像要加个数控电源,实际实现要简单得多:用 PWM 斩波改变风机两端的平均电压。L298N 是双路电机驱动模块,输入端接受 PWM,输出端连续可调,能同时驱动两路电机,还能对外提供 5V 电源接口,价格便宜、控制逻辑简单。它的短板是工作电流大、需要装散热片,这一点在结构设计时就得留出散热空间。另一套方案 LM2596 是降压模块,输入范围宽、输出连续可调、带大电容滤波,但它只能靠手动旋钮调节,想用电子方式调压得额外加控制电路,反而更繁琐。所以驱动选 L298N。
PM2.5 传感器对比的是红外反射式和激光散射式。前者中间开一个气体流通圆孔,靠红外发光二极管和反射原理判断灰尘含量,输出与粉尘浓度成正比的模拟电压,需要 A/D 转换后再换算,价格便宜但对 PM2.5 这类微小颗粒不够敏感。后者依据激光散射原理,激光照射悬浮颗粒产生散射,感光部件根据散射波形判断颗粒直径,再按换算公式转成统一单位,通过串口按固定波特率输出十六进制数据,单片机里转成十进制即可。精度高、响应快,代价是价格略高。本设计选激光方案,理由是这套系统的档位判断依赖颗粒物浓度的变化趋势,传感器分辨率不够,自动模式就没法做。
PWM 输出这一层的初始化大致是下面这个样子,用的是通用定时器通道,配置成 1kHz 左右的斩波频率,占空比由档位映射表给出:
/* 风机 PWM 初始化:TIM3_CH1,频率约 1kHz,分辨率 1000 级 */ void FanPwm_Init(void) { GPIO_InitTypeDef gpio; TIM_TimeBaseInitTypeDef tb; TIM_OCInitTypeDef oc; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); /* PA6 复用推挽输出,接 L298N 的 ENA 使能端 */ gpio.GPIO_Pin = GPIO_Pin_6; gpio.GPIO_Mode = GPIO_Mode_AF_PP; gpio.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &gpio); /* 72MHz / 72 = 1MHz 计数频率,计满 1000 即 1kHz */ tb.TIM_Period = 999; tb.TIM_Prescaler = 71; tb.TIM_ClockDivision = TIM_CKD_DIV1; tb.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &tb); oc.TIM_OCMode = TIM_OCMode_PWM1; oc.TIM_OutputState = TIM_OutputState_Enable; oc.TIM_Pulse = 0; /* 上电默认停转 */ oc.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &oc); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_Cmd(TIM3, ENABLE); } /* 档位映射:0 停机,1~5 档对应 200~1000 的比较值 */ void Fan_SetGear(uint8_t gear) { static const uint16_t duty[6] = {0, 200, 400, 600, 800, 1000}; if (gear > 5) gear = 5; TIM_SetCompare1(TIM3, duty[gear]); }两个函数分工明确:初始化负责时钟、引脚模式和定时器基准,Fan_SetGear只做查表赋值。把档位和占空比拆成表的好处是,后面实测发现某档风速偏大或偏小,改表里的数就行,不用动逻辑。另外 IN1、IN2 两个方向脚固定成一个电平组合,风机只做单向调速,不做正反转,这样接线和逻辑都最简。比较值给到 1000 是满占空,实际调试时通常不会拉满,留一点余量给电压波动。
3. 硬件电路设计:最小系统、显示、驱动与两路采集接口
硬件这块的目标不是画得漂亮,是画完能一次打板点亮、出问题能对着原理图定位。下面按信号流向从主控往外讲,每部分给出关键连接关系和容易踩的参数。
3.1 主控最小系统与供电拓扑
最小系统包含电源、复位、晶振、启动配置四部分。STM32F103ZET6 的电源引脚分数字电源和模拟电源两组,每组都要就近放 0.1μF 去耦电容,模拟电源那组再并一个 1μF 或 10μF 的储能电容,否则 A/D 采样值会飘。外部晶振用 8MHz,负载电容按晶振规格书给,通常 20pF 上下,晶振走线尽量短、包地、远离风机驱动线。复位电路是 10k 上拉加 0.1μF 电容到地,再加一个手动复位按键。启动配置的 BOOT0 通过电阻下拉到地,保证从主 FLASH 启动。
供电拓扑要单独说。整机一路较高电压给风机,一路降到 5V 给显示和传感器,5V 再经线性稳压到 3.3V 给主控。风机是感性负载,启动瞬间电流能到额定值的数倍,如果和主控共用一条地线且走线很长,地电位会被抬起来,表现为单片机偶发复位或者串口乱码。常规做法是风机电源和逻辑电源在电源入口处单点连接,各自走独立的粗线,滤波电容靠近负载端放。
注意:打板前一定核对稳压芯片的压差和散热。5V 降到 3.3V 如果整机电流偏大,线性稳压会明显发热,必要时换成开关电源方案或加散热焊盘。
3.2 TFT_LCD 与触屏接口
320×240 的彩屏常用的接法是并口数据线加控制线:数据总线若干位、写信号、读信号、片选、复位,再加背光控制。并口的好处是刷屏快,全屏刷新对主频的压力小;代价是占用引脚多。这个项目用的是 100 脚以上的封装,引脚够用,所以并口是可以接受的方案。
触摸部分用 SPI 接口的电阻触摸控制芯片,四线制,输出的是原始 AD 值,需要做两点校准才能映射到屏幕坐标。校准通常在首次上电时引导用户点四个角,把四个点的原始值存进 FLASH,之后每次读到的坐标都用这组参数换算。省掉校准直接写死经验值,换一块屏坐标就偏,这是后面调试章节要展开的问题之一。
背光一般用三极管或 MOS 管做开关,由主控一个 I/O 控制,方便做息屏省电。这里加一个限流电阻,阻值按背光模组的额定电流算,别直接拿 I/O 去驱动背光,那点驱动能力不够。
3.3 L298N 驱动与风机回路
L298N 这边关键引脚是逻辑电源、电机电源、使能端、两个方向输入端和地。使能端接主控的 PWM 引脚,方向端固定成一组电平,输出端接风机。模块自带的 5V 输出可以给逻辑侧供电,但要注意它的输出能力有限,如果整机 5V 负载比较大,还是单独给一路 5V 更稳妥。散热片必须装,实测中档以上连续跑十几分钟,芯片表面温度上升很明显,长期运行要把这点写进使用说明。
风机回路上并一个续流二极管是必要的,感性负载断电瞬间会产生反向尖峰,没有泄放路径就可能打穿驱动管或者干扰主控。模块内部一般有二极管,但如果风机功率较大,外部再加一个更保险。另外风机线尽量远离传感器和晶振,走线不要平行走长距离。
3.4 DHT11 单总线与 SDS011 串口
DHT11 是单总线器件,一根线完成通信。主机先拉低总线不少于 18ms 作为起始信号,然后释放,器件响应后连续输出 40 位数据:湿度整数、湿度小数、温度整数、温度小数、校验和。校验和等于前四个字节相加取低八位。读取时序对延时精度要求高,微秒级延时必须准,用系统滴答定时器或者校准过的软件延时。
/* DHT11 读取一次,成功返回 0,失败返回错误码 */ uint8_t DHT11_Read(uint8_t *temp, uint8_t *humi) { uint8_t buf[5] = {0}; uint8_t i, j; DHT11_Start(); /* 主机拉低 18ms 后释放 */ if (DHT11_WaitResp() != 0) /* 等器件拉低 80us 再拉高 80us */ return 1; for (i = 0; i < 5; i++) { for (j = 0; j < 8; j++) { /* 每位以 50us 低电平开始,高电平长短区分 0 和 1 */ while (DHT11_PinRead() == 0); DelayUs(40); /* 40us 后仍为高则判为 1 */ buf[i] <<= 1; if (DHT11_PinRead() == 1) { buf[i] |= 1; while (DHT11_PinRead() == 1); } } } if ((uint8_t)(buf[0] + buf[1] + buf[2] + buf[3]) != buf[4]) return 2; /* 校验失败 */ *humi = buf[0]; *temp = buf[2]; return 0; }这段代码的重点在两处:一是DelayUs(40)这个判位窗口,太短会把 1 误判成 0,太长会把 0 误判成 1;二是校验和的判断,温湿度这种慢变量偶尔读错一次影响不大,但必须有校验,否则界面上会跳出一个离谱的数字。实际使用中两次读取之间至少间隔 1 秒以上,器件本身刷新率就低,读太密只会拿到重复值。
SDS011 走串口,波特率固定 9600,周期性主动上报 10 字节的数据帧。帧头是固定的两个字节,后面依次是 PM2.5 低字节、PM2.5 高字节、PM10 低字节、PM10 高字节、设备 ID 两个字节、校验和、帧尾。校验和是数据字段几个字节之和取低八位。接线上把传感器的发送端接主控的接收端,接收端接发送端,共地。供电用 5V,注意它的启动电流比稳态电流大,电源余量要给足。
4. 软件设计:主程序框架与五个子程序的落地方式
软件这块我一般按"一个主循环 + 若干定时任务 + 若干中断服务"来组织,不追求上完整的实时操作系统,因为这套系统任务数量有限,裸机加状态机完全够跑,还少一层调试成本。原文提到基于嵌入式操作系统做模块化编程,落到实现上就是文件级分层:每个外设一个驱动文件,每个功能一个应用文件,头文件只暴露接口。
4.1 主程序流程与模块化分层
主程序干三件事:初始化、进主循环、在循环里按节拍调度任务。初始化顺序有讲究,先时钟和 GPIO,再延时和串口,然后是显示、传感器、定时器,最后开中断。顺序反了会出现外设已经使能但时钟没开的情况,现象是死等。
主循环里的任务用节拍计数来分频:10ms 一次的任务处理按键和触屏扫描,100ms 一次的任务处理数据采集与状态判断,200ms 一次的任务刷新显示。采集和显示分属不同节拍,屏幕刷新慢一点不会堵住串口收包,因为串口数据是靠中断收进环形缓冲的。
int main(void) { SystemInit(); Delay_Init(); /* 滴答定时器,提供 us/ms 延时 */ Uart1_Init(9600); /* SDS011 */ Uart2_Init(9600); /* 无线透传模块 */ LCD_Init(); Touch_Init(); DHT11_Init(); FanPwm_Init(); Key_Init(); Timer_Init(); /* 提供 1ms 系统节拍 */ SysState_Load(); /* 从 FLASH 读回档位、模式、校准参数 */ while (1) { if (Flag_10ms) { Flag_10ms = 0; Key_Scan(); Touch_Scan(); } if (Flag_100ms) { Flag_100ms = 0; Sensor_Task(); Ctrl_Task(); } if (Flag_200ms) { Flag_200ms = 0; Ui_Refresh(); Comm_Report(); } } }这里Flag_10ms这些标志由定时器中断置位,主循环只负责消费。好处是每个任务的执行周期是确定的,不会因为某个任务耗时长而整体漂移。Ctrl_Task是决策核心,读当前 PM2.5 值、判断模式、算目标档位、调 PWM;Ui_Refresh只读全局状态结构体,不直接碰硬件,这样界面改版不用动控制逻辑。
4.2 SDS011 帧解析与校验
串口中断里只做一件事:把字节塞进环形缓冲,然后退出。解析放在主循环的Sensor_Task里做,这样中断服务时间短,不会影响其他中断响应。解析用状态机找帧头,找到后连续取 10 个字节,校验通过才更新数据。
/* 从环形缓冲取一帧,成功返回 1 并填充 pm25 / pm10 */ uint8_t Sds011_Poll(uint16_t *pm25, uint16_t *pm10) { uint8_t b, buf[10], i; static uint8_t idx = 0; while (Ring_Get(&b)) { if (idx == 0 && b != 0xAA) continue; /* 等帧头第一字节 */ if (idx == 1 && b != 0xC0) { idx = 0; continue; } buf[idx++] = b; if (idx == 10) { idx = 0; if (buf[9] != 0xAB) return 0; /* 帧尾不对,丢弃 */ /* 校验和 = 第 2~7 字节之和的低八位 */ uint8_t sum = 0; for (i = 2; i < 8; i++) sum += buf[i]; if (sum != buf[8]) return 0; *pm25 = (uint16_t)(buf[2] | (buf[3] << 8)); /* 低字节在前 */ *pm10 = (uint16_t)(buf[4] | (buf[5] << 8)); return 1; } } return 0; }三处校验一层层收紧:帧头两字节、帧尾一字节、中间的累加和。少任何一层,都可能把一次错位的数据当成有效浓度,界面上就会突然跳到几百。数据是低字节在前,拼的时候别写反。设备 ID 两个字节这个项目没用到,跳过即可。
4.3 档位映射与自动模式策略
手动模式直接查表,一键一档。自动模式需要一个不会来回跳的判断逻辑,最忌讳的是"浓度超过阈值就升档、低于阈值就降档"这种双边一刀切,结果是在阈值附近反复切换,风机声音忽大忽小。
我一般的做法是加回差和驻留时间:设两个阈值,高于上限升档,低于下限降档,中间区间保持不动;同时规定每次换档后至少保持 30 秒才允许下一次换档。这样浓度在阈值附近波动时,档位是稳的。
| 档位 | PWM 比较值 | 适用场景 | 自动模式触发条件 |
|---|---|---|---|
| 0 | 0 | 关机 | — |
| 1 | 200 | 夜间、无人 | PM2.5 低于下限且持续 30s |
| 2 | 400 | 日常轻度污染 | 默认起始档 |
| 3 | 600 | 中度污染 | 高于上限一档 |
| 4 | 800 | 重度污染 | 高于上限两档 |
| 5 | 1000 | 应急强排 | 高于上限三档并持续 60s |
提示:阈值不要拍脑袋定。先让样机跑一段连续记录,把一天里浓度的波动范围看清楚,再定上限和下限,回差宽度取波动幅度的 1.5 倍左右比较稳。
4.4 显示界面与触屏事件处理
界面分三个页面:主界面显示 PM2.5、PM10、温湿度、当前档位和模式;设置页调档位和自动模式开关;状态页显示运行时长和设备信息。页面切换用状态变量控制,每个页面一个绘制函数,切页时整屏重绘一次,页内只刷新数值区域。
触屏事件的难点在防抖。电阻屏的原始值会有几个像素的抖动,按下和抬起之间还可能连续上报。处理方式是:读到按下后延时 20ms 再确认,坐标做几次平均,然后与上一次有效坐标比较,偏移在阈值内就认为是同一次按压。按键响应只在抬起时触发一次,避免长按被当成连击。
数值刷新也有讲究。整屏重绘一次耗时较长,如果每 200ms 全屏刷一次,会明显看到闪烁。做法是把每个数值区域的背景和字符宽高固定,刷新时先填底色再写新值,只重绘变化的那一小块。
4.5 上位机控制台与无线通信协议
上位机用 C# 写串口助手式的控制台,功能是三块:实时数据显示、历史曲线、远程下发指令。下位机通过无线透传模块把数据打包上报,模块对主控来说就是一个串口,配置好波特率和信道后透传字节流。
协议设计得越简单越好,一条上报帧大致是:帧头、帧类型、PM2.5 高低字节、PM10 高低字节、温度、湿度、档位、模式、校验、帧尾。下发帧是帧头、命令字、参数、校验、帧尾。命令字至少要有开关机、设档位、切模式、读状态四条。上下位机用同一套校验规则,出错就整帧丢弃,不要试图纠错,串口这层的重发成本很低,上位机隔几百毫秒再要一次就行。
上位机侧要注意串口读数据用事件触发而不是死循环轮询,否则界面会卡;数据到齐后放到界面线程更新,跨线程更新控件要做调度,不然会抛异常。历史曲线按固定点数滚动,超过就丢弃最老的点,不要无限追加,内存会一直涨。
5. 避坑与排查:调试阶段最容易翻车的五个点
这一章写的都是实测里真发生过的。共同特征是现象看着像硬件坏了,实际原因往往在时序、地线或者参数上。按"现象—原因—解决"的顺序记下来,遇到同类问题可以照着排查。
5.1 串口收包错位,浓度值突然跳到几百
现象是界面上的 PM2.5 数字偶尔蹦出一个明显不合理的值,几秒后自己恢复。原因是解析时只判了帧头没判帧尾和校验和,一次丢字节之后状态机错位,把数据段当成了帧头。解决办法是三层校验全部加上,并且状态机在超时后强制归零重新找帧头,不能一直停留在中间状态。另外环形缓冲的读写指针要用原子操作或者关中断保护,主循环和中断同时改指针,迟早出问题。
5.2 风机一启动,传感器就复位或者数据乱跳
现象是手动切到高档,PM2.5 读数瞬间变成 0 或者直接不更新。原因通常是两个:一是风机启动瞬间的电流冲击把 5V 拉低,传感器欠压复位;二是风机的地线和传感器的地线共用一段细走线,大电流在地线上产生压降,传感器参考地被抬高。解决办法是电源入口单点共地、风机单独走粗线、传感器电源端就近加 100μF 电解电容加 0.1μF 瓷片电容,风机两端加续流二极管。改完之后再测,波动明显收敛。
5.3 触屏坐标偏移,点左边跳到右边
现象是换了块屏或者重新装配之后,触摸位置整体偏移。原因是校准参数是写死的经验值,而每块触摸屏的阻值都有离散性。解决办法是做四点校准,把原始 AD 值和屏幕坐标的对应关系存进 FLASH,开机读回来用。校准流程要考虑用户误操作,可以加一个"恢复默认"入口。另外触摸线要远离 PWM 走线,否则读数会带噪声,表现为点击位置轻微抖动。
5.4 档位切换时风机啸叫,低档位尤其明显
现象是低档运行时能听到明显的蜂鸣声,中高档反而正常。原因是 PWM 频率落在了人耳敏感区间,同时低占空比下风机转矩脉动大。解决办法是把斩波频率提到 20kHz 以上,超出听觉范围;如果驱动模块响应跟不上,就退一步用 1kHz 但在风机两端并联电容做滤波。另外低档占空比不要设得太低,低于风机启动转矩时会转不动,表现为有声音但不转,反而更吵。
5.5 整机跑一段时间后死机,重启又正常
现象是连续运行几十分钟后,界面卡住或者程序跑飞。原因可能是堆栈溢出、数组越界,也可能是看门狗没开导致一次偶发干扰后无法自恢复。解决办法是先把看门狗打开,喂狗放在主循环里,任何一个任务卡死都能复位;再用调试器看复位原因寄存器,区分是上电复位、看门狗复位还是硬件异常。数组越界这类问题在裸机上不容易暴露,养成所有接收缓冲都做长度检查的习惯,血泪经验。
6. 验收与答辩:用一张测试表把结论讲实
验收这件事,很多人栽在"我做完了但说不清怎么证明它做完了"。答辩老师问的不是你用了什么芯片,而是"你怎么知道它测出来是对的、档位切换是有效的"。所以测试表要在动手做之前就想好,测完把数据填进去,讲的时候照着念都行。
我的做法是把测试拆成四类,每类给明确的判定标准。第一类是精度类,把样机和一个参考测量值放在同一环境里比对,记录偏差范围,不用追求绝对准确,讲清偏差在可接受区间内即可。第二类是功能类,逐条对照任务书的功能点,开关机、档位切换、模式切换、触屏、上位机通信,每条给通过或不通过。第三类是稳定性类,连续运行一段时间,记录复位次数和通信丢包率。第四类是响应类,人为制造浓度变化,看档位在多长时间内跟上。
| 测试项 | 方法 | 判定标准 | 记录方式 |
|---|---|---|---|
| PM2.5 测量 | 与参考仪器同环境比对 | 偏差在 ±15% 以内 | 每小时记 1 组,共 8 组 |
| 温湿度测量 | 与标准温湿度计比对 | 温度 ±2℃,湿度 ±5%RH | 每 30 分钟 1 组 |
| 档位切换 | 手动逐档切换 | 5 档均能切换,风机转速可辨 | 逐档记录 PWM 值与现象 |
| 自动模式 | 人为改变浓度环境 | 30s 内完成一次换档,无反复跳变 | 记录换档时间点 |
| 触屏操作 | 各页面点击按钮 | 命中率 100%,无偏移 | 每页点 10 次计通过率 |
| 上位机通信 | 连续上报 | 丢包率低于 1% | 统计 1000 帧 |
| 连续运行 | 通电运行 2 小时 | 无复位、无死机 | 记录复位次数 |
答辩讲解的顺序也很关键。我建议按"需求—方案—实现—数据—不足"走:先用一句话说清办公室场景下 PM2.5 监测和净化的实际需求,再讲为什么选 STM32 和激光传感器,接着现场演示触屏切档和上位机曲线,然后用测试表上的数据支撑结论,最后主动说两处不足,比如净化效果只做了浓度趋势验证、滤网寿命没有做检测。主动认下不足反而比被问出来强,显得你知道边界在哪。
实物演示一定要提前彩排。开机顺序、预热时间、无线模块的连接、上位机先开还是先开下位机,这些都要固定成流程写成小纸条贴在样机旁边。演示前把环境浓度弄上去,让自动模式的换档过程在几十秒内能看到,效果比讲十分钟原理都管用。我吃过一次亏,现场空气太干净,自动模式死活不换档,只能尴尬地解释阈值逻辑,从那以后我每次答辩或演示都强制走一遍"预热—制造浓度变化—观察换档—看上位机曲线"这套完整流程,再准备一段录好的视频兜底。希望这套结构和这张测试表能帮到你,把自己的方案讲成一个别人敢照着做的方案。
本文还有配套的精品资源,点击获取