土壤湿度传感器

STM32F103C8T6 · HAL库 · 双传感器ADC采集 · OLED显示
ADC
采集方式
PA0 / PA1
模拟引脚
PA4
数字输出
50ms
刷新间隔
1 传感器原理与功能
电容式与电阻式土壤湿度传感器的工作原理、核心功能及引脚定义

1.1 工作原理

🔵 电容式土壤湿度传感器

电容式土壤湿度传感器基于电容变化原理工作。传感器探头由两块平行金属电极构成,中间的介质为土壤。空气的介电常数约为1,而水的介电常数约为80,远大于空气和干燥土壤。

当土壤含水量增加时,水分填充了土壤颗粒间的空隙,导致电极间的等效介电常数增大,传感器的电容值随之增大。内部振荡电路将电容变化转换为频率变化,再经过滤波处理后输出与湿度成反比的模拟电压信号。

特点:不易受腐蚀、寿命长、响应稳定。输出电压越低表示土壤越湿,电压越高表示土壤越干。

土壤越湿 → 介电常数↑ → 电容↑ → 输出电压↓ → ADC值↓
土壤越干 → 介电常数↓ → 电容↓ → 输出电压↑ → ADC值↑

🟠 电阻式土壤湿度传感器

电阻式土壤湿度传感器基于电阻变化原理工作。传感器探头带有两根金属插脚,直接插入土壤中。土壤作为导体,其电阻值取决于含水量和离子浓度。

当土壤含水量增加时,水中溶解的离子增多,导电能力增强,土壤的电阻值减小。传感器内部将电阻变化分压后输出与湿度成反比的模拟电压信号。

特点:结构简单、成本低,但金属探头易受电化学腐蚀,长期使用可能影响精度。输出电压越低表示土壤越湿,电压越高表示土壤越干。

土壤越湿 → 导电性↑ → 电阻↓ → 输出电压↓ → ADC值↓
土壤越干 → 导电性↓ → 电阻↑ → 输出电压↑ → ADC值↑

📊 双传感器对比

对比项电容式电阻式
检测原理介电常数变化电阻值变化
输出电压与湿度反比(湿→低压)反比(湿→低压)
ADC值范围(湿)约1900以下约2730以下
ADC值范围(干)约3300以上约4095
抗腐蚀性强弱
寿命长较短
STM32引脚PA0 (ADC1_IN0)PA1 (ADC1_IN1)

1.2 核心功能

📡

双通道ADC采集

ADC1同时采集两路传感器信号,使用扫描模式+DMA循环传输,无需CPU干预即可持续更新数据

💧

湿度百分比换算

根据不同传感器的输出特性,分别采用线性映射和比例缩放算法将ADC原始值转换为0~100%湿度值

📊

OLED实时显示

0.96寸OLED屏幕每50ms刷新一次,同时显示电容式、电阻式湿度值及数字触发状态

⚡

数字阈值检测

传感器板载比较器输出数字信号(PA4),可直接判断湿度是否超过设定阈值,无需ADC参与

1.3 引脚定义

电容式土壤湿度传感器(3引脚)
引脚名称功能STM32连接
GND电源地接地GND
VCC电源正极5V供电5V
AOUT模拟输出湿度模拟电压PA0 (ADC1_IN0)
电阻式土壤湿度传感器(4引脚)
引脚名称功能STM32连接
VCC电源正极5V供电5V
GND电源地接地GND
DOUT数字输出阈值触发信号PA4 (GPIO_INPUT)
AOUT模拟输出湿度模拟电压PA1 (ADC1_IN1)
OLED显示屏 (I2C软件模拟)
引脚名称功能STM32连接
SCLI2C时钟OLED时钟线PB15
SDAI2C数据OLED数据线PB14
2 模块外观展示
电容式与电阻式土壤湿度传感器实物外观
电容式土壤湿度传感器
电容式土壤湿度传感器
电阻式土壤湿度传感器
电阻式土壤湿度传感器
3 原理图与PCB封装
传感器模块的电路原理图与PCB封装设计
原理图
PCB封装
4 程序分析
基于STM32 HAL库的ADC+DMA双通道采集、湿度计算与OLED显示程序

4.1 ADC1初始化 (adc.c)

配置说明

ADC1配置为扫描模式+连续转换,启用2个规则通道(Channel 0和Channel 1),采样时间设置为239.5个时钟周期以确保精度。数据右对齐,软件触发启动转换。DMA将转换结果自动搬运至内存数组,无需CPU干预。

adc.c — MX_ADC1_Init()
void MX_ADC1_Init(void)
{
  ADC_ChannelConfTypeDef sConfig = {0};

  /* ADC1通用配置 */
  hadc1.Instance = ADC1;
  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;          // 扫描模式:多通道自动扫描
  hadc1.Init.ContinuousConvMode = ENABLE;               // 连续转换
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;      // 软件触发
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;            // 数据右对齐
  hadc1.Init.NbrOfConversion = 2;                        // 2个转换通道
  HAL_ADC_Init(&hadc1);

  /* 配置通道0 - 电容式土壤湿度传感器 (PA0) */
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
  HAL_ADC_ConfigChannel(&hadc1, &sConfig);

  /* 配置通道1 - 电阻式土壤湿度传感器 (PA1) */
  sConfig.Channel = ADC_CHANNEL_1;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}

