基于Labview与STM32单片机的智能液位控制装置:双向通信与实时显示
咱们这次用STM32F103C8T6当主控,搭配双继电器玩抽水与进水,OLED实时显示水位曲线,再通过Labview整点工业上位机的仪式感——这组合拳打下来,高低得让毕设老师眼前一亮。整套系统跑起来后,看着Labview上跳动的曲线和实体设备联动的效果,突然理解了什么叫做"软硬兼施"的快乐。代码仓库里扔着stm32部分的HAL库版本和标准库版本,还有Labview2018和2023的工程文件——毕
基于Labview和单片机的液位控制装置 一,功能说明 (1)基于STM32实现主控; (2)OLED实现具体液位控制过程的展示; (3)双继电器控制抽水和进水; (4)液位传感器实现水位数据的测量; (6)t独立按键实现液位的阈值; (6)LABVIEW作为上位机,通过波形图展示实时的水位变化过程 (7)和下位机具备双向通信,可以在上位机上直接改变阈值信息。 二,关键词 Labview; 32单片机;双向通信 三,包含的东西 1、配套文档一份 2、代码+原理图+下位机程序+上位机程序(Labview)
撸起袖子干一个基于Labview和单片机的液位控制系统,绝对是硬件狗和Labview玩家的双重快乐。咱们这次用STM32F103C8T6当主控,搭配双继电器玩抽水与进水,OLED实时显示水位曲线,再通过Labview整点工业上位机的仪式感——这组合拳打下来,高低得让毕设老师眼前一亮。
先说硬件部分的重头戏,液位传感器选了个模拟输出的型号,直接怼到STM32的ADC1通道上。核心代码就这几行:
void ADC1_Init(void) {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);
ADC_Cmd(ADC1, ENABLE);
}
uint16_t Get_WaterLevel(void) {
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
return ADC_GetConversionValue(ADC1);
}
这ADC配置看着简单,实际调试时发现采样周期得调到239.5个周期才能抗住实验室电源的波纹干扰。转换后的数值用滑动平均滤波处理,实测波动能控制在±2cm以内。

OLED显示用硬件I2C驱动,重点在界面布局。把水位柱状图和阈值线做成了动态效果:
void Draw_WaterLevel(uint8_t level) {
OLED_DrawLine(0, 63-level, 127, 63-level); // 水位线
OLED_DrawRectangle(105, 20, 127, 30); // 阈值显示框
OLED_ShowNum(107, 22, current_threshold, 3, 8);
}
当水位超过阈值时,整个柱状图会变成闪烁的红色——这招是通过反复擦写局部区域实现的,比全局刷新省资源得多。
按键配置最怕抖动,这里直接上定时器消抖方案:
void EXTI0_IRQHandler(void) {
if(EXTI_GetITStatus(EXTI_Line0) != RESET) {
TIM_Cmd(TIM2, ENABLE); // 启动消抖定时器
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
配合50ms的定时器中断检测引脚电平,实测在实验室各种暴力拍打下也没出现误触发。
基于Labview和单片机的液位控制装置 一,功能说明 (1)基于STM32实现主控; (2)OLED实现具体液位控制过程的展示; (3)双继电器控制抽水和进水; (4)液位传感器实现水位数据的测量; (6)t独立按键实现液位的阈值; (6)LABVIEW作为上位机,通过波形图展示实时的水位变化过程 (7)和下位机具备双向通信,可以在上位机上直接改变阈值信息。 二,关键词 Labview; 32单片机;双向通信 三,包含的东西 1、配套文档一份 2、代码+原理图+下位机程序+上位机程序(Labview)

Labview上位机用VISA串口通信,前面板放了两个关键控件:波形图表和数值输入框。数据解析部分用了移位寄存器做缓存,防止数据包被截断:
VISA读取 -> 字符串至字节数组 -> 拼接循环缓冲区 -> 提取完整帧(0xAA开头0x55结尾)
特别要注意的是STM32发送的浮点数用联合体处理:
typedef union {
float f_val;
uint8_t bytes[4];
} float_union;
Labview端用"拆解字符串"函数按大端模式重组,再用类型转换变成单精度浮点数。实测115200波特率下,500ms的刷新周期刚好能稳定传输。
双向通信的骚操作在阈值修改功能。当Labview发送新阈值时,STM32会先回复ACK信号:
if(rx_buf[1] == 0x01) { // 阈值修改指令
new_threshold = (rx_buf[3]<<8) | rx_buf[2];
Send_ACK();
}
同时OLED立即刷新显示,避免出现设置值与实际值不同步的尴尬。调试时曾遇到Modbus协议和自定义协议混用导致的冲突,最后改用纯自定义协议才解决。
项目最坑的居然是继电器控制逻辑——抽水和进水必须互锁,还要加状态反馈:
void Pump_Ctrl(uint8_t mode) {
if(mode == PUMP_IN) {
GPIO_ResetBits(GPIOA, IN_PIN);
GPIO_SetBits(GPIOA, OUT_PIN);
} else {
GPIO_SetBits(GPIOA, IN_PIN);
GPIO_ResetBits(GPIOA, OUT_PIN);
}
}
看似简单的GPIO操作,实际接线时忘了加续流二极管,结果现场演示时继电器火花带闪电,差点把院长吓出表情包。

整套系统跑起来后,看着Labview上跳动的曲线和实体设备联动的效果,突然理解了什么叫做"软硬兼施"的快乐。代码仓库里扔着stm32部分的HAL库版本和标准库版本,还有Labview2018和2023的工程文件——毕竟,兼容性才是工程项目的终极boss战。
更多推荐



所有评论(0)