基于STM32F407实现土壤湿度检测

        土壤湿度传感器它利用电磁脉冲原理、根据电磁波在介质中传播频率来测量土壤的表观介电常数,从而得到土壤相对含水量。

代码流程


    1.看原理图确定GPIO与ADC通道        PA5, ADC1IN5
    2.配置GPIO为模拟模式
    3.ADC初始化
        a.结构体申明     ADC_CommonInitTypeDef
        b.时钟使能
        c.结构体配置
        d.初始化
    4.ADC通道初始化
        a.结构体申明         ADC_InitTypeDef
        b.结构体配置
        c.初始化
    5.可以进行中断配置
        记得开中断,规则通道结束中断标志为ADC_IT_EOC
    6.各种使能
        a.ADC通道使能
        b.ADC使能
        c.软件开启ADC转换

ADC结构体的介绍在上一篇文章有讲

ADC等结构体的配置
void ADC_SOIL_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	ADC_CommonInitTypeDef ADC_CommonInitStructure;//通用初始化结构体,决定三个ADC 共用的工作环境,比如模式选择、ADC 时钟等等
	ADC_InitTypeDef ADC_InitStructure;

	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;
	//GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;			//单路模式
	ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div6;  //四分频,84/4 = 21Mhz ,低于36Mhz
	ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
	ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_10Cycles; //两次混合采样的周期延迟,独立模式怎么设置都不影响
	ADC_CommonInit(&ADC_CommonInitStructure);

	
	ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;				//是否扫面
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;	//是否连续
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
	ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //无边沿检测
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//右对齐
	ADC_InitStructure.ADC_NbrOfConversion = 1;
	ADC_Init(ADC1, &ADC_InitStructure);
	
	ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_84Cycles);
	
	ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); //开启规则转换结束中断
	
	ADC_Cmd(ADC1, ENABLE); //使能ADC
	
	ADC_SoftwareStartConv(ADC1);	//软件触发,开始转换
}
土壤湿度检测模块的引脚配置
void Gpio_Soil_Init(void)
{    	 
	GPIO_InitTypeDef GPIO_InitStructure;                     //定义一个设置GPIO的变量给土壤湿度检测器 - PA1
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);   //使能GPIOA端口时钟
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;       //设置PA1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; 
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;	//浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);            		 //设置PA
}
获得 ADC 值

//ch:通道值 0~16 ADC_Channel_0~ADC_Channel_16 
//返回值:转换结果 
u16 Get_Adc_Soil(u8 ch)
{ 
		//设置指定 ADC 的规则组通道,一个序列,采样时间 
	 ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles ); 
	
	 ADC_SoftwareStartConv(ADC1); //使能指定的 ADC3 的软件转换启动功能 
	
	 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束 
	
	 return ADC_GetConversionValue(ADC1); //返回最近一次 ADC3 规则组的转换结果 
}

平均多次ADC结果,提高精度     


/*参  数:channel: 通道数            
/*参  数:count: 平均次数      

int Get_Adc_Soil_Average(int channel,int count)
{
	int sum_val=0;
	char t;
	
	for(t=0;t
实现功能函数

这里我用的是OLED显示汉字和数据(字模可以用取模软件得到),没配置OLED的可以用串口打印一下

void soil_moisture(void)
{
    
    float raindata;     //接受雨滴数据
    float    voltage;//水位数据

    raindata = 90 - (((float)Get_Adc_Soil_Average(3,20))*(3.3/4096)*30);
    printf("雨水值:%.2f\r\n",raindata);
    
    if(raindata > 40)
    {
            printf("有雨水出现!\r\n");
    }
    else
    {
            printf("没有雨水出现!\r\n");
    }
    int i;
    for(i = 0;i < 4; i++)
    {
        OLED_ShowSoil(1,i+1,i);//显示汉字 - 土壤湿度
    }
    OLED_ShowString(1,9,":");
            
    OLED_ShowNum(1,10,(int)raindata,2);

}

你可能感兴趣的:(stm32,单片机,嵌入式硬件)