蓝桥杯嵌入式备赛实战:用STM32G431实现液位监测系统(附完整源码解析)

张开发
2026/6/9 8:14:55 15 分钟阅读

分享文章

蓝桥杯嵌入式备赛实战:用STM32G431实现液位监测系统(附完整源码解析)
基于STM32G431的智能液位监测系统开发实战在工业自动化、环境监测和智能家居等领域液位监测是一个常见但至关重要的功能需求。本文将带您从零开始构建一个完整的智能液位监测系统基于STM32G431微控制器融合ADC采样、LCD显示、按键控制、LED状态指示、串口通信和EEPROM存储等多项技术。1. 系统架构设计与硬件选型一个完整的液位监测系统需要考虑传感器选型、信号处理、人机交互和数据存储等多个环节。我们选择STM32G431作为主控芯片这是一款基于Arm Cortex-M4内核的微控制器具有丰富的外设资源和出色的实时性能。核心硬件组件清单STM32G431RB微控制器电阻式液位传感器或超声波传感器2.4寸TFT LCD显示屏4个机械按键3个LED状态指示灯EEPROM存储芯片AT24C02USB转串口模块硬件连接示意图如下外设模块STM32引脚功能描述液位传感器PA1ADC2通道1模拟输入按键1PB0模式切换/确认按键2PB1参数切换按键3PB2参数增加按键4PA0参数减少LED1PC8系统运行状态指示LED2PC9液位变化报警指示LED3PC10串口通信指示LCD_CSPB12LCD片选信号LCD_SCKPB13SPI时钟LCD_MISOPB14SPI主机输入LCD_MOSIPB15SPI主机输出I2C_SCLPB6EEPROM时钟线I2C_SDAPB7EEPROM数据线2. 软件架构设计与关键模块实现2.1 主程序流程设计系统采用前后台架构主循环负责调度各功能模块中断处理实时性要求高的任务。以下是精简后的main.c核心逻辑int main(void) { // 硬件初始化 HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_ADC2_Init(); MX_TIM2_Init(); MX_USART1_UART_Init(); // 外设初始化 HAL_TIM_Base_Start_IT(htim2); // 启动1ms定时器中断 HAL_UART_Receive_IT(huart1, OneData, 1); // 启动串口接收中断 LCD_Init(); I2CInit(); // 初始化EEPROM默认值 E2PROM_Write(0x00, min); HAL_Delay(5); E2PROM_Write(0x01, med); HAL_Delay(5); E2PROM_Write(0x02, max); HAL_Delay(5); // 主循环 while (1) { adc_process(); // ADC采样处理 key_process(); // 按键处理 lcd_process(); // LCD显示更新 led_process(); // LED状态控制 rx_process(); // 串口数据处理 } }2.2 ADC采样与液位计算液位监测的核心是ADC采样和数据处理。我们采用均值滤波算法提高测量稳定性float get_Adc(ADC_HandleTypeDef *hadc) { int val 0.0f; for(int i 0; i 5; i) { HAL_ADC_Start(hadc); HAL_ADC_PollForConversion(hadc, 100); val HAL_ADC_GetValue(hadc); HAL_ADC_Stop(hadc); } return val * 3.3f / 4096.0f / 5.0f; // 转换为电压值并取平均 }液位高度计算采用线性转换公式height k * adc_value其中k为传感器特性系数需根据实际传感器标定。2.3 多任务调度与状态机设计系统使用1ms定时器中断作为时间基准实现精确的时序控制void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim-Instance TIM2) { // 按键扫描 key[0].key_gpio HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0); // ...其他按键扫描 // 定时计数器更新 adctimes; led1times; led2times; led3times; } }界面切换采用状态机设计通过view变量控制不同显示模式void lcd_process(void) { switch(view) { case 0: // 主显示界面 sprintf((char *)lcdtext, Liquid Level); LCD_DisplayStringLine(Line0,lcdtext); // ...其他显示内容 break; case 1: // 参数设置界面 sprintf((char *)lcdtext, Parameter Setup); LCD_DisplayStringLine(Line0,lcdtext); // ...其他显示内容 break; // ...其他界面状态 } }3. 关键问题解决与优化技巧3.1 I2C通信稳定性优化EEPROM读写操作需要注意时序问题特别是连续写入时需要保持足够的时间间隔void E2PROM_Write(uint8_t addr, uint8_t data) { I2CStart(); I2CSendByte(0xA0); I2CWaitAck(); I2CSendByte(addr); I2CWaitAck(); I2CSendByte(data); I2CWaitAck(); I2CStop(); HAL_Delay(5); // 必须的延时确保写入完成 }提示AT24C02系列EEPROM的页写入周期典型值为5ms连续写入时必须遵守这个时间间隔否则会导致数据写入失败。3.2 液位变化检测算法为了避免频繁触发液位变化报警我们采用带滞回的比较算法void adc_process(void) { if(adctimes 1000) { // 1秒采样一次 adctimes 0; newheight k * get_Adc(hadc2); // 液位分级判断 if(newheight min) newlevel 0; else if(newheight med) newlevel 1; else if(newheight max) newlevel 2; else newlevel 3; // 液位变化检测带5mm滞回 if(abs(newheight - height) 5 || newlevel ! level) { led2flag 1; // 触发LED报警 height newheight; level newlevel; // 发送串口通知 sprintf((char *)txtext, A:H%dL%d\r\n, height, level); HAL_UART_Transmit(huart1, (uint8_t *)txtext, strlen((char *)txtext), 50); } } }3.3 低功耗优化策略对于电池供电的应用场景可以采用以下优化措施动态时钟调整根据任务负载动态调整系统时钟频率外设电源管理不使用时关闭LCD背光、传感器电源等间歇工作模式设置ADC采样间隔从1秒延长到5秒或更长睡眠模式在无操作时进入STOP模式通过按键或定时器唤醒4. 系统功能扩展与进阶开发4.1 无线通信模块集成通过添加蓝牙或Wi-Fi模块可以实现远程监控// 伪代码示例通过串口发送JSON格式数据 void send_web_data(void) { sprintf(json_buffer, {\level\:%d,\height\:%d,\voltage\:%.2f}, level, height, adcval); HAL_UART_Transmit(huart1, (uint8_t *)json_buffer, strlen(json_buffer), 100); }4.2 上位机监控软件开发使用Python可以快速开发一个简单的监控界面import serial import matplotlib.pyplot as plt ser serial.Serial(COM3, 115200, timeout1) data [] while True: line ser.readline().decode().strip() if line.startswith(A:H): height int(line.split(H)[1].split()[0]) data.append(height) plt.plot(data) plt.pause(0.01)4.3 多传感器数据融合为了提高测量精度可以结合多种传感器电阻式传感器成本低适合静态液位测量超声波传感器非接触式适合腐蚀性液体压力传感器可测量深罐体液位光电传感器检测液面是否存在通过卡尔曼滤波算法融合多传感器数据可以得到更稳定可靠的测量结果。

更多文章