4.2 GPIO初始化 (gpio.c)

配置说明

PA4配置为输入模式(无上下拉),用于读取电阻式土壤湿度传感器板载比较器的数字输出信号。当土壤湿度超过设定阈值时,DOUT输出低电平(0),反之输出高电平(1)。

gpio.c — MX_GPIO_Init()
void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /* 配置PA4为输入模式 - 传感器数字输出(DOUT) */
  GPIO_InitStruct.Pin = GPIO_PIN_4;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

4.3 DMA配置 (adc.c - HAL_ADC_MspInit)

配置说明

DMA1通道1配置为外设到内存模式,半字(16位)数据对齐,内存地址自增(MINC_ENABLE)以将两个通道的ADC值依次存入AD_Value数组。DMA模式为循环模式(DMA_CIRCULAR),确保ADC数据持续自动刷新。

adc.c — HAL_ADC_MspInit() - DMA配置部分
  /* ADC1 GPIO配置: PA0->ADC1_IN0, PA1->ADC1_IN1 */
  GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* ADC1 DMA配置 */
  hdma_adc1.Instance = DMA1_Channel1;
  hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;       // 外设→内存
  hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;          // 外设地址不增
  hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;              // 内存地址自增
  hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
  hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
  hdma_adc1.Init.Mode = DMA_CIRCULAR;                   // 循环模式
  HAL_DMA_Init(&hdma_adc1);
  __HAL_LINKDMA(&hadc1, DMA_Handle, hdma_adc1);

4.4 主程序初始化与主循环 (main.c)

初始化流程

系统启动后依次初始化GPIO、DMA、ADC1,然后执行ADC校准(HAL_ADCEx_Calibration_Start),初始化OLED显示屏,最后启动ADC+DMA转换。此后AD_Value数组将由DMA自动维护,主循环只需读取计算即可。

main.c — main() 初始化部分
int main(void)
{
  HAL_Init();
  SystemClock_Config();

  MX_GPIO_Init();       // GPIO初始化
  MX_DMA_Init();       // DMA初始化
  MX_ADC1_Init();      // ADC1初始化

  HAL_ADCEx_Calibration_Start(&hadc1);           // ADC校准
  OLED_Init();                                         // OLED初始化
  HAL_ADC_Start_DMA(&hadc1, (uint32_t *)AD_Value, 2); // 启动ADC+DMA
main.c — while(1) 主循环
  while (1)
  {
    // 电容式土壤湿度传感器 - 线性映射
    soil_1 = AD_Value[0] < 1900 ? 100 : (AD_Value[0] > 3300 ? 0 : (3300 - AD_Value[0]) * 100 / 1400);

    // 电阻式土壤湿度传感器 - 比例缩放
    soil_2 = (100 - AD_Value[1] / 4095.0 * 100) * 3;
    if(soil_2 > 100) soil_2 = 100;   // 限幅

    if(HAL_GetTick() - Time_Now >= 50)       // 50ms刷新一次
    {
      OLED_Clear();
      OLED_Printf(0, 0, OLED_8X16, "电容式:%d%%", soil_1);
      OLED_Printf(0, 32, OLED_8X16, "电阻式:%d%%", soil_2);

      if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4) == 0)
        OLED_Printf(0, 48, OLED_8X16, "土壤湿度:是");
      else
        OLED_Printf(0, 48, OLED_8X16, "土壤湿度:否");

      OLED_Update();
      Time_Now = HAL_GetTick();
    }
  }
5 程序流程图
STM32土壤湿度传感器采集程序执行流程
开始 HAL_Init() + SystemClock_Config() MX_GPIO_Init() + MX_DMA_Init() + MX_ADC1_Init() ADC校准 + OLED_Init() + HAL_ADC_Start_DMA() while(1) 主循环 计算 soil_1 (电容式) + soil_2 (电阻式,含限幅) HAL_GetTick() - Time_Now >= 50ms? 否 是 OLED_Clear + 显示soil_1/soil_2 + 读取PA4状态 OLED_Update() + Time_Now = HAL_GetTick()
6 交互式动画演示
双传感器土壤湿度检测模拟与OLED显示效果展示

🌱 传感器检测模拟

电容式传感器 (PA0)
电阻式传感器 (PA1)

📊 OLED显示与数据

电容式:--%
 
电阻式:--%
 
土壤湿度:--
电容式 ADC (PA0):----
电阻式 ADC (PA1):----
PA4 数字输出:--
电容式湿度0%
电阻式湿度0%

电容式:ADC值越低→湿度越高(反比关系)

电阻式:ADC值越低→湿度越高(反比关系)

PA4:数字输出,低电平=湿度触发

刷新:每50ms更新OLED显示