STM32F103C8T6 × HAL库 × 霍尔效应脉冲检测
YF-S401 霍尔水流量传感器的工作原理与核心特性
1.1 工作原理
YF-S401 是一款基于霍尔效应的水流量传感器。其内部结构由水流管道、转子(叶轮)和霍尔传感器三部分组成。当水流通过管道时,水流的动能推动转子旋转,转子上镶嵌有磁铁,磁铁随转子一同转动。
每当磁铁经过霍尔传感器附近时,霍尔传感器检测到磁场变化并输出一个脉冲信号。转子转速与水流速度成正比,因此脉冲频率与水流量成线性关系。通过外部中断计数单位时间内的脉冲数,即可计算出水流量。
STM32 通过 GPIO 外部中断(EXTI)捕获 PB3 引脚的上升沿脉冲,每收到一个脉冲计数器 Pulse 加 1。主循环每 1 秒读取一次 Pulse 值作为瞬时流量(脉冲/秒),并清零重新计数,同时在 OLED 屏幕上显示。
通过转子转速反映水流量大小,脉冲频率与流量成正比,适用于液体流量测量。
输出方波脉冲信号,每个上升沿代表一定体积的水流通过,可直接连接MCU GPIO。
利用霍尔元件检测转子磁铁的旋转,非接触式检测,寿命长、响应快、抗干扰强。
配合STM32外部中断,可实现毫秒级脉冲捕获,每秒更新流量数据并显示在OLED上。
| 引脚 | 名称 | 功能 | STM32连接 |
|---|---|---|---|
| 1 | VCC | 电源正极(5V DC) | 5V / 3.3V |
| 2 | GND | 电源地 | GND |
| 3 | OUT | 脉冲信号输出 | PB3(EXTI3 上升沿) |
YF-S401 水流量传感器实物外观
YF-S401 水流量传感器外观 — 可见水流管道、转子腔体及三根引线(VCC/GND/OUT)
传感器模块的电路原理图与PCB封装设计
基于 STM32 HAL 库的 YF-S401 水流量传感器驱动程序解析
配置 PB3 为外部中断输入模式,上升沿触发。传感器输出的脉冲信号连接到 PB3,每次上升沿产生中断。中断优先级设为最高(0,0),确保脉冲捕获不丢失。
void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO 端口时钟使能 */ __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /* 配置 PB3 为外部中断模式,上升沿触发 */ GPIO_InitStruct.Pin = GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; // 上升沿触发中断 GPIO_InitStruct.Pull = GPIO_NOPULL; // 无上下拉 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* EXTI3 中断配置:优先级最高 */ HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 0); HAL_NVIC_EnableIRQ(EXTI3_IRQn); }
OLED 采用 0.96 导 SSD1306 驱动芯片,通过软件模拟 I2C 通信。SCL 接 PB15,SDA 接 PB14,均配置为开漏输出模式。初始化序列配置显示方向、对比度、充电泵等参数。
/* OLED 引脚宏定义 */ #define SCL_Port GPIOB #define SCL_Pin GPIO_PIN_15 // SCL -> PB15 #define SDA_Port GPIOB #define SDA_Pin GPIO_PIN_14 // SDA -> PB14 void OLED_GPIO_Init(void) { __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = SCL_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; // 开漏输出 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; // 50MHz HAL_GPIO_Init(SCL_Port, &GPIO_InitStruct); GPIO_InitStruct.Pin = SDA_Pin; HAL_GPIO_Init(SDA_Port, &GPIO_InitStruct); OLED_W_SCL(1); // 释放 SCL OLED_W_SDA(1); // 释放 SDA } void OLED_Init(void) { OLED_GPIO_Init(); OLED_WriteCommand(0xAE); // 关闭显示 OLED_WriteCommand(0xD5); OLED_WriteCommand(0x80); // 时钟分频 OLED_WriteCommand(0xA8); OLED_WriteCommand(0x3F); // 多路复用率 OLED_WriteCommand(0xA1); // 段重映射 OLED_WriteCommand(0xC8); // COM扫描方向 OLED_WriteCommand(0x8D); OLED_WriteCommand(0x14); // 充电泵使能 OLED_WriteCommand(0xAF); // 开启显示 OLED_Clear(); OLED_Update(); }
当 PB3 检测到上升沿时,触发 EXTI3 中断,最终调用 HAL_GPIO_EXTI_Callback 回调函数。在回调中判断中断源引脚,若为 GPIO_PIN_3 则 Pulse 计数器加 1。这是流量检测的核心逻辑——每个脉冲代表一定体积的水流通过传感器。
/* 全局变量定义 */ uint32_t Time_Now; // 时间戳,用于定时更新 uint16_t Pulse; // 脉冲计数器(中断中累加) uint16_t Flow; // 流量值(每秒脉冲数) /** * @brief 外部中断回调函数 * PB3 上升沿触发时,Pulse 计数器 +1 */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == GPIO_PIN_3) { Pulse++; // 每个脉冲代表一次水流通过 } }
主循环采用基于 HAL_GetTick() 的时间戳机制,每 1000ms(1秒)执行一次更新。将 Pulse 的值赋给 Flow(即1秒内的脉冲数,代表瞬时流量),然后清零 Pulse 重新计数。OLED 清屏后居中显示 "Flow:xxx",最后更新时间戳。
int main(void) { HAL_Init(); SystemClock_Config(); // 系统时钟:HSE 8MHz × PLL9 = 72MHz MX_GPIO_Init(); // GPIO初始化(PB3 EXTI配置) OLED_Init(); // OLED显示屏初始化 while (1) { /* 每 1000ms(1秒)更新一次流量数据 */ if(HAL_GetTick() - Time_Now >= 1000) { Flow = Pulse; // 1秒内的脉冲数 = 瞬时流量 Pulse = 0; // 清零,开始下一秒计数 OLED_Clear(); // 清屏 OLED_CenterPrintf(24, "Flow:%d", Flow); // 居中显示流量 OLED_Update(); // 更新OLED显示 Time_Now = HAL_GetTick(); // 更新时间戳 } } }
程序中 Flow 变量的值为每秒脉冲数(Hz),即传感器的输出频率。YF-S401 的脉冲频率与水流量存在线性关系,典型换算公式如下:
| 参数 | 说明 | 数值/公式 |
|---|---|---|
| Pulse | 中断累计脉冲数 | 每个上升沿 +1 |
| Flow | 1秒内脉冲数(频率) | Flow = Pulse / 1s |
| 更新周期 | 主循环刷新间隔 | 1000ms(1秒) |
STM32 水流量传感器检测程序执行流程
模拟水流量传感器的工作过程:水流驱动转子旋转,霍尔传感器输出脉冲,OLED 实时显示流量
管道:蓝色水流从左向右流动,流速由滑块控制
转子:水流推动转子旋转,流速越快转速越高
霍尔传感器:转子每旋转一圈,磁铁经过霍尔传感器,产生一个脉冲信号
脉冲信号线:PB3 引脚电平变化,上升沿触发 EXTI3 中断
OLED:0.96 寸 SSD1306,I2C 软件模拟通信
显示内容:每秒刷新一次,居中显示当前流量值
更新周期:1000ms(与实际程序一致)