目录
[2.1 基本特性](#2.1 基本特性)
[2.2 结构与工作原理](#2.2 结构与工作原理)
[2.3 电气特性](#2.3 电气特性)
[2.4 模块接口说明](#2.4 模块接口说明)
[2.5 原理图设计](#2.5 原理图设计)
[2.6 实际应用注意事项](#2.6 实际应用注意事项)
[3.1 硬件组成](#3.1 硬件组成)
[3.2 硬件连接](#3.2 硬件连接)
[4.1 开发环境配置](#4.1 开发环境配置)
[4.2 关键代码实现](#4.2 关键代码实现)
[4.2.1 ADC初始化代码](#4.2.1 ADC初始化代码)
[4.2.2 读取ADC值函数](#4.2.2 读取ADC值函数)
[4.2.3 主程序框架](#4.2.3 主程序框架)
[5.1 湿度值校准](#5.1 湿度值校准)
[5.2 软件滤波处理](#5.2 软件滤波处理)
一、模块概述
土壤湿度检测是现代智能农业、园林自动灌溉系统中的重要组成部分。本文详细介绍如何使用STM32F103C8T6最小系统板通过标准库读取四针式土壤湿度传感器模块(VCC、GND、AO、DO)的数据,实现土壤湿度的精确监测。该系统具有成本低、可靠性高、易于集成等特点,适合各类湿度监测应用场景。
二、模块简介
模块实物图:

2.1 基本特性
土壤湿度传感器模块主要特性包括:
-
工作电压:3.3V-5V DC
-
输出信号:模拟量输出(AO)和数字量输出(DO)双信号
-
探测深度:约3-5cm
-
模块尺寸:小型化设计,便于安装
-
使用寿命:抗氧化探头设计,延长使用寿命
2.2 结构与工作原理
传感器采用电阻式测量原理:
-
探头部分由两个导电电极组成
-
土壤中的水分含量影响电极间的电阻值
-
模块内部电路将电阻变化转换为电压信号输出
-
模拟输出(AO)提供连续湿度值,数字输出(DO)提供阈值报警
- 模块中蓝色的电位器是用于土壤湿度的阀值调节,顺时针调节,控制的湿度会越大,逆时针越小
- 数字量输出D0可以与单片机直接相连,通过单片机来检测高低电平,由此来检测土壤湿度;
- 小板模拟量输出AO(0~4095)可以和AD模块相连,通过AD转换,可以获得土壤湿度更精确的数值;
2.3 电气特性
参数 | 规格 |
---|---|
工作电流 | 约15-20mA |
模拟输出范围 | 0-VCC |
数字输出电平 | 0V或VCC |
响应时间 | <1s |
工作温度 | -10°C ~ +60°C |
2.4 模块接口说明
四针接口定义:
|-----|---------------------|
| VCC | 电源正极(3.3V或5V) |
| GND | 电源地 |
| AO | 模拟信号输出,连接MCU的ADC引脚 |
| DO | 数字信号输出,连接MCU的GPIO引脚 |
2.5 原理图设计

电源部分:
- VCC:电源正极输入,为整个模块提供工作电压。
- 104电容:即0.1μF的电容,并联在电源两端,起到滤波作用,去除电源中的高频噪声,使电源更加稳定。
- 电源指示:由一个发光二极管和1K的限流电阻组成。当模块接上电源后,电流通过限流电阻使发光二极管发光,指示模块已通电。
土壤湿度传感器部分:
- 土壤湿度传感器:通常是由两个电极组成,其电阻值会随着土壤湿度的变化而变化。土壤湿度越高,电极间的导电性越好,电阻值越低;反之,土壤干燥时,电阻值较高。
- 电位器VR1:一个10K的可调电阻,与土壤湿度传感器配合使用,用于设置湿度检测的阈值。通过调节电位器,可以改变比较器的参考电压,从而调整模块对土壤湿度的敏感度。
比较器电路:
- LM393 :这是一个电压比较器芯片。它将土壤湿度传感器输出的电压信号与电位器设置的参考电压进行比较。
- 当土壤湿度传感器的电压(即土壤湿度对应的电压)高于参考电压时,比较器输出高电平。
- 当土壤湿度传感器的电压低于参考电压时,比较器输出低电平。
- 510K和104电容:510K的电阻和104的电容组成了一个RC滤波电路,对土壤湿度传感器的信号进行滤波处理,去除信号中的干扰和噪声,使输入到比较器的信号更加稳定。
输出指示与接口部分:
- 开关指示:由一个发光二极管和1K的限流电阻组成。当比较器输出高电平时,发光二极管可能发光(具体取决于电路设计逻辑,通常高电平触发指示),用于指示当前土壤湿度状态是否达到或超过设定的阈值。
- DO(数字输出):3线制或4线制接口中的数字输出引脚,输出比较器的结果(高电平或低电平),可直接连接到微控制器(如Arduino)的数字输入引脚,用于程序判断土壤湿度状态。
- AO(模拟输出):在4线制接口中存在,直接输出土壤湿度传感器经过处理后的模拟电压信号,该信号与土壤湿度成一定比例关系,可连接到微控制器的模拟输入引脚,通过ADC转换获取具体的湿度数值。
- GND:接地引脚,为整个模块提供电气参考点。
2.6 实际应用注意事项
-
长期使用时,探头金属部分可能氧化,需定期清洁
-
避免在极端干燥或完全浸水环境中长期工作
-
不同土壤类型需重新校准湿度值
-
安装时应确保探头与土壤充分接触
三、硬件设计
3.1 硬件组成
系统所需硬件:
-
STM32F103C8T6最小系统板
-
土壤湿度传感器模块(四针)
-
杜邦线若干
-
5V或3.3V电源
-
可选:OLED用于显示数据
3.2 硬件连接
具体连接方式:
传感器引脚 | STM32连接引脚 |
---|---|
VCC | 3.3V或5V |
GND | GND |
AO | PA0 (ADC1_IN0) |
DO | PA1 |
**注意:**若使用5V供电,需确保AO输出不超过STM32的ADC输入电压范围(最大3.6V),必要时添加分压电路。
四、软件设计
4.1 开发环境配置
-
安装Keil MDK-ARM开发环境
-
配置STM32标准外设库
-
设置工程选项,选择正确的STM32F103C8T6器件
-
配置调试工具(如ST-Link)
4.2 关键代码实现
4.2.1 ADC初始化代码
#include "stm32f10x.h"
void ADC1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
// 启用GPIOA和ADC1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);
// 配置PA0为模拟输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// ADC配置
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
// 启用ADC1
ADC_Cmd(ADC1, ENABLE);
// ADC校准
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
}
- 时钟使能:STM32的外设需要先启用时钟才能操作。
- GPIO模式 :土壤传感器的AO输出是模拟信号,必须配置为模拟输入(
GPIO_Mode_AIN
)。 - ADC配置 :
- 独立模式:ADC1单独工作(非双ADC模式)。
- 单次转换:每次手动触发采样(适合低功耗场景)。
- 右对齐:12位ADC结果存储在16位变量的低12位。
- 校准:ADC模块上电后需校准,消除内部误差。
4.2.2 读取ADC值函数
uint16_t Get_ADC_Value(uint8_t ch, uint8_t times)
{
uint32_t temp_val = 0;
uint8_t t;
// 设置指定ADC的规则组通道,一个序列,采样时间
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5);
for(t = 0; t < times; t++)
{
ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 启动转换
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); // 等待转换结束
temp_val += ADC_GetConversionValue(ADC1); // 获取转换值
delay_ms(5);
}
return temp_val / times; // 返回平均值
}
- 通道配置 :
ch
参数指定ADC通道(如ADC_Channel_0
对应PA0)。 - 软件触发 :通过
ADC_SoftwareStartConvCmd
手动启动转换。 - 多次采样 :通过
times
参数指定采样次数,取平均值以提高稳定性。 - 采样时间 :
ADC_SampleTime_239Cycles5
是较长的采样时间,适合高阻抗信号源(如土壤传感器)。
4.2.3 主程序框架
int main(void)
{
uint16_t adc_value;
float moisture_percent;
// 初始化系统时钟
SystemInit();
// 初始化ADC
ADC1_Init();
// 初始化串口用于调试输出
USART1_Init(115200);
// 初始化DO引脚为输入
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
GPIO_Init(GPIOA, &GPIO_InitStruct);
while(1)
{
// 读取ADC值
adc_value = Get_ADC_Value(ADC_Channel_0, 10);
// 转换为百分比湿度(需根据实际传感器校准)
// 通常湿度越高,ADC值越低
moisture_percent = 100 - (adc_value * 100.0 / 4095);
// 读取数字输出状态
uint8_t digital_status = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1);
// 通过串口输出结果
printf("ADC值: %d, 湿度: %.1f%%, 数字输出: %s\n",
adc_value, moisture_percent,
digital_status ? "低于阈值" : "高于阈值");
delay_ms(1000); // 每秒采样一次
}
}
- DO引脚配置 :设置为上拉输入(
GPIO_Mode_IPU
),因为传感器的DO输出是数字信号(高/低电平)。 - 湿度计算公式 :
- 土壤湿度越高,导电性越强,AO输出电压越低,ADC值越小。
100 - (adc_value * 100.0 / 4095)
将ADC值(0-4095)反向转换为百分比。
- 数字输出:DO引脚的状态由传感器内部比较器决定,可通过电位器调节阈值。
五、功能实现与优化
5.1 湿度值校准
实际应用中需进行传感器校准:
-
在完全干燥环境中读取ADC值(作为0%湿度)
-
在完全浸水环境中读取ADC值(作为100%湿度)
-
使用线性插值计算中间值
校准代码示例:
#define DRY_VALUE 3800 // 干燥时的ADC值
#define WET_VALUE 1500 // 浸水时的ADC值
float Get_Calibrated_Moisture(uint16_t adc_val)
{
if(adc_val >= DRY_VALUE) return 0.0f;
if(adc_val <= WET_VALUE) return 100.0f;
return 100.0f * (DRY_VALUE - adc_val) / (DRY_VALUE - WET_VALUE);
}
-
两点校准法:
-
DRY_VALUE
:完全干燥时的ADC值(如3800)。 -
WET_VALUE
:完全浸水时的ADC值(如1500)。
-
-
线性插值:通过干燥和浸水两点建立线性关系,计算中间值。
5.2 软件滤波处理
为消除噪声干扰,可采用以下滤波方法:
-
移动平均滤波
-
中值滤波
-
卡尔曼滤波
移动平均滤波实现:
#define FILTER_SIZE 10
typedef struct {
uint16_t buffer[FILTER_SIZE];
uint8_t index;
uint32_t sum;
} MovingAverageFilter;
void Filter_Init(MovingAverageFilter* filter)
{
memset(filter, 0, sizeof(MovingAverageFilter));
}
uint16_t Filter_Update(MovingAverageFilter* filter, uint16_t new_value)
{
// 减去最旧的值
filter->sum -= filter->buffer[filter->index];
// 添加新值
filter->buffer[filter->index] = new_value;
filter->sum += new_value;
// 更新索引
filter->index = (filter->index + 1) % FILTER_SIZE;
// 返回平均值
return filter->sum / FILTER_SIZE;
}
-
移动平均滤波:维护一个固定长度(如10)的缓冲区,每次更新时替换最旧的数据。
-
优点:有效抑制随机噪声,代码实现简单。
-
缺点:会引入一定的延迟,不适合快速变化的信号。
六、常见问题解决
ADC读数不稳定:
-
检查电源是否稳定,可增加滤波电容
-
实施软件滤波算法
-
确保传感器探头与土壤接触良好
数字输出(DO)不变化:
-
检查电位器调节是否适当
-
确认比较器电路工作正常
-
验证GPIO输入配置正确
传感器响应迟缓:
-
可能是探头氧化导致,清洁探头
-
检查土壤与探头的接触情况
湿度百分比计算不准确:
-
重新进行干湿两点校准
-
考虑土壤类型差异,可能需要非线性校准
STM32无法识别传感器:
-
检查接线是否正确
-
测量传感器供电电压
-
确认AO信号电压在ADC输入范围内
七、总结
本文详细介绍了基于STM32F103C8T6最小系统板和标准库读取土壤湿度传感器的完整方案。通过合理配置ADC模块和GPIO接口,实现了土壤湿度的精确测量和阈值检测。系统具有以下特点:
-
双模式输出:同时支持模拟量精确测量和数字量阈值报警
-
灵活配置:可根据不同土壤类型进行校准
-
低功耗设计:适合电池供电的远程监测应用
-
扩展性强:可轻松集成到自动灌溉等大型系统中
实际应用中,建议根据具体环境对传感器进行定期校准和维护,以获得最佳的测量效果。本方案也可推广到其他类似传感器的接口应用中,具有较高的参考价值。