资讯详情

基于51单片机的输液报警控制系统:滴速与液位分路检测设计与仿真

📅 2026/9/13 13:55:31 | 华诺云谱 👁 阅读
基于51单片机的输液报警控制系统:滴速与液位分路检测设计与仿真
简介基于51单片机的输液报警控制系统设计资源面向电子、自动化及嵌入式方向的课程设计与毕业设计人群针对输液过程中滴速与液位监测报警的实际需求提供一套从检测、显示到报警的完整软硬件方案。压缩包共43个文件、约828KB包含C语言源程序、Proteus仿真工程、Altium Designer原理图及PDF预览、元件清单、流程图和编译生成的hex、lst、obj等程序构建文件DSN仿真工程可直接打开运行SchDoc原理图便于二次修改能够满足从原理学习到仿真验证、实物烧录的完整流程。目前已有146人学习浏览。设计上以电位器代替液位传感器、信号发生器代替滴速传感器借助ADC0832进行数据采集由STC89C52等51系列单片机处理并在LCD1602上显示同时支持设定报警阈值测量值越限即报警其中可重点学习ADC0832采集、LCD1602显示驱动、阈值比较逻辑等模块化编程方法。原理图与仿真工程相互对应源代码结构清晰便于初学者理解各模块协作也可根据实际传感器替换模拟输入快速扩展为临床输液监测装置原型。1. 输液报警控制系统为什么滴速和液位要分开测我在调试这套基于51单片机的输液报警控制系统时最先卡住的不是代码而是「滴速」和「液位」这两路输入根本不是同一种信号滴速是脉冲频率量液位是缓慢变化的模拟量。把它们混在一个采集通道里后面做阈值判断全是错的。这个系统用STC89C52这类51内核单片机外扩ADC0832双通道ADC和LCD1602显示在Proteus里用信号发生器模拟滴速脉冲、用电位器模拟液位电压完整实现了滴速超限报警和低液位报警。对正在做单片机课程设计或者想快速搭建输液监护原型的工程师来说这套资料的价值在于原理图、PCB、C源代码、Proteus仿真文件一次给齐照着把「传感器替代」这一层看懂再替换成真实红外对管和液位传感器逻辑几乎不用改。2. 原理图与PCB设计ADC0832双通道采样链路与传感器替代方案2.1 系统硬件架构与管脚分配这套系统的单片机按AT89C52或STC89C52处理12MHz晶振。外围模块主要有LCD1602显示、ADC0832采集、蜂鸣器报警和三个按键输入。Proteus元件清单里能看到Lcd、ADC0832、Resistors、Capacitors、Buzzer、Button、Potentiometer以及仿真用的信号发生器。我在Keil工程里看main.c管脚定义基本是这样#define LCD_DATA P0 // LCD1602 8位数据口 sbit LCD_RS P2^0; // 寄存器选择0命令1数据 sbit LCD_RW P2^1; // 读写选择0写1读 sbit LCD_EN P2^2; // 使能信号下降沿锁存 sbit ADC_CS P1^0; // ADC0832 片选低有效 sbit ADC_CLK P1^1; // ADC0832 时钟 sbit ADC_DIO P1^2; // ADC0832 双向数据线 sbit BEEP P2^3; // 蜂鸣器低电平触发 sbit KEY_SET P3^2; // 设置键 sbit KEY_UP P3^3; // 加键 sbit KEY_DOWN P3^4; // 减键这段代码把LCD数据总线放在P0口是因为P0内部没有上拉电阻接LCD时必须在外部加4.7k或10k排阻否则高电平拉不上去。ADC0832用P1.0到P1.2三根线控制比ADC0809省了8根并行数据和一堆控制线做PCB时走线压力小很多。蜂鸣器我按低电平驱动处理单片机IO口高电平驱动能力弱用8550三极管在低电平时导通更可靠。各模块与单片机引脚的对应关系如下外设信号线单片机引脚说明LCD1602RS/RW/ENP2.0/P2.1/P2.28位数据模式ADC0832CS/CLK/DIOP1.0/P1.1/P1.2双通道8位ADC滴速输入INT0P3.2信号发生器方波脉冲输入液位模拟CH0ADC0832的CH0输入电位器中点电压蜂鸣器BEEPP2.3低电平触发按键SET/UP/DOWNP3.2/P3.3/P3.4设置报警阈值注意KEY_SET和滴速中断输入共用P3.2原资源里信号发生器直接接在外部中断引脚上所以按键只能用查询方式扫描。做实物时我一般会把这个引脚拆开滴速走P3.2中断按键换到P2口避免仿真能跑、实物按键受脉冲干扰的情况。2.2 液位检测电位器怎么代替真实液位传感器真实输液液位检测常见两种方案红外对管贴在莫非氏滴管两侧有液和无液时透光率不同电容式接近开关探测液面是否降到警戒线。无论哪种输出基本都是电压等级或开关量。仿真里用10k电位器代替电位器接在5V和GND之间中间抽头进ADC0832的CH0旋转电位器就等于改变液位传感器的输出电压。原理图上要注意分压范围和ADC输入耐压。ADC0832参考电压接VCC为5V输入范围0到5V电位器分压恰好落在这个区间。真实传感器如果输出0到3.3V可以直接接但要重新计算阈值如果输出4到20mA电流必须加250欧采样电阻转成1到5V电压。我在做实物时会在ADC输入前串联一个100欧电阻和0.1uF电容滤掉传感器引线上的高频噪声。2.3 滴速检测信号发生器与红外对管的等效关系真实滴速传感器是红外对管液滴掉入滴壶瞬间遮挡红外光接收管输出一个脉冲。Proteus里用信号发生器代替选择方波频率就代表每秒的滴数。比如1Hz就是每秒1个脉冲换算成滴速是60滴/分钟。容易被忽略的是触发条件。单片机外部中断检测下降沿信号发生器必须选方波幅度覆盖TTL电平。我一般设幅度5V、偏置2.5V波形在0V到5V跳变。幅度设成1V或10V都不行Proteus数字仿真可能识别不到稳定跳变导致中断不触发。2.4 PCB布局布线的几个实用惯例原理图用Altium打开PCB文件可以直接继续铺板。51单片机这种低速板两层就够。我布线时主要管三件事晶振X1和两个20pF到30pF负载电容紧靠单片机X1、X2引脚走线越短越好ADC0832的模拟输入线远离晶振和P0总线防止数字噪声耦合进液位采样蜂鸣器驱动三极管的地要和单片机数字地单点连接关断瞬间的电流变化不会拉低ADC参考电压。提示: Proteus仿真文件里只有DSNPCB工程在Altium一侧。想直接打样的话先核对电位器和按键封装尺寸这两种器件最容易买错。3. C语言固件实现LCD1602驱动、ADC0832读取与滴速计数3.1 Keil工程结构与生成HEX的流程程序文件夹里有main.c、lcd1602.c、ADC0832.C、STARTUP.A51以及main.uvproj工程文件。用Keil打开main.uvproj编译后输出main.hex这个HEX文件在Proteus里加载到单片机。STARTUP.A51是Keil自动生成的启动文件负责清零和堆栈初始化通常不用改。编译设置里要注意Device选择AT89C52或STC89C52都可以Output选项卡必须勾选Create HEX File。晶振频率设为12MHz这样代码里所有延时函数的时间基准才是准的。源代码把LCD1602和ADC0832分文件实现main.c只做逻辑调度这是课程设计里比较清晰的分层方式后续把lcd1602.c换成OLED驱动或者把ADC0832换成TLC1543都不会动到主流程。3.2 LCD1602显示延时代替读忙LCD1602初始化我习惯用延时不读忙标志。因为代码少Proteus下也很稳定。下面这段是lcd1602.c里最核心的写命令函数void LCD_WriteCmd(unsigned char cmd) { LCD_RS 0; // 命令模式 LCD_RW 0; // 写操作 LCD_DATA cmd; // 命令字送到数据口 LCD_EN 1; // 使能高电平 delay_5us(); // 建立时间至少几微秒 LCD_EN 0; // 下降沿锁存数据 delay_1ms(); // 等待内部处理 }逻辑说明LCD1602在EN引脚的下降沿锁存数据线上的命令或数据所以先置EN1保持一小段时间再拉低。RS决定访问命令寄存器还是数据寄存器RW固定为0表示只写。0x38设置8位数据、2行、5x7点阵0x0C开显示不显示光标0x01清屏。如果显示乱码先查RS/RW/EN接线顺序再看初始化前有没有等15ms以上的上电延时。3.3 ADC0832读取三线SPI式时序ADC0832是8位双通道逐次逼近型ADC通过CS、CLK、DIO三根线做类似SPI的串行通信。读取CH0的时序是CS拉低后在CLK上升沿前把DIO置高表示起始位接着写入通道选择位再在CLK下降沿读数据。下面代码按常见时序读取一位通道的数据unsigned char ADC0832_Read(unsigned char ch) { unsigned char i, dat 0; ADC_CS 0; // 片选有效 ADC_CLK 0; ADC_DIO 1; // 起始位 ADC_CLK 1; ADC_CLK 0; ADC_DIO ch; // 通道选择0或1 ADC_CLK 1; ADC_CLK 0; ADC_CLK 1; ADC_CLK 0; // 第一个转换时钟 for (i 0; i 8; i) // 读取8位数据 { dat 1; ADC_CLK 1; ADC_CLK 0; if (ADC_DIO) dat | 0x01; // 从高位开始读 } ADC_CS 1; // 片选释放 return dat; }参数说明ch传0读CH0液位传1读CH1滴速幅度。滴速本质是频率信号但也可以先用ADC看一眼波形幅度是否正常。8位ADC在5V参考下分辨率是5/256约0.0195V对液位报警足够。时序上要注意CLK翻转间隔Proteus仿真可以很快实物上51单片机IO翻转速度有限建议在CLK翻转之间加一个NOP防止ADC0832采样不稳定。3.4 滴速计数和报警逻辑定时器与外部中断配合滴速测量我采用最常用做法外部中断INT0对脉冲下降沿计数定时器T0定时1秒每秒把计数器累加进数组再取最近10秒平均值乘6得到滴/分钟。这比直接测单个周期更抗干扰真实红外对管输出会有毛刺。unsigned int pulse_count 0; // 1秒内脉冲数 unsigned int speed_smooth 0; // 滤波后的滴速 unsigned char time_1s 0; // 1秒标志 void INT0_ISR() interrupt 0 // 外部中断0下降沿触发 { pulse_count; } void Timer0_ISR() interrupt 1 // 50ms中断累计20次得到1秒 { static unsigned int sum 0; TH0 0x4C; TL0 0x00; // 12MHz下50ms重装初值 if (time_1s 20) { time_1s 0; sum pulse_count; pulse_count 0; if (time_1s % 10 0) // 每10秒更新一次平滑值 { speed_smooth sum * 6; // 10秒总脉冲数换算成滴/分 sum 0; } } }逻辑说明定时器0工作在方式116位计数器12MHz晶振下每50ms中断一次20次累积为1秒。每次进入1秒逻辑时把pulse_count累加到sum10秒后sum*6就是等效每分钟滴数。这样显示值不会每秒跳变。报警条件一般是speed_smooth超过上限或低于下限并且持续3秒再触发液位阈值直接和ADC0832读回值比较低于设定值立刻报警报警动作就是BEEP0并让LCD闪烁。提示: 如果信号发生器频率调到10Hz以上每秒计数会到600滴/分要确认上限报警值设置合理。真实临床输液滴速通常在20到60滴/分。4. Proteus仿真搭建信号发生器模拟滴速电位器模拟液位4.1 打开仿真DSN与加载HEX文件解压后找到仿真文件夹用Proteus ISIS打开“仿真.DSN”。文件里已经放好单片机、LCD、ADC0832、电位器、信号发生器和蜂鸣器。双击单片机元件在Program File属性里选择Keil生成的main.hexClock Frequency设为12MHz。点击运行按钮LCD上应出现滴速和液位数值。Proteus版本不同会导致部分元件显示为灰色8.x以上打开老DSN基本兼容但AT89C52的Program File路径如果丢失单片机不会执行代码。重新指定HEX后最好按一下复位按钮再观察。Proteus 8 Professional里这个操作在Debug菜单下也有仿真运行中改代码后重新加载HEX时仿真器不会自动复位手动复位是习惯动作。4.2 信号发生器参数设置用频率直接对应滴速双击信号发生器波形选择Square方波。频率换算关系1Hz等于60滴/分钟。常用参数如下滴速滴/分信号发生器频率Hz脉冲周期秒200.3333.0300.52.0400.6671.5601.01.01202.00.5幅度设为5V偏置设为2.5V。这样方波在0V和5V之间跳变。如果信号发生器输出的是双极性波形低电平低于0.8V才能被识别成TTL低电平INT0下降沿才可靠。可以用Proteus右侧工具栏里的虚拟示波器把信号发生器和单片机引脚同时接上去观察波形是否满足要求。4.3 电位器模拟液位从满瓶到警戒线液位用电位器RV1调整。按5V供电电位器调到最高时CH0电压5VADC值255代表液位最高调到20%时电压约1VADC值51代表液位接近警戒。主程序里液位报警值通常设一个ADC比较值我建议先旋转电位器到“液位大概1/3处”看LCD上显示的数字再把这个数字减去20作为报警点。如果电位器调整后ADC读数不变先在电位器滑动端挂一个虚拟电压表确认电压真的在变化。常见原因是电位器抽头接到ADC0832的CH1而不是CH0或者接地端悬空。Proteus里电位器默认中间抽头有明细端子连接时要看清网络标号。4.4 仿真运行时的常见故障与排查我在Proteus里遇到过三类典型问题。第一类LCD只有背光没有字符原因是P0口没加上拉排阻或者LCD的VO引脚直接接地导致对比度过高。解决办法在VO接一个10k电位器到GND调节出正常对比度。第二类ADC0832读到255不变多数是CLK和DIO接反DIO是双向口接反就读不回数据。第三类仿真卡死或提示仿真发散先查电源节点和信号发生器的幅度是否过大再把ADC输入端的模拟地和数字地检查一遍。提示: 虚拟示波器在Proteus右侧“Virtual Instruments”面板里拖出来挂到信号发生器输出端确认频率和幅度与设置一致再排查单片机侧逻辑。5. 阈值整定与报警边界让仿真结果逼近真实输液场景5.1 用线性映射把ADC值换算成物理量直接拿ADC原始值报警不是不行但换传感器后要重新改代码。更实用的方式是把ADC值映射成0到100的液位百分比满量程5V对应255unsigned char level_percent; level_percent (unsigned char)((unsigned long)adc_value * 100 / 255);adc_value是ADC0832读到的8位值乘100再除以255结果落在0到100之间。这样报警值设置成20就代表液位低于约1V时报警。滴速也一样可以做标定系数真实红外对管的输出频率和滴速不一定是1:1液滴遮挡光路时可能一个脉冲被分成两次下降沿解决办法是在中断里加10ms消抖或者把speed_smooth乘0.5。5.2 低速滴速用周期测量法如果滴速很慢比如低于20滴/分1秒计数的办法会频繁读到0。我一般在这种场景改用测周期法外部中断记录相邻两次下降沿的定时器计数值用定时器频率除以计数值得到单滴间隔再换算成分速。这个方式分辨率高但单次测量容易毛刺最终显示还是要做滑动平均。一个折中方案是把计数窗口从1秒拉长到5秒读数更新慢一点但稳定很多。5.3 报警带迟滞避免反复触发最后一个技巧报警阈值不要用单点比较。低液位报警设为20%恢复阈值设为25%这样液位在报警点附近波动时不会刚报警又马上解除。实现上就是定义两个全局变量low_limit和low_limit_recover判断时分开比较if (level_percent low_limit) BEEP 0; // 进入报警 else if (level_percent low_limit_recover) BEEP 1; // 回差恢复low_limit和low_limit_recover分别存20和25中间5%就是迟滞带。这段逻辑改动很小但能把“报警器每隔两秒响一次”的问题彻底压掉。把这些参数整定思路带回真实输液装置把信号发生器换成红外对管整形电路把电位器换成液位传感器代码里只调整采样系数和迟滞带宽度报警行为基本不用动。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。