基于单片机的农田监测系统毕业设计:效率提升与低功耗优化实战

📅 发布时间:2026/7/5 6:49:05 👁️ 浏览次数:
基于单片机的农田监测系统毕业设计:效率提升与低功耗优化实战
基于单片机的农田监测系统毕业设计效率提升与低功耗优化实战1. 背景痛点轮询式设计的“三高”困境做毕设时我最初也走了“经典”老路主循环里挨个read_sensor()每隔 5 s 把 5 路传感器全部跑一遍再用delay_ms()等 LoRa 回包。结果现场跑 3 天两节 18650 就见底更尴尬的是当土壤湿度瞬间跌到 15 % 以下系统还在delay里睡大觉错过最佳灌溉窗口。总结下来传统轮询带来三大硬伤功耗高MCU 与传感器全程“在线”平均电流 28 mA电池寿命按周计算实时性差最坏情况下 5 s 才采样一次异常事件响应延迟可高达 5 s资源浪费80 % 的采样值在阈值范围内却仍旧占用 CPU、Flash 与空口带宽毕设答辩时评委一句“你们这套系统农民伯伯敢用吗”让我彻底下决心改架构。2. 技术选型STM32F103 还是 ESP32农田场景没有 220 V只有 3.7 V 锂电没有 Wi-Fi只有 2 km 外的 LoRa 网关。我把两款常用芯片放到同一套功耗测试工装里跑 24 h数据如下指标STM32F103C8T6ESP32-WROOM-32运行功耗MCU 主频4.2 mA72 MHz68 mA240 MHzDeep-sleep 电流1.8 µARTC 开8 µAULP 协处理器外设资源3×ADCDMA、低功耗串口8×ADC、Wi-Fi/BT 双模开发成本核心板 12 元模组 22 元射频扩展需外挂 SX1278自带 Wi-FiLoRa 仍需外挂结论农田节点“睡得多、醒得少”ESP32 的 Wi-Fi 在野外形同虚设反而拉高底电流STM32F103 凭借 1.8 µA 的 RTC 休眠胜出。3. 核心实现事件驱动 批量上报3.1 系统框图3.2 事件驱动架构传感器只在“阈值窗口外”才触发中断唤醒 MCURTC 每 30 min 强制唤醒一次做“心跳包”与电池电压巡检唤醒后 DMA 批量采样 16 次求平均后写入缓存缓存满 8 条或异常事件到达一次性 LoRa 发送 64 B 数据块3.3 低功耗状态机Sleep所有外设时钟关仅保留 RTC 与 GPIO 中断Sample打开 ADC→DMA→关闭 ADC全程 6 msTx打开 SPI→LoRa→发送→关闭全程 45 msReturn事件计数器清零立即回 Sleep3.4 传感器端防抖土壤湿度传感器最容易“极化”——长期直流激励金属探针电解锈蚀。我的做法交流激励GPIO 推挽输出 1 kHz 方波隔直电容耦合到探针ADC 采样在方波上升沿后 50 µs 进行避开瞬态采样完毕立即把 GPIO 置高阻探针零电位延长寿命 3×4. 关键代码片段基于 HAL 库Keil5 编译以下代码可直接复制到main.c已去掉头文件与冗余初始化保留核心逻辑与注释。/* 低功耗进入函数调用前需确保所有外设 DeInit */ void Enter_Stop_Mode(void) { /* 清除 RTC 唤醒标志防止误中断 */ __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(hrtc); /* 设置 RTC 30 min 后唤醒 */ HAL_RTCEx_SetWakeUpTimer_IT(hrtc, 30*60-1, RTC_WAKEUPCLOCK_RTCCLK_DIV16); /* 挂起 SysTick防止滴答干扰电流测试 */ SysTick-CTRL ~SysTick_CTRL_ENABLE_Msk; /* 进入 STOP 模式RTC 仍跑 */ HAL_PWR_EnterSTOPMode(PWR_REGULATOR_LOWPOWER, PWR_STOPENTRY_WFI); /* 醒来后重新配置系统时钟 */ SystemClock_Config(); SysTick-CTRL | SysTick_CTRL_ENABLE_Msk; } /* GPIO 中断回调土壤湿度低于阈值 */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin GPIO_PIN_0) { BaseType_t xHigherPriorityTaskWoken pdFALSE; /* 给采样任务发信号 */ xSemaphoreGiveFromISR(xSemaphore, xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } } /* ADC 采样 平均 */ uint16_t ADC_Average(uint32_t Channel) { uint32_t sum 0; ADC_ChannelConfTypeDef sConfig {0}; sConfig.Channel Channel; sConfig.Rank 1; sConfig.SamplingTime ADC_SAMPLETIME_239CYCLES_5; HAL_ADC_ConfigChannel(hadc1, sConfig); for(uint8_t i0; i16; i) { HAL_ADC_Start(hadc1); HAL_ADC_PollForConversion(hadc1, 1); sum HAL_ADC_GetValue(hadc1); HAL_ADC_Stop(hadc1); } return sum 4; } /* LoRa 发送带幂等序号 */ void LoRa_Send_Packet(uint8_t* buf, uint8_t len) { static uint16_t seq_id 0; buf[len] seq_id 8; buf[len] seq_id 0xFF; seq_id; SX1278_Send(buf, len); /* 等待发送完成中断超时 300 ms */ if(xSemaphoreTake(xLoRaIq, pdMS_TO_TICKS(300)) ! pdTRUE) { /* 超时处理重新初始化射频防止死锁 */ SX1278_Reset(); } }5. 性能测试数据说话把整机含传感器、LoRa 模块放进恒温箱串 10 Ω 电阻测电流结果如下休眠平均电流1.9 µA温度 25 ℃唤醒到 ADC 完成3.2 ms唤醒到 LoRa 发送完成42 ms连续 30 天运行无重启、无丢包心跳包 864 条接收 864 条EMC 方面电机灌溉泵启动时产生 1 kV 群脉冲系统曾复位两次。解决措施在电源入口加 600 W TVSSMBJ6.0A复位脚 1 kΩ 串 100 pF 下地滤除 50 ns 毛刺看门狗改为窗口型喂狗窗口 50~100 ms防止极端干扰下“死喂狗”6. 生产环境避坑指南电源噪声便宜 DC-DC 升压模块 3.3 V 输出纹波 120 mV导致 ADC 跳动 5 LSB。换成 TI TPS63020纹波 10 mV采样误差回到 ±1 LSB土壤传感器极化上文已提务必交流激励否则两周后数据漂移 30 %看门狗误区STM32 独立看门狗一旦启用STOP 模式下仍计数唤醒不及时会误复位。解决进入休眠前HAL_IWDG_Refresh或改用 RTC 唤醒代替“死等”LoRa 天线朝向胶棒天线贴地通信距离从 2 km 掉到 300 m。抬高 1 m 后RSSI 提升 18 dB丢包率 1 %灌封胶选型某环氧灌封胶 24 h 吸水率 0.3 %雨季进水短路。改用水性聚氨酯吸水率 0.05 %成本贵 5 元但节点寿命翻倍7. 结语与思考一套小小的农田节点把“事件驱动”与“低功耗”做到极致电池也能跑 180 天。毕设答辩那天评委老师问“如果 2 km 外没有 LoRa 网关怎么让多节点自组网”——这个问题我至今还在迭代。无网络覆盖区域能否用 STM32 做时隙中继或者把节点当简易 MESH 路由器靠前向纠错跳频实现多跳留给你我一起动手复现、验证。把代码拉下来先让电流表降到 2 µA再谈网络拓扑也许下一个更优雅的答案就诞生在你的桌面。