电子工程毕业从选题到实物,最怕“想得美、做不出”。我当年也踩过坑:一上来就想做“智能家居中控”,结果PCB打样三次都起不来,答辩前两周还在飞线救板。痛定思痛,总结了一套“最小可落地”套路,今天用“温湿度+光照远程监测”这个小项目串起来,给还在纠结选题的同学当参考。整篇尽量说人话,能复刻就复刻,能改就改,毕业要紧。
1. 选题阶段最容易踩的坑
功能清单写两页,一查芯片没货
先列BOM再谈创意,别等四月才发现关键器件交期16周。算法仿真很丰满,硬件一跑就跪
没有原型验证的“AI边缘识别”基本等于“PPT毕业”。电源口算5 V,实测掉到4.3 V
板子一上电MCU反复重启,90 %是供电裕量没留够。资料全靠搜“CSDN免费下载”
散碎例程版本对不上,后期调试想死。官方HAL+CubeMX才是亲妈。
2. 技术选型:三分钟看懂主流方案
| 维度 | STM32F103C8T6 | Arduino Uno | ESP32-S3 |
|---|---|---|---|
| 主频 | 72 MHz | 16 MHz | 240 MHz |
| 低功耗 | 20 µA Stop | ~35 mA | 10 µA DeepSleep |
| 外设 | 双ADC+DMA | 单ADC无DMA | 双8-bit ADC |
| 开发环境 | Keac/CubeMX | Arduino IDE | IDF/Arduino |
| 价格 | 6 RMB | 25 RMB | 18 RMB |
结论:
- 想省成本、学寄存器——STM32
- 想三天出demo——Arduino
- 想直接跑Wi-Fi——ESP32
通信模块同理:
- 宿舍到实验室30 m穿墙→LoRa(SX1278)
- 手机直连调参→BLE(nRF52)
- 实时云绘图→Wi-Fi(ESP8266)
电源:
- 锂亚3.6 V + DCDC→LoRa节点半年续航
- 18650 + 锂电保护+USB-C→调试友好
- 干电池9 V叠层→答辩完当天就没电,别选
3. 核心实现:环境监测系统架构
系统目标:每5 min把“温湿度+光照”打包,经LoRa发到250 m外的接收端,电池续航>3个月。
3.1 硬件拓扑
- MCU:STM32L051C8(低功耗)
- 温湿度:SHT30(I²C)
- 光照:BH1750(I²C,同一总线不同地址)
- 通信:SX1278 LoRa模块(SPI)
- 电源:2 x AA 1.5 V → 3.0 V,先DCDC到3.3 V,再LDO给数字/模拟分区
3.2 固件状态机(极简5态)
- 上电初始化 → 2
- 采集传感器 → 3
- 打包待发送 → 4
- 射频发送 → 5
- 深度休眠,RTC唤醒 → 2
状态机用switch-case写,方便打断点;每态超时1 s自动复位看门狗,防止卡死。
4. 带注释的HAL库C代码(关键片段)
以下代码只留“传感器+LoRa”两条主线,去掉了CRC、重传等,保证一页能看完。模块解耦思路:
- 每个外设一个.c/.h
- 返回统一枚举:OK/BUSY/ERROR
- 高层状态机只调抽象接口,方便换芯片
/* main.c 状态机主干 */ typedef enum { ST_INIT=0, ST_READ, ST_PACK, ST_TX, ST_SLEEP } State_t; State_t state = ST_INIT; int main(void) { HAL_Init(); SystemClock_Config(); MX_RTC_Init(); Sensor_Init(); LoRa_Init(); while (1) { switch (state) { case ST_INIT: state = ST_READ; break; case ST_READ: if (SHT30_Update(&env) == SENSOR_OK && BH1750_Update(&lux) == SENSOR_OK) state = ST_PACK; else state = ST_SLEEP; /* 读失败也睡,省功耗 */ break; case ST_PACK: pkt.hum = env.h; pkt.temp = env.t; pkt.lux = lux; state = ST_TX; break; case ST_TX: if (LoRa_Send(&pkt, sizeof(pkt)) == LORA_OK) state = ST_SLEEP; else HAL_Delay(100); /* 稍作延时再试,避免连续撞频 */ break; case ST_SLEEP: HAL_SuspendTick(); HAL_PWR_EnterSTOPMode(PWR_REGULATOR_LOWPOWER, PWR_STOPENTRY_WFI); SystemClock_Config(); /* 唤醒后重配时钟 */ HAL_ResumeTick(); state = ST_READ; break; } } }/* sensor_sht30.c 错误处理示例 */ Sensor_Status SHT30_Update(Sensor_Val *v) { uint8_t buf[6]; if (HAL_I2C_Mem_Read(&hi2c1, SHT30_ADDR, CMD_MEAS, I2C_MEMADD_SIZE_8BIT, buf, 6, 200) != HAL_OK) return SENSOR_ERROR; /* 总线故障 */ if (SHT30_CrcOk(buf) == false) return SENSOR_ERROR; /* 校验失败 */ v->t = SHT30_CalcT(buf); v->h = SHT30_CalcH(buf); return SENSOR_OK; }要点:
- I²C超时设200 ms,防止总线死锁
- 每次采集先复位看门狗,卡住也能自动重启
- 传感器返回ERROR时,状态机直接进休眠,不卡死
5. 性能&安全:别让数据“看起来差不多”
ADC精度
STM32L051内部ADC只有12 bit,温湿度已数字量,但电池电压分压后要走ADC,参考电压选2.5 V基准,别用VDDA,否则VDD掉一点,读值飘一片。射频干扰
- LoRa天线走板边,包地+π型匹配
- 30 cm内勿平行布置I²C时钟线,免得天线包络把“毛刺”当 preamble
低功耗休眠
- 进入STOP前把SX1278置Sleep,电流从15 mA→1 µA
- 唤醒后重新初始化LoRa寄存器,否则第一次发送易失败
- RTC时钟源选LSI,省掉32.768 k晶振,BOM成本-0.3元,代价是±5 %误差,环境监测够用
6. 生产级避坑指南
PCB布局
- 模拟/数字分地,单点连接
- DCDC芯片下方留铜皮散热,过孔0.3 mm打阵列,否则2 A瞬态升温20 ℃
烧录失败排查
- 先测NRST是否被IO强行拉低
- 再查SWDIO/SWCLK有没有5 V容忍,很多人直接接USB-TTL→3.3 V,结果一上电过压锁芯片
传感器校准
- SHT30读回湿度>98 %时,用饱和盐法(NaCl,75 %RH)做单点修正
- BH1750线性度好,但玻璃外壳会反光,外壳开孔直径≥5 mm,角度45 °,数据才稳
外壳结构
- 电池仓与主板隔离墙≥1 mm,防跌落实测1 m高水泥地不裂
- 螺丝柱别放天线正下方,金属会直接把辐射压到-6 dB
7. 可扩展&可维护思考
把上面框架跑通后,你可以:
- 把SHT30换成SPS30,加PM2.5,秒变“空气质量节点”
- 把LoRa换成NB-IoT,数据直接进云,手机小程序就能看
- 在接收端加Raspberry Pi + InfluxDB,自动出图,论文“可视化”章节就有了
维护性方面,建议:
- 所有驱动写单元测试,用PC串口模拟I²C回环,毕业答辩后还能回归测试
- Git提交按“功能+版本”打Tag,v1.0能跑,v1.1低功耗,v1.2加OTA,老师一看就懂
- 写一份“快速装配指引”,附BOM替代料号,后来学弟学妹直接抄板,你的项目还能当学院模板
8. 结尾
毕业设计不是科研,是“有限时间内把东西跑起来”。先让板子亮、数据传、功耗低,再谈算法和情怀。把这篇当毛坯房,换传感器、换协议、换外壳,都能快速二次开发。等你真正在实验室看到第一包数据从LoRa那头蹦出来,会发现“选题焦虑”其实也就那么回事。祝你毕业顺利,把板子带回家当纪念品。