基于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显示。通过简单的硬件连接和模块化代码,可快速部署于菜园、花园等场景,实现智能化灌溉。

posted @ 2026-04-08 16:13  风一直那个吹  阅读(23)  评论(0)    收藏  举报