收藏 分销(赏)

液体点滴速度监控装置(最终版).doc

上传人:天**** 文档编号:4683492 上传时间:2024-10-09 格式:DOC 页数:25 大小:307.01KB 下载积分:10 金币
下载 相关 举报
液体点滴速度监控装置(最终版).doc_第1页
第1页 / 共25页
液体点滴速度监控装置(最终版).doc_第2页
第2页 / 共25页


点击查看更多>>
资源描述
液体点滴速度监控装置 组员:李海豹 王会强 杨亚娟 时间:2011年7月27日 液体点滴速度监控装置 摘要:本系统设计是以单片机STC89C52为核心,以键盘及红外对射式传感器作为输入系统,以液晶显示屏及电动机作为输出系统的智能化输液控制及监测系统。键盘系统为矩阵式按键系统,红外传感器的功能为检测点滴的速度,红外对管监测储液瓶内液体剩余量,少于一定量时报警。报警系统用蜂鸣器。电动机具有转速可控功率大及输入脉冲不变时可保持大力矩等优点,这样就可以自如控制吊瓶的上、下缓移可以达到智能控制的目的。 关键字:红外对射式传感器 矩阵式按键系统 智能化输液控制监测系统 目录 1 系统设计 1 1.1 方案选择 1 1.1.1 点滴速度监测方案 ……………………………………………………………………..1 1.1.2 储液量监测方案……………………………………………………………………........1 1.1.3 键盘显示模块方案设计…………………………………………………………………1 1.1.4 电机控制系统模块………………………………………………………………………1 1.2 系统最终方案确定………………………………………………………………………...1 2 单元电路设计……………………………………………………………………………………2 2.1 点滴速度测量电路设计…………………………………………………………………….2 2.2 储液检测电路……………………………………………………………………………….2 2.3 键盘显示电路……………………………………………………………………………….3 2.4 点滴速度控制电路设计…………………………………………………………………….3 3 系统软件设计……………………………………………………………………………………5 3.1 检测点滴速度子程序……………………………………………………………………….5 3.2 储液检测子程序…………………………………………………………………………….5 3.3点滴速度控制子程序………………………………………………………………………..6 3.4键盘显示子程序……………………………………………………………………………..6 3.5系统的主程序设计…………………………………………………………………………..7 4 系统测试…………………….…………………………………………………………………...8 5结论……………………………………………………………………………………………….9 参考文献…………………………………………………………………………………………..10 附录………………………………………………………………………………………………..11 1 系统设计 1.1 方案选择 1.1.1 点滴速度监测方案 方案一,采用红外对管测量点滴一段时间落下的液滴数,点滴落下时挡住了红外发射管发 出的光,接收管无法接受。此时计数一次。采用塑料泡沫将对管固定在滴斗上,简单轻巧,减小滴管摆动带来的采集误差,同时不影响电机工作。 方案二, 采用电感式传感器测量点滴速度。在输液器的漏斗外围绕线圈作为敏感元件。当液滴滴下是电感量发生变化,通过LC振荡电路后输出变化的频率值,经过F/V变换电路及电压比较后输出TTL电平信号来检测点滴速度。此方案测量精度比较高,但是外围电路比较复杂。 1.1.2 储液量监测方案 方案一:同点滴速度测量模块,仍然采用红外对管发射接收。根据该接收管收到的光强的大小来判断液位是否达到警戒水位。 方案二:采用称重传感器检测。利用称重传感器检测总质量,并与实际测量中当液体液面达到设定位置时的总质量相比较,根据液体体积与质量的关系,当测量总质量与设定值相等时发出报警。 1.1.3 键盘显示模块方案设计 方案一:采用液晶显示屏和通用矩阵键盘。液晶显示屏用1602。液晶显示屏(LCD)具有功耗小、轻薄短小无辐射危险,平面直角显示以及影象稳定不闪烁,可视面积大,画面效果好,抗干扰能力强等特点。输入简单,灵活。 方案二:采用三位LED七段数码管显示点滴数目。按键采用单列三按键。数码管具有:低能耗、低损耗、低压、寿命长、耐老化,对外界环境要求较低。但数码管显示时,每个字符都要查询段码值,使用起来没有液晶显示方便。 1.1.4 电机控制系统模块 方案一:通过改变滴斗到受液瓶的高度来调节点滴的速度。由电动机带动储液瓶使储液瓶上升或下降改变滴斗到受液瓶的高度,从而调节点滴速度。此种调节方法简单,容易实现。 方案二:通过控制滴速夹的松紧来控制点滴的速度。不过滴速夹用于大范围的调节滴速,调节是不精确, 1.2 最终方案确定 综合考虑,最终方案确定为点滴速度和储液均用红外对管监测,键盘显示模块用44矩阵键盘和1602液晶显示,液滴速度控制用电机实现。 2 单元电路设计 2.1 点滴速度测量电路设计 采用红外对管发射接收测量点滴速度,其电路原理图如图2.1.1.所示。 图2.1点滴速度测量电路 由电路图可以看到,接收管与发射管正相对,无液滴滴下时,接收管收到信号,输出低电平;有液滴滴下时,下落的水滴对红外光有较强的漫反射、吸收及一定的发散作用,导致接收光强的较大改变,接收管不能收到较强的信号,产生一个较长的脉动,但是波形不是太好,需要经过一级施密特触发器整形,输出一个正向的脉冲信号送给单片机中断口,据此就可以正确的测出液滴的滴数,即点滴的速度(滴/分)。 2.2 储液检测电路 液检测电路图仍然是和点滴速度测量电路一样,只是所接单片机的接口不同。其电路图如2.2.2图所示。 2.2.1 储液检测电路 该电路图的原理和点滴雕塑度检测电路的原理是一样的。由于红外光在水中和空气中的吸收系数不同,从而通过空气和水后的光强也是不同的。 其报警信号也是由储液信号来决定的。当储液的液面的高度为2~3cm后,会由红外对管发射接收产生检测信号,即为报警信号。 2.3 键盘显示电路 键盘采用44矩阵键盘,按键有0~9,+,-,,=,ON 字符, 采用1602液晶显示屏 2.4 点滴速度控制电路设计 系统将点滴速度采集信号和储液信号进行处理后,在相应的单片机的I/O控制口输出对应的控制信号来驱动电动机的正反转,从而进行精确的控制。 点滴的控制其实是靠单片机检测滴速,得到一个反馈量,输出一定信号驱动电动机,控制电动机的正转或反转,进而带动储液瓶的上升或下降来调节滴斗的高度即控制点滴的速度。 电动机驱动电路就如图2.4.1示。 图2.2. 4路是用ULN20003来驱动电机, 图2.4.1 电动机驱动电路 点滴控制靠单片机检测滴速,得到一个反馈量,输出一定信号控制电机上升或下降调节滴斗的高度。 3 系统软件设计 系统的软件设计采用C语言,对单片机进行编程来实现各项功能。 主程序对模块进行初始化,接收从传感器传来的信号,并对此信号进行处理,输出调整信号控制电动机的转动,扫描键盘进行动态显示。用的是循环查询方式,来显示和控制点滴的速度。 3.1 监测点滴速度子程序 检测点滴速度子程序主要是用与系统信号的采集。经过光电传感器采集,后由施密特触发器整形,输出到单片机的端口送入单片机内部。 3.2 储液监测子程序 本程序主要是用于测量储液瓶内部的液位高度的,当液位低于2~3cm时,发出报警信号。如果液位的高度不在此区间内,则点滴的速度照常采集,并送入单片机内部。其储液子程序流程图如图3.2.1所示。 开 始 光电传感信号变化否? 发出报警信号,储液面进入2~3cm的警戒水位 进入检测点滴速度子程序 Y N 发出报警信号,储液面进入2~3cm的警戒水位 图3.2.1储液子程序流程图 3.3 点滴速度控制子程序 开 始 当前值与设定值比较 小于 大于 等于 电动机正转,储出液瓶下降 电动机维持,滴速稳定 电动机反转,储液瓶上升 先设定一个速度值,随着点滴数落下,检测到信号后。滴数值加一,同时定时器工作计时,每有液滴被检测到时,程序计算出当前液滴落下速,与之前设定的值比较,来控制电机是正转、反转还是停止。 3.4 键盘显示子程序 键盘及显示字程序主要是用于判断速度有没有调整的动向和点滴速度的显示(包括当前值和设定值)。其程序流程图如3.4.1所示。 开 始 初始化 继续扫描显示 判断有没有键盘的按下 延时子程序 显 示 数据转化成BCD码,查表送入显示缓冲区 Y N 图3.4.1系统键盘显示子程序 3.5 系统的主程序 开 始 初 始 化 判断液位的高度,有没有产生中断 有没有调整键按下 调用按键处理程序 数据的BCD码转换 显 示 继续执行,等待 4 系统测试 4.1 系统测试数据 表4.2.1液滴速度检测测试速据 单片机检测速度(滴/分) 实际速度 30 30 52 53 23 23 34 35 85 85 73 74 133 133 144 145 表4.2.2流速调整测试 原始值 (滴/分) 预置值 (滴/分) 调整后低速 (滴/分) 稳定时间 秒 23 80 83 34 93 120 119 78 103 80 77 43 4.2 报警功能测试: 将夹头放松,使瓶中的水快速流出至警戒线附近,稍稍夹紧夹头,可以看到当水位降至警戒水位时,从机蜂鸣器发出报警信号。此功能正常。 4.3 测试结果分析 从以上测试结果可以看出,本系统已基本完成题目中的各项要求并在此基础上有所发挥,其中点滴速度的测量比较精确,在全量程内其误差小于3(滴/分)。设置点滴速度功能中,控制精度在全量程范围内优于4(滴/分),但是还是有一定的误差,经分析主要是由以下原因造成的: 1 由于瓶中的水不断减少,造成水滴的下落速度不均匀。 2 中断处理的进入和中断处理程序都会有一定时间的延时,这也是造成测量误差的一个因素。 3 在动态控制时,由于瓶处于运动状态,其上升、下降运动不可避免的会产生加速度,导致水滴下落时速度不稳定。 5 结论 本系统完成了在滴斗处检测点滴速度,并制作了一个数码管显示装置,能动态显示点滴速度(滴/分)。通过改变高度控制点滴速度,点滴速度可用键盘设定并显示,设定范围为20~150(滴/分),误差在要求范围内。当高度降到警戒值是能发出报警信号。每个从站都可以和主站通信。主站可以工作在定点和巡回检测两种方式下,可以显示从站传输来的从站号和点滴速度。 参考文献: [1]郭天祥.51单片机C语言教程[M].北京:电子工业出版社,2009 [2]谭浩强.C程序设计.北京:清华大学出版社,1991 [3]单片机应用开发实用子程序. 边春元等 编著. 人民邮电出版社. 2005 附录: 元器件明细表: 序号 元器件 数量 备注 1 STC89C51 2个 2 液晶显示1602 1个 3 红外对管 2对 4 44矩阵键盘 1个 5 28BYJ-48电机 1个 6 LM324 1个 7 ILN2003 1个 8 电阻 若干 9 晶振 1个 12MHz 10 排阻 1个 103 程序清单: #include <STC89C51.H> #define DB0_DB7 P0 #define busy 0x80 #define SCANPORT P1 sbit E=P2^5; sbit RW=P2^6; sbit RS=P2^7; unsigned char uca_LineScan[4]={0xEF,0xDF,0xBF,0x7F};//列线扫描电压,分为第1,2,3,4 根列线 unsigned char key_ctt[4]={0}; unsigned int time_sq[4]={0}; // 连续测得的三点的时间 unsigned char speed_bcd[4]={0}; // unsigned int speed_ck[4]={0}; // unsigned int di_xx[2]={0}; unsigned char speed_sc[2]={0}; unsigned char yy=0,temp; unsigned int ct=0,ttb=0,xx=0,tt3=0,speedct=0,speed=0,speedcd=10,cott=0; typedef unsigned char uchar; uchar code lcd3[]={"0123456789abcdef"}; uchar code lcdnow[]={"NOW:000"}; uchar code lcdset[]={"SET:000"}; unsigned char CONTROL[8]={0x38,0x18,0x98,0x88,0xC8,0x48,0x68,0x28}; unsigned char codes1[8]={0xb8,0x98,0xd8,0xc8,0xe8,0x68,0x78,0x38};///9,18,36,45,54,63,72,81度顺时针// unsigned char codes2[8]={0x38,0x78,0x68,0xe8,0xc8,0xd8,0x98,0xb8}; //9,18,36,45,54,63,72,81度逆时针 unsigned char counts,pt; bit flag=1; // 度数,正反转,速度控制 bit a_ac=0;//比较系统标志 unsigned char uc_KeyTemp=0;//按键键码暂存。 unsigned char uc_ClickCount=0; unsigned char ucCount; void vKeyProcess(unsigned char ucKeyCode); void bleep();//报警 bit bleept=0;//报警标准 bit moto=0;//电机标志位 void ac();//电机速度比较 void akey();//功能处理A bit a_key=0; bit b_key=0; void getspeed();//速度检测 void stdisplay();//显示 void Delay(unsigned int t);//延时 void delay_50ms(unsigned int t); void SendCommand(unsigned char ch);//发送命令 void vWriteData(unsigned char ch);//发送数据 void InitLcd();//初始化 void DisplayOneChar(unsigned char x,unsigned y,unsigned char ddata);//按指定位置显示一个字符 void DisplayListChar(unsigned char x, unsigned char y, unsigned char *DData);//按指定位置显示一串字符 //============================================== void Delay(unsigned int t) // delay 40us { //for(;t!=0;t--) ; while(t--); } void delay_50ms(unsigned int t) {unsigned int j; /**** 可以在此加少许延时补偿,以祢补大数值传递时(如 delay_50ms(1000) )造成的误差, 但付出的代价是造成传递小数值( delay_50ms(1) )造成更大的误差。 因为实际应用更多时候是传递小数值,所以补建议加补偿! ****/ for(;t>0;t--) for(j=6245;j>0;j--); } void SendCommand(unsigned char ch)//发送命令 { /*CheckBusy();*/ RS=0; RW=0; DB0_DB7=ch; E=1; Delay(1000); E=0; Delay(1000); //delay 40us } //================================================== void vWriteData(unsigned char ch)//发送数据 { /* CheckBusy(); */ RS=1; RW=0; DB0_DB7=ch; E=1; Delay(1000); E=0; Delay(1000); //delay 40us } //============================================= void InitLcd()// { SendCommand(0x38); Delay(1000); SendCommand(0x08); // Delay(10); SendCommand(0x01); //显示状态设置 Delay(1000); SendCommand(0x06); //清屏 Delay(2000); SendCommand(0x0c); //输入方式设置 } //============================================= void DisplayOneChar(unsigned char x,unsigned y,unsigned char ddata)//按指定位置显示一个字符 { y &= 0x1; x &= 0xF; //限制X不能大于15,Y不能大于1 if (y) x |= 0x40; //当要显示第二行时地址码+0x40; x |= 0x80; //算出指令码 SendCommand(x); vWriteData(ddata); } //============================================= void DisplayListChar(unsigned char x, unsigned char y, unsigned char *DData)//按指定开始位置显示字符串 { unsigned char ListLength; ListLength = 0; y &= 0x1; x &= 0xF; //限制X不能大于15,Y不能大于1 while (DData[ListLength]>0x20) //若到达字串尾则退出 { if (x <= 0xF) //X坐标应小于0xF { DisplayOneChar(x, y, DData[ListLength]); //显示单个字符 ListLength++; x++; } } } void vShowOneChar(unsigned char ucChar) { switch(ucChar) { case '0': vWriteData(0x30);break; case '1': vWriteData(0x31);break; case '2': vWriteData(0x32);break; case '3': vWriteData(0x33);break; case '4': vWriteData(0x34);break; case '5': vWriteData(0x35);break; case '6': vWriteData(0x36);break; case '7': vWriteData(0x37);break; case '8': vWriteData(0x38);break; case '9': vWriteData(0x39);break; case 'a': vWriteData(0x61);break; case 'b': vWriteData(0x62);break; case 'c': vWriteData(0x63);break; case 'd': vWriteData(0x64);break; case 'e': vWriteData(0x65);break; case 'f': vWriteData(0x66);break; default: break; } } //=========================================================== unsigned char ucKeyScan() { unsigned char ucTemp=0; //扫描状态暂存。 unsigned char ucRow=0,ucLine=0; //行号,列号。 for(ucLine=0;ucLine<4;ucLine++) //列扫描 { SCANPORT=uca_LineScan[ucLine]; //输出扫描电位。 ucTemp=SCANPORT&0x0F; //输入扫描电位,并屏蔽高4位。 if(ucTemp!=0x0F) { //判断该列是否有按键按下。 switch(ucTemp) { case 0x0E: ucRow=10;break; //如果有,则判断行号。 case 0x0D: ucRow=20;break; case 0x0B: ucRow=30;break; case 0x07: ucRow=40;break; default: ucRow=50;break; } break; } } //恢复键扫描处理前初始状态 SCANPORT=0x0F; //恢复P1口 return ucRow+ucLine+1; //返回按键编码。格式为2位数,高位为行号,低位为列号 } void vKeyProcess(unsigned char ucKeyCode) { SendCommand(0xC4+uc_ClickCount); if(a_key==1) { switch(ucKeyCode) { case 41:vShowOneChar('7');temp=7;break; //'7' case 42:vShowOneChar('8');temp=8;break; //'8' case 43:vShowOneChar('9');temp=9;break; //'9' case 31:vShowOneChar('4');temp=4;break; //'4' case 32:vShowOneChar('5');temp=5;break; //'5' case 33:vShowOneChar('6');temp=6;break; //'6' case 21:vShowOneChar('1');temp=1;break; //'1' case 22:vShowOneChar('2');temp=2;break; //'2' case 23:vShowOneChar('3');temp=3;break; //'3' case 12:vShowOneChar('0');temp=0;break; //'0' } SendCommand(0xc4+uc_ClickCount); SendCommand(0x0f); } switch(ucKeyCode) { case 44:/*vShowOneChar('c');*/temp=12;break; //'/' case 34:/*vShowOneChar('d')*/temp=13;break; //'*' case 24:/*vShowOneChar('e')*/temp=14;break; //'-' case 14:/*vShowOneChar('f')*/temp=15;break; //'+' case 13:/*vShowOneChar('b');*/temp=11;break; //'=' case 11:/*vShowOneChar('a');*/temp=10;break; //'ON/C' default:break; } if(temp==11) //判断按键与上一次所按的键是否相同 { delay_50ms(100); if(uc_ClickCount<255) //同一个按连续按下的次数:1~255 { uc_ClickCount++; SendCommand(0xc3+uc_ClickCount); SendCommand(0x0f);} if(uc_ClickCount==3) uc_ClickCount=0; SendCommand(0xc4+uc_ClickCount); SendCommand(0x0f); } if(temp<=9) {switch(uc_ClickCount) { case 0:key_ctt[0]=temp;break; case 1:key_ctt[1]=temp;break; case 2:key_ctt[2]=temp;break; default:break; } } } void int_timer0(void) { TMOD=0X10; TMOD=0X01; TH0=0X3C; TL0=0XB0; TH1=0X3C; TL1=0XB0; ET1=1; TR1=1; ET0=1; TR0=1; EA=1; IT1=1; EX1=1; } void Timer1() interrupt 3 { TH1=0X3c; TL1=0Xb0; pt++; //控制速度 if(pt==2) { pt=0; if(flag==0&&moto==1) P2=(P2&0x0f)|CONTROL[counts]; if(flag==0&&moto==0) P2=(P2&0x0f)|codes2[counts]; counts++; if(counts==8)counts=0; //角度重置 } } void Timer0() interrupt 1 { TH0=0X3c; TL0=0Xb0; yy++; if(yy==2) { ct++; tt3++; yy=0; if(ct==600)//60秒定时 { ct=0; xx=0; } if(tt3==20) { tt3=0; di_xx[1]=di_xx[0]; di_xx[0]=xx; if((di_xx[0]==di_xx[1])&&a_ac==1) {bleept=1;flag=1;} } } } void Int1() interrupt 2 { static cott=0; cott++; if(cott==2) { xx++; time_sq[2]=time_sq[1]; //把当前检测到液滴的时间保存起来 time_sq[1]=time_sq[0]; time_sq[0]=ct; if(a_key==0) { DisplayOneChar(10,0,lcd3[speed/100]); DisplayOneChar(11,0,lcd3[speed%100/10]); DisplayOneChar(12,0,lcd3[speed%10]); DisplayOneChar(10,1,lcd3[xx/100]); DisplayOneChar(11,1,lcd3[xx%100/10]); DisplayOneChar(12,1,lcd3[xx%10]); SendCommand(0xC4+uc_ClickCount);} getspeed(); cott=0; } } void stdisplay() { DisplayListChar(0,0,lcdnow); DisplayListChar(0,1,lcdset); DisplayOneChar(14,0,0x4f); DisplayOneChar(15,0,0x46); DisplayListChar(8,0,"S:"); DisplayListChar(8,1,"T:"); } void main(void) { delay_50ms(1); int_timer0(); InitLcd(); P2_3=1; SCANPORT=0x0F; stdisplay(); while(1) { bleep(); if(SCANPORT!=0x0F) { for(ucCount=0;ucCount<200;ucCount++); if(SCANPOR
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 通信科技 > 监控/监视

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服