STM32水位检测原理及水传感器应用详解

        起因于某位因查找对应资料效果不如意的小白,几经查找后,找到效果较为理想的工程,为后来小白节约时间,故此工程分享出来。

        本代码移植与江科大的的代码,侵权请联系删除。

基于STM32F103C8T6  标准库,能够检测电压并转化为水位深度(测量数据有偏差,自己修改) 

水位模块:Water Sensor

0.96寸OLED显示屏

以下为测试效果(当时没拍清楚照片)

一般水位最多测到4cm左右,因为再高水就碰到模块的元器件了,有短路风险

直接上关键部分工程

目录

bsp_adc.c代码

bsp_adc.h

#include "stm32f10x_it.h"

主函数部分


bsp_adc.c代码

使用的是adc1,引脚PA0





#include "bsp_adc.h"

__IO uint16_t ADC_ConvertedValue1;


/**
  * @brief  ADC GPIO 初始化
  * @param  无
  * @retval 无
  */
static void ADCx_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	// 打开 ADC IO端口时钟
	ADC_GPIO_APBxClock_FUN ( ADC_GPIO_CLK, ENABLE );
	
	// 配置 ADC IO 引脚模式
	// 必须为模拟输入
	GPIO_InitStructure.GPIO_Pin = ADC_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	
	// 初始化 ADC IO
	GPIO_Init(ADC_PORT, &GPIO_InitStructure);				
}

/**
  * @brief  配置ADC工作模式
  * @param  无
  * @retval 无
  */
static void ADCx_Mode_Config(void)
{
	ADC_InitTypeDef ADC_InitStructure;	

	// 打开ADC时钟
	ADC_APBxClock_FUN ( ADC_CLK, ENABLE );
	
	// ADC 模式配置
	// 只使用一个ADC,属于独立模式
	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;
	
	// 转换通道1个
	ADC_InitStructure.ADC_NbrOfChannel = 1;	
		
	// 初始化ADC
	ADC_Init(ADCx, &ADC_InitStructure);
	
	// 配置ADC时钟为PCLK2的8分频,即9MHz
	RCC_ADCCLKConfig(RCC_PCLK2_Div8); 
	
	// 配置 ADC 通道转换顺序和采样时间
	ADC_RegularChannelConfig(ADCx, ADC_CHANNEL, 1, 
	                         ADC_SampleTime_55Cycles5);
	
	// ADC 转换结束产生中断,在中断服务程序中读取转换值
	ADC_ITConfig(ADCx, ADC_IT_EOC, ENABLE);
	
	// 开启ADC ,并开始转换
	ADC_Cmd(ADCx, ENABLE);
	
	// 初始化ADC 校准寄存器  
	ADC_ResetCalibration(ADCx);
	// 等待校准寄存器初始化完成
	while(ADC_GetResetCalibrationStatus(ADCx));
	
	// ADC开始校准
	ADC_StartCalibration(ADCx);
	// 等待校准完成
	while(ADC_GetCalibrationStatus(ADCx));
	
	// 由于没有采用外部触发,所以使用软件触发ADC转换 
	ADC_SoftwareStartConvCmd(ADCx, ENABLE);
}

static void ADC_NVIC_Config(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
	// 优先级分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  // 配置中断优先级
  NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQ; 
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}


/**
  * @brief  ADC初始化
  * @param  无
  * @retval 无
  */
void ADCx_Init(void)
{
	ADCx_GPIO_Config();
	ADCx_Mode_Config();
	ADC_NVIC_Config();
}




#include "stm32f10x_it.h"

注意,得在#include "stm32f10x_it.h" 文件里面添加以下代码,否则可能导致oled不亮



///头文件上添加:

#include "bsp_adc.h"
extern __IO uint16_t ADC_ConvertedValue1;
 




void ADC_IRQHandler(void)
{	
	if (ADC_GetITStatus(ADCx,ADC_IT_EOC)==SET) 
	{
		// 读取ADC的转换值
		ADC_ConvertedValue1 = ADC_GetConversionValue(ADCx);
	}
	ADC_ClearITPendingBit(ADCx,ADC_IT_EOC);
}

主函数部分

//头文件上添加以下变量定义
 #include "bsp_adc.h"


 extern  uint16_t ADC_ConvertedValue1;

// 局部变量,用于保存转换计算后的电压值 	 
float ADC_ConvertedValueLocal;        
char Dis_AD_VO_Buf[20]={0};
char Dis_VA_Buf[20]={0};
char Dis_Depth_Buf[20]={0};
uint8_t Depth=0;
int16_t ADC_Depth;



int main()
{

     ADCx_Init();       

    while(1)
    {
          ADC_ConvertedValueLocal =(float) ADC_ConvertedValue1/4096*3.3; 
		ADC_Depth=ADC_ConvertedValueLocal;
		if((ADC_ConvertedValue1-1500)>0)
		{
				Depth=(ADC_ConvertedValue1-1550)/100;
		}
		else
		{
			Depth=0;
		}
		sprintf(Dis_AD_VO_Buf,"AD_VO:%.2fV  ",ADC_ConvertedValueLocal);
		sprintf(Dis_VA_Buf,"AD_VA:%d  ",ADC_ConvertedValue1);
		sprintf(Dis_Depth_Buf,"Depth:%d cm ",Depth);   
        //转换后可用串口或者显示屏显示,自己写
         OLED_ShowNum(4,1,(char)ADC_ConvertedValue1,4);
         OLED_ShowNum(4,8,(char)Depth,1);//显示为  cm
    }
}

PS:

        这是小白第一次写的文章。文章搬运江科大up的代码工程。

作者:锤子174

物联沃分享整理
物联沃-IOTWORD物联网 » STM32水位检测原理及水传感器应用详解

发表回复