基于51单片机的土壤湿度检测仪与自动浇水系统设计
一、系统概述
以STC89C52RC单片机为核心,结合土壤湿度传感器、水泵驱动电路、LCD显示模块和按键设置,实现土壤湿度的实时检测与自动浇水功能。系统可根据预设湿度阈值自动控制水泵启停,适用于菜园、花园等小型种植场景,具备低功耗、低成本、易部署的特点。
二、硬件设计
2.1 核心组件选型
| 模块 | 型号/参数 | 功能说明 |
|---|---|---|
| 主控 | STC89C52RC(8位单片机,11.0592MHz) | 数据处理、逻辑控制、外设驱动 |
| 湿度传感器 | FC-28(电阻式,输出模拟电压) | 检测土壤湿度(干燥→阻值大,湿润→阻值小) |
| ADC转换 | ADC0832(8位串行ADC) | 将传感器模拟电压转换为数字信号(0~255) |
| 显示模块 | LCD1602(16×2字符型液晶) | 显示当前湿度、设定阈值、水泵状态 |
| 水泵 | 5V微型直流水泵(流量100L/h) | 浇水执行机构(通过继电器驱动) |
| 驱动电路 | S8050三极管+继电器(5V/10A) | 单片机IO口控制水泵通断(隔离强电) |
| 按键 | 3个轻触按键(设置/加/减) | 设置湿度阈值(下限/上限)、手动控制水泵 |
| 电源 | 5V/2A DC电源(或18650电池+升压模块) | 为系统供电(传感器、单片机、水泵) |
2.2 硬件连接图
+-------------------+ +-------------------+ +-------------------+
| 土壤湿度传感器 | | STC89C52RC | | LCD1602 |
| (FC-28) | | | | |
| VCC → 5V | | P1.0 → ADC0832 CS | | VCC → 5V |
| GND → GND | | P1.1 → ADC0832 CLK | | GND → GND |
| AO → ADC0832 CH0 |◄---------| P1.2 → ADC0832 DO | | RS → P2.0 |
+-------------------+ | P2.0~P2.7 → LCD DB0~DB7 | | RW → P2.1 |
| P3.0 → LCD RS | | E → P2.2 |
+-------------------+ | P3.1 → LCD RW | | |
| ADC0832 | | P3.2 → LCD E | +-------------------+
| CS → P1.0 | | P3.3 → 按键设置 | +-------------------+
| CLK → P1.1 |◄---------| P3.4 → 按键加 | | 继电器(水泵) |
| DO → P1.2 | | P3.5 → 按键减 | | IN → P3.6 |
| VCC → 5V | | P3.6 → 继电器控制 | | VCC → 5V |
| GND → GND | | P3.7 → 水泵状态LED | | GND → GND |
+-------------------+ +-------------------+ +-------------------+
| P3.7 → LED(水泵运行指示) |
+---------------------------+
三、软件设计(Keil C51)
3.1 系统架构
graph TD
A[主程序] --> B[初始化]
B --> C[读取ADC值(湿度传感器)]
C --> D[转换为湿度百分比]
D --> E[LCD显示(当前湿度/阈值)]
E --> F[按键扫描(设置阈值)]
F --> G{湿度 < 下限?}
G -->|是| H[启动水泵浇水]
G -->|否| I{湿度 > 上限?}
I -->|是| J[停止水泵]
I -->|否| K[维持当前状态]
H --> E
J --> E
K --> E
3.2 核心代码实现
3.2.1 头文件与宏定义
#include <reg52.h>
#include <intrins.h>
// 引脚定义
#define ADC_CS P1_0 // ADC0832片选
#define ADC_CLK P1_1 // ADC0832时钟
#define ADC_DO P1_2 // ADC0832数据输出
#define LCD_RS P2_0 // LCD1602 RS
#define LCD_RW P2_1 // LCD1602 RW
#define LCD_E P2_2 // LCD1602 E
#define LCD_DB P0 // LCD1602数据总线
#define KEY_SET P3_3 // 设置按键
#define KEY_UP P3_4 // 加按键
#define KEY_DOWN P3_5 // 减按键
#define PUMP P3_6 // 水泵控制(高电平启动)
#define LED_RUN P3_7 // 水泵运行指示灯
// 全局变量
unsigned char adc_val = 0; // ADC采样值(0~255)
unsigned char humidity = 0; // 湿度百分比(0~100%)
unsigned char set_min = 30; // 湿度下限(默认30%)
unsigned char set_max = 60; // 湿度上限(默认60%)
bit pump_flag = 0; // 水泵状态(0=停止,1=运行)
3.2.2 ADC0832驱动(读取土壤湿度)
// ADC0832读取函数(单通道CH0)
unsigned char ADC0832_Read() {
unsigned char i, dat = 0;
ADC_CS = 0; // 片选使能
ADC_CLK = 0; // 时钟初始化
// 发送通道选择信号(CH0:起始位+1位通道号)
ADC_DO = 1; _nop_(); ADC_CLK = 1; _nop_(); ADC_CLK = 0; _nop_(); // 起始位
ADC_DO = 0; _nop_(); ADC_CLK = 1; _nop_(); ADC_CLK = 0; _nop_(); // CH0(0)
// 读取8位数据(MSB先出)
for (i=0; i<8; i++) {
ADC_CLK = 1; _nop_();
dat <<= 1;
if (ADC_DO) dat |= 0x01;
ADC_CLK = 0; _nop_();
}
ADC_CS = 1; // 片选禁用
return dat;
}
3.2.3 湿度计算(ADC值→百分比)
FC-28传感器特性:干燥时输出≈5V(ADC=255),完全浸入水中输出≈0V(ADC=0),湿度与ADC值成反比。
// 计算湿度百分比(0~100%)
unsigned char Calc_Humidity(unsigned char adc) {
// 线性转换:湿度% = (255 - adc) / 255 * 100
unsigned char hum = (unsigned char)((255 - adc) * 100.0 / 255.0);
return (hum > 100) ? 100 : hum; // 限幅
}
3.2.4 LCD1602驱动(显示湿度与状态)
// LCD延时函数(约1ms@11.0592MHz)
void LCD_Delay(unsigned int t) {
unsigned int i, j;
for (i=t; i>0; i--)
for (j=110; j>0; j--);
}
// LCD写命令
void LCD_WriteCmd(unsigned char cmd) {
LCD_RS = 0; LCD_RW = 0;
LCD_DB = cmd; LCD_Delay(1);
LCD_E = 1; LCD_Delay(1); LCD_E = 0;
}
// LCD写数据
void LCD_WriteData(unsigned char dat) {
LCD_RS = 1; LCD_RW = 0;
LCD_DB = dat; LCD_Delay(1);
LCD_E = 1; LCD_Delay(1); LCD_E = 0;
}
// LCD初始化
void LCD_Init() {
LCD_WriteCmd(0x38); // 8位数据,2行显示,5×7点阵
LCD_WriteCmd(0x0C); // 开显示,关光标
LCD_WriteCmd(0x06); // 光标右移,不滚动
LCD_WriteCmd(0x01); // 清屏
}
// 显示湿度与状态
void LCD_Display() {
LCD_WriteCmd(0x80); // 第一行首地址
LCD_WriteData('H'); LCD_WriteData('u'); LCD_WriteData('m'); LCD_WriteData(':');
LCD_WriteData(humidity/10 + '0'); // 十位
LCD_WriteData(humidity%10 + '0'); // 个位
LCD_WriteData('%'); LCD_WriteData(' ');
LCD_WriteCmd(0xC0); // 第二行首地址
LCD_WriteData('L'); LCD_WriteData(':'); LCD_WriteData(set_min/10+'0'); LCD_WriteData(set_min%10+'0');
LCD_WriteData('%'); LCD_WriteData(' ');
LCD_WriteData('H'); LCD_WriteData(':'); LCD_WriteData(set_max/10+'0'); LCD_WriteData(set_max%10+'0');
LCD_WriteData('%'); LCD_WriteData(' ');
LCD_WriteData(pump_flag ? 'P' : ' '); // 显示水泵状态(P=运行)
}
3.2.5 按键扫描与阈值设置
// 按键扫描(返回键值:0=无,1=设置,2=加,3=减)
unsigned char Key_Scan() {
if (KEY_SET == 0) { LCD_Delay(10); if (KEY_SET == 0) { while(!KEY_SET); return 1; } }
if (KEY_UP == 0) { LCD_Delay(10); if (KEY_UP == 0) { while(!KEY_UP); return 2; } }
if (KEY_DOWN == 0) { LCD_Delay(10); if (KEY_DOWN == 0) { while(!KEY_DOWN); return 3; } }
return 0;
}
// 阈值设置逻辑
void Key_Process() {
unsigned char key = Key_Scan();
if (key == 1) { /* 设置模式切换(略,可扩展)*/ }
if (key == 2) { // 加按键
if (set_min < 90) set_min += 5;
if (set_max < 95) set_max += 5;
}
if (key == 3) { // 减按键
if (set_min > 10) set_min -= 5;
if (set_max > 20) set_max -= 5;
}
}
3.2.6 主程序(自动浇水逻辑)
void main() {
LCD_Init(); // LCD初始化
PUMP = 0; LED_RUN = 0; // 初始水泵停止
while (1) {
adc_val = ADC0832_Read(); // 读取ADC值
humidity = Calc_Humidity(adc_val); // 计算湿度百分比
Key_Process(); // 按键处理
LCD_Display(); // 显示数据
// 自动浇水逻辑
if (humidity < set_min) { // 湿度低于下限
PUMP = 1; LED_RUN = 1; // 启动水泵
pump_flag = 1;
} else if (humidity > set_max) { // 湿度高于上限
PUMP = 0; LED_RUN = 0; // 停止水泵
pump_flag = 0;
}
LCD_Delay(1000); // 1秒刷新一次
}
}
参考代码 51单片机土壤的湿度检测仪程序 自动对菜园,花园自动浇水 www.youwenfan.com/contentcnt/182739.html
四、系统调试与优化
4.1 传感器校准
-
干燥校准:将传感器置于干燥土壤,记录ADC值(如250),对应湿度0%;
-
湿润校准:将传感器浸入水中,记录ADC值(如50),对应湿度100%;
-
线性修正:根据实际校准值调整
Calc_Humidity函数(如humidity = (255 - adc) * 100 / (255 - 50))。
4.2 抗干扰措施
-
硬件:传感器信号线加滤波电容(10μF),电源端加100μF电解电容;
-
软件:ADC采样取3次平均值(
adc_val = (ADC0832_Read() + ADC0832_Read() + ADC0832_Read())/3)。
4.3 低功耗优化
-
空闲时单片机进入掉电模式(PCON |= 0x01),通过按键或传感器中断唤醒;
-
水泵采用间歇式浇水(如启动30秒,停止5分钟),减少功耗。
五、总结
基于51单片机实现了土壤湿度检测与自动浇水,核心包括ADC信号采集、湿度计算、阈值控制和LCD显示。通过简单的硬件连接和模块化代码,可快速部署于菜园、花园等场景,实现智能化灌溉。

浙公网安备 33010602011771号