基于STM32的土壤湿度传感器使用
最近在学习中用到了ADC数据采集这里使用的硬件模块为土壤湿度传感器,下面为土壤传感器相关的使用方法和代码介绍。
1、土壤湿度传感器实物图
土壤湿度传感器一共有4个引脚分别为:
GND VCC DO AO,在本次实验中使用的为A0模拟引脚,因此在单片机资源上需要使用到ADC,模数转换,将模拟量进行数字的形式输出。当然也可以直接接DO数字引脚,通过调节模块上的电位器进行数字阈值的改变。
2、代码介绍
在代码部分这里不详细介绍ADC的使用,有需要的可自行去查看相关adc的知识,这里使用的是单片机内部资源ADC2,对于STM32F103C8T6这款单片机来讲内部一共有三个ADC,每个ADC又对于着多个通道的采集,引脚参考如下所示。
adc.c
#include "delay.h"
#include "sys.h"
#include "adc.h"
//编写ADC2_Init初始化函数//
void ADC2_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE ); //使能ADC2通道时钟//
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC时钟//
ADC_DeInit(ADC2); //复位ADC2,将外设ADC2的全部寄存器重设为缺省值//
//ADC2_InitStructure参数设置//
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式//
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //关闭扫描模式//
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //单次转换模式//
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //软件触发启动//
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐//
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目//
ADC_Init(ADC2, &ADC_InitStructure);
ADC_Cmd(ADC2, ENABLE); //使能指定的ADC2//
//下面四个函数用于校准//
ADC_ResetCalibration(ADC2); //使能复位校准//
while(ADC_GetResetCalibrationStatus(ADC2)); //等待复位校准结束//
ADC_StartCalibration(ADC2); //开启AD校准//
while(ADC_GetCalibrationStatus(ADC2)); //等待校准结束//
}
//编写Get_ADC2函数//
u16 Get_ADC2(u8 ch)
{
//设置指定ADC的规则组通道,四个入口参数//
ADC_RegularChannelConfig(ADC2, ch, 1, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC2, ch, 2, ADC_SampleTime_239Cycles5 );
ADC_SoftwareStartConvCmd(ADC2, ENABLE); //使能指定的ADC2的软件转换启动功能//
while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC )); //等待转换结束//
return ADC_GetConversionValue(ADC2); //返回最近一次ADC2规则组的转换结果//
}
adc.h
#ifndef __ADC_H
#define __ADC_H
#include "stm32f10x.h"
void ADC2_Init(void); //ADC3初始化//
u16 Get_ADC2(u8 ch) ;
#endif
Sensor.c
这里使用了光敏传感器PA4模拟引脚和土壤湿度传感器PA5模拟引脚输入
#include "ldr.h"
#include "delay.h"
//该文件为土壤湿度检测 原理和光敏采集一样//
void Lsens_Soil_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO ,ENABLE); //使能GPIOF时钟
//配置GPIOF参数,引脚4 引脚5,模拟输入//
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC2_Init();
}
//范围0-100
u8 Get_ADC_Val(u8 ch)
{
u32 temp_val=0;
u8 t;
for(t=0;t<LSENS_READ_TIMES;t++) //LSENS_READ_TIMES在lsens.h文件中设好,默认10//
{
temp_val+=Get_ADC2(ch);
delay_ms(2);
}
temp_val/=LSENS_READ_TIMES; //计算平均值//
if(temp_val>4000)temp_val=4000; //当计算后的值大于4000时,强制转换为4000//
return (u8)(100-(temp_val/40)); //将temp_val值归一化到0-100之间//
}
/***************************************************************/
Sensor.h
#ifndef __LDR_H
#define __LDR_H
#include "sys.h"
#include "adc.h"
//定义两个常量//
#define LSENS_READ_TIMES 10 //定义光敏传感器读取次数,读10次,然后取平均值//
#define LSENS_ADC_CHX ADC_Channel_4 //定义光敏传感器所在的ADC通道编号,即0x06//
#define SOIL_ADC_CHX ADC_Channel_5 //定义土壤湿度传感器
//申明两个函数//
void Lsens_Soil_Init(void); //初始化光敏传感器和土壤湿度传感器函数//
u8 Get_ADC_Val(u8 ch);
#endif
main.c
#include "stm32f10x.h"
#include "usart.h"
#include "delay.h"
#include "ldr.h"
unsigned char ldr = 0;
unsigned char soil_humi = 0;
void Sensor_Task(void)
{
ldr = Get_ADC_Val(LSENS_ADC_CHX);
soil_humi = Get_ADC_Val(SOIL_ADC_CHX);
delay_ms(500);
printf("ldr = %d soli_value = %d\r\n",ldr,soil_humi);
}
int main(void)
{
LED_Init(); //led初始化
Init_Usart(); //串口初始化
Lsens_Soil_Init(); //光敏初始化
while(1)
{
Sensor_Task(); //数据采集任务
}
}
输出结果