STM32 水位检测 Water Sensor

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

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

基于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的代码工程。

### 配置 Water Sensor 模块与 STM32CubeMX 的集成 #### 设置 STM32 硬件 在 STM32CubeMX 中配置 Water Sensor 模块涉及多个步骤,主要包括 ADC 初始化、GPIO 配置以及可能使用的通信协议(如 I2C 或 SPI)。以下是详细的说明: #### 1. 配置 GPIO 和 ADC 模块 Water Sensor 是一种常见的模拟传感器,其输出电压随液体高度变化而改变。因此,在 STM32CubeMX 中需要启用 ADC 功能来读取该模拟信号。 - 打开 **STM32CubeMX** 软件并加载目标 MCU 型号。 - 进入 **Pinout & Configuration** 页面,找到用于连接 Water Sensor 的引脚,并将其模式设置为 **Analog (AN)**。 - 在左侧的外设列表中选择 **ADC** 并激活它。确保所选通道对应于之前配置的 GPIO 引脚[^1]。 #### 2. 参数调整 进入 ADC 外设的具体参数页面,完成以下设置: - **Resolution**: 根据需求选择分辨率(通常是 12-bit)。 - **Data Alignment**: 数据对齐方式可以选择左对齐或右对齐。 - **Sampling Time**: 设定采样时间以适应 Water Sensor 输出特性。 - 启用连续转换模式或者扫描模式以便实时获取水位数据[^2]。 #### 3. 添加中断/DMA 支持(可选) 如果希望提高效率,则可以考虑开启 DMA 来自动传输 ADC 结果至内存缓冲区;也可以通过 NVIC 配置触发相应的中断服务程序处理每次测量后的逻辑运算。 #### 4. 导出项目到 IDE 当所有必要的硬件资源都已正确分配完毕之后,点击菜单栏中的 “Project -> Generate Code”,这会自动生成初始化代码框架并将整个工程导出给指定的集成开发环境(比如STM32CubeIDE)[^3]。 #### 示例代码片段 下面展示了一段简单的 C 语言代码用来演示如何利用上述配置好的 ADC 接口去采集来自 water sensor 的数值: ```c #include "stm32f4xx_hal.h" void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_ADC1_Init(void); int main(void){ HAL_Init(); SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_ADC1_Init(); while (1) { uint16_t adcValue; // Start conversion and get the result. HAL_ADC_Start(&hadc1); HAL_ADC_PollForConversion(&hadc1, 100); adcValue = HAL_ADC_GetValue(&hadc1); printf("Current Water Level Value:%d\n",adcValue); HAL_Delay(1000); // Delay one second between readings. } } // Initialization functions omitted here... ``` 此代码展示了基本的操作流程——启动一次新的 AD 转换请求,等待直到有有效结果返回后再打印当前检测到的水量等级值。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值