储油罐实时监测系统的与实现.docx
《储油罐实时监测系统的与实现.docx》由会员分享,可在线阅读,更多相关《储油罐实时监测系统的与实现.docx(48页珍藏版)》请在冰豆网上搜索。
储油罐实时监测系统的与实现
长治学院
2012届学士学位毕业论文
储油罐实时监测系统的设计与实现
学号:
08405433
姓名:
张国雁
指导教师:
张毅
专业:
电子信息科学与技术
系别:
电子信息与物理系
完成时间:
2012年5月
储油罐实时监测系统的设计与实现
专业:
电子信息科学与技术姓名:
张国雁学号:
08405433
指导教师:
张毅
摘要:
我国石油资源丰富,采油炼油企业众多,储油罐是储存油品的重要设备,储油罐液位的精确计量对生产厂库存管理及经济运行影响很大。
但国内许多反应罐、大型储油罐、加油站的液位计量仍采用人工检尺和分析化验的方法,其他参数的测定也没有实行实时动态测量,这样易引发安全事故,无法为生产操作和管理决策提供准确的依据。
本系统针对上述问题,采用相应的传感器采集储油罐内的温度和压力,并通过单片机将储油量、温度值显示出来;同时利用串口将各项数据发送给上位机,从而进行更精确的计算与统计。
关键词:
储油罐、液位监测、QT、ARM、嵌入式
目录
1系统概述1
1.1题目分析1
1.1.1选题意义1
1.1.2需求分析1
1.2功能分析2
2方案论证3
2.1硬件方案3
2.1.1、硬件方案13
2.1.2、硬件方案23
2.1.3、两种硬件方案论证3
2.2软件方案3
2.2.1、软件开发工具论证4
2.2.2、方案比较4
3系统设计之下位机部分6
3.1.液面测量模块:
6
3.2.温度检测模块12
3.3串口数据发送模块14
3.4显示模块16
4系统设计之上位机部分18
4.1PC端软件18
4.2ARM嵌入式设备端软件21
5系统调试23
5.1调试计划23
5.2程序运行中的错误23
5.3调试结果23
6总结分析28
附录31
1系统概述
1.1题目分析
1.1.1选题意义
随着科技的发展,特别是计算机技术的广泛应用和迅猛发展,由传统的人工测量开始逐步向计算机智能监测方向发展。
相比较而言,国外的油罐区安全监测系统性能好,但其价格过高,远远超出了我国广大用户的承受能力。
而国内研制的系统大多计算精度低、稳定性和可靠性差。
因此,研发出符合我国国情的油罐区安全监测系统,不仅可以保障石油库区的安全生产,而且将加快石油行业的现代化管理进程。
针对油库储油罐地理位置分布广,信号传送距离远的特点,采用“功能分散、负荷分散、危险分散、管理集中”的分布式控制系统设计思想,“硬件模块化、软件组合化、通信网络化”的设计方法。
1.1.2需求分析
在设计储油罐管理系统时,首先确定系统设计目标和功能要求,从技术和经济角度上进行可行性分析,然后进行方案选择和总体设计,考虑下位机硬件电路的结构是否合理,性价比等问题,探讨上位机的功能框架,采用的数据结构等细节,再进行详细设计和调试,最终完成设计任务。
在设计初期,主要考虑了以下因素:
(1)可靠性。
系统运行安全可靠,性能稳定,可以在恶劣环境长期连续工作。
(2)通用性。
在设计时,应充分考虑其应用对象的共性,使系统具有较强的通用性,可以在油库推广应用。
(3)兼容性。
系统应能携挂不同类型的传感器,能够测量多种参数。
(4)经济性。
系统的造价经济合理,性能价格比高。
(5)操作维护方便性。
在软件方面,要求人机界面友好,操作简便;在硬件方面,要求维护检修方便。
1.2功能分析
根据对储油罐液位监测及计量管理任务的深入分析,系统应实现以下几大功能:
1.系统参数的设定与修改
储油罐区参数设定和修改:
储油罐数量、标号设定、通讯参数设置,储油罐分区管理定义等。
储油罐参数设定与修改:
储油罐的安全高度、液位的高低报警值等设定和修改。
2.储油罐实时监测与计量
储油罐状态实时监测:
储油罐液位等参数的实时监测。
储油罐实时计量:
依据压力值,计算出液位的高度和剩余百分比。
3.可视信息服务
显示系统总貌及构成、各个油罐的温度,液位,压力数据。
2方案论证
2.1硬件方案
2.1.1硬件方案1
硬件方案1的系统主要由现场仪表和储油罐实时监测与计量的管理主机或服务器等组。
系统主机和现场仪表之间通过RS-485总线连接,储油罐实时监测和采集液位的核心是两个压力传感器。
整个系统的工作流程大致如下:
压力传感器从储油罐终端采集到数据,经单片机处理(A/D转换)后显示到现场端的数码管上,同时通过串口传输给上位机,实现远端监测,连入计算机,计算机显示并保存上传的液位数据,并可以通过管理软件对数据来进行后续处理。
2.1.2硬件方案2
硬件方案2是光用单片机设计一个液位监控系统。
其硬件的组成是:
单片机,A/D转换部分,液位显示部分,将采集到的数据经过单片机处理,显示到数码管上,管理人员可以定时查看各个储油罐的信息。
2.1.3两种硬件方案论证
结合两种硬件方案,采用的硬件结构有所不同,方案2用单片机作为硬件系统,显然电路复杂,可靠性较低,而且无法向上位机发送数据,实现远端监测。
再者系统调试比较困难,无形中延长了开发周期,而且系统的稳定性不高。
本设计最终选择方案1,因为它相对于方案2来说,系统结构较为简单,结构高度模块化,低功耗电路设计,全数字总线接口,通信协议开放,网络扩展能力强,抗干扰能力强,所利用的液位测量技术成熟,可靠性高。
2.2软件方案
使用储油罐计量监测管理系统,能够实时采集和处理储油罐中所储油品的各项数据,通过软件显示并打印油品的储量、温度及相关的各项数据,使管理人员了解各个油罐的情况。
通过对储油罐实时监测与计量管理设计目标的论证,确定上位机主要实现以下功能:
(1)系统参数的修改
(2)储油罐实时监测与计量
2.2.1软件开发工具论证
i.下位机端:
方案一:
使用汇编语言为单片机编写程序。
特点是执行效率高。
方案二:
使用keil软件,用C语言为单片机编写程序。
特点是易读性强,可维护性高,开发简单,代码量低。
ii.上位机端:
方案一:
使用Delphi作为开发工具,Delphi是著名的Borland公司开发的可视化软件开发工具。
Delphi的优点是:
不能隐式定义、结构严格、方便快捷、运行速度快、使用方便、可读性高等。
缺点是结构过于严谨,对编程水平要求颇高。
方案二:
使用Qt设计计量管理系统。
优点是Qt提供了强大的可视化编程能力。
编程语言是C++,是面向对象的语言,功能强大。
Qt的良好封装机制使得Qt的模块化程度非常高,可重用性较好,对于用户开发来说是非常方便的。
Qt提供了一种称为signals/slots的安全类型来替代callback,这使得各个元件之间的协同工作变得十分简单。
2.2.2方案比较
i.下位机端:
显然,用C语言开发下位机程序有可读性强、易于编程、代码量低的优点,而且可以降低开发难度与开发周期。
ii.上位机端:
Qt是面向对象语言,易于扩展,允许组件编程,对日后软件的维护,功能的扩充提供了极大的方便,而且是一款完全开源免费的软件。
所以我们选用Qt作为本系统的上位机开发软件。
3系统设计之下位机部分
3.1液面测量模块
液面测量模块功能是测量液位的高度,并计算出液位高度比。
大致的实现方法是由两个压力传感器获取到两个压力模拟量,经A/D转换后以I2C数据形式发送到单片机中,单片机经过一定的算数运算后得到当前液位与满载液位的高度比。
其中涉及到的内容有I2C总线驱动,A/D转换,数学建模等内容。
具体实现方法在下文中分模块详细介绍。
(1)数学模型部分
利用压差法计算储油罐液面高度,可以消除密度对计算的影响。
如图3.1所示,其中P1,P2是底端和上端的压力值。
成品油是一种混合物,各种规格的成品油密度不一致。
甚至同厂生产的不同批次的成品油密度差别也很大,所以利用压差法不必事先去测定各种油的密度。
这样适应性就更广阔。
无论是常压容器还是受压容器,只要被测量的溶液为均匀液体即容器中液体处处密度相等,均可采差压法来测量液位。
压差法的计算的思路是:
压差比=液面高度比
图3.1储油罐数学模型
两个传感器之间的相对高度h0是事先设定且固定的,也就是说底端的压力值P1减去上端的压力值P2,就是这段液位的压差。
同理,底端压力值P1减去顶端的压力值,就是当前液位h(顶端与底端)的压差。
由液体压力计算公式P=ρgH可知,液体在某一位置的压力与深度H有关.液面最顶端的深度是0,故液面最顶端的压力值也是0。
由此可以推出当前液位的压力差也就是底端的压力值。
(1)
(2)
联立
(1),
(2)式,可以消除ρ,g.并可以得到当前液位h的计算公式:
(3)
压力不是基准量,而是力和面积的导出量,故测量压力的方法很多,在本系统中我们要测量液体的压力,所以选择液体式压力计。
液体式压力计又可以分为U型管压力计、单管压力计、倾斜微压计和自动液柱压力计等,不管采用哪种压力传感器,在测量压力时两个传感器必须要用相同规格的,这样测量的的数据在计算时才有意义。
无论是常压储油罐还是受压储油罐,底部是承压最大的区域,监测储油罐的压力值时,就应该以底部作为监测部位。
将底端压力值P1经过物理量化就可以得到这个值。
需要说的一点,P1和P2是两个模拟压力量,经8位的A/D转化器转换后得到的数字值。
8位A/D转换器的数值取值空间是0~255,也就是说它只能将一个模拟量分割成256份,这个量化数值对于高达几十米的大型储油罐无法做到精确的统计,这就需要提升A/D转换器的精确度,比如用16位的转换器,但原理都是一致的。
在本系统中就采用的是8位的转换器。
根据式(3)计算当前液位高度h时,用到的压力值都是比值关系,所以无须计算出确切的物理压力量来。
两传感器之间的距离h0我们设置1000mm,这个值的大小可以根据两个传感器的实际距离,在程序中手动更改。
这样就可以轻松的计算出当前液位高度h了。
再将当前液位高度除以储油罐满载时的高度hmax,就可以得到当前储油量与满载时的百分比。
我们就将两个压力值利用串口发送给上位机,让PC或32位的ARM嵌入式设备去计算,将结果输出到软件界面的相应位置。
但是在下位机端,单片机计算乘除运算比较吃力,而且精确度相当差。
所以上述的数学模型并不适应于下位机端。
在下位机端需要建立另一套数学模型,将底端压力乘某个常量,得到一个大概的液位高度值,显示到下位机的数码管上。
(2).A/D转换部分
本系统要对两个模拟压力量进行监测,如果使用传统的8位并行A/D转换器件,光数据口就会占据16个I/O口,对于一个只有4组8位I/O口的单片机来说,这种硬件上的开销实在比较大。
所以我在设计过程中选择了同样能实现两路模拟量检测,且对硬件资源开销极小的PCF8591。
PCF8591是一个单片集成、单独供电、低功耗、8-bitCMOS数据获取器件。
PCF8591具有4个模拟输入、1个模拟输出和1个串行I²C总线接口。
PCF8591的3个地址引脚A0,A1和A2可用于硬件地址编程,允许在同个I²C总线上接入8个PCF8591器件,而无需额外的硬件。
在PCF8591器件上输入输出的地址、控制和数据信号都是通过双线双向I²C总线以串行的方式进行传输。
PCF8591的功能包括多路模拟输入、内置跟踪保持、8-bit模数转换和8-bit数模转换。
PCF8591的最大转化速率由I²C总线的最大速率决定。
要用PCF8591监测两个压力模拟量,首先得确定PCF8591在I2C总线上的地址,其次要确定控制字节。
PCF8591采用典型的I2C总线接口寻址方法,即总线地址由器件地址、引脚地址和方向位共同组成。
飞利浦公司规定A/D器件地址为1001,引脚A2A1A0由用户硬件编程,在本系统中这三个引脚全部接地,也就是个说A2A1A0分别为000。
所以在I2C系统中最多可以接23=8个A/D器件。
总线地址的最后一位为方向位,当主控器件对A/D器件进行读操作时为1,进行写操作时为0。
总线操作时,由器件地址、引脚地址、方向位组成的从地址为主控器发送的一个字节。
这时总线上的I2C设备会根据自己的地址来判断主控器是否在“呼叫”自己。
若收到的地址和自己的地址和自己的地址相匹配,就要做好接收数据的准备了。
主控器发送的第二个字节是控制字节,控制字节用于控制器件实现各种功能,如模拟信号由哪几个通道输入等。
控制字节存放于控制寄存器中的格式如图3.2所示:
图3.2控制寄存器格式
其中:
D0D1两位是A/D通道编号:
00通道0,01通道1,10通道2,11通道3;在本系统中利用A/D通道0和A/D通道1。
D2是自动增益位,有效值是1。
当这一位置位时,A/D通道0转换完成后,芯片自动会去转换A/D通道1的值,依次循环类推。
D3是保留位。
D4D5是模拟量输入选择:
00四路单独输入,01三路差分输入,10为单端与差分配合输入,11为模拟输出允许有效。
我们在这里选择单独输入。
D6是A/DD/A选择位,A/D转换时选择0,D/A转换是选择1。
D7也是保留位.
由此可知,当单片机要监测某一个压力值时,它的工作流程如下:
(1)单片机向I2C上发出一个8位的设备地址,这时的D0位(读写位)为0,通知被控器件将要向其执行写操作,并等待应答;
(2)收到应答后,发送控制字节,写入被控器件的控制寄存器,等待应答;
(3)收到应答后,再发送一个8位的设备地址,这时的D0(读写位)为1,通知被控器件将要读取它发送的数据,等待应答;
(4)收到应答后,把总线的控制权交给被控器件,读取它发送到总线上的数据。
将这个过程结合到本系统中,PCF8591的器件地址为1001,引脚地址为000,写操作时方向位为0,即0x90,读操作时方向位为1,即0x91。
读取通道0时,控制字节为00000000,读取通道1时,控制字节为00000001。
操作的C程序代码:
ISendByte(0x90,0x00);//ISendByte是数据发送函数
p1=IRcvByte(0x91);//AD0模数转换0,将值赋给p1
这个函数的作用是发送器件地址0x90和控制字0x00(A/D通道0)读取A/D通道0的值,具体的实现过程参照附录中的源代码部分。
到此,我们就顺利的读取到了想要的压力值,但我们不免会有疑问:
数据究竟是如何在总线上传输的?
这个问题将在下一个小节:
I2C总线驱动部分中介绍到。
(3)I2C总线驱动部分
I2C总线设备是飞利浦公司推出的串行总线设备,它与传统的并行总线设备相比较,具有结构简单、可维护性好,易于实现扩展、易于模块化标准设计,可靠性高等优点。
但是STC89C516RD+单片机内部没有集成I2C总线设备模块,所以外围的I2C总线设备要实现与单片机的通信时,必须要用软件程序模拟出一个I2C总线设备的时序电路.这无疑增大了系统的开销,也增大了开发难度。
可是用I2C总线传输数据只需占用主控器件的两个引脚,就能传输8个外围器件的数据,相当节省硬件资源.所以综合利弊,本系统采用I2C总线设备来传输压力值数据.
它的工作原理如下:
I2C总线设备由一条数据总线SDA和一条时钟总线SCL与中控器件相连,I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,且高电平状态维持一定的时间(一般为5微秒)以后,数据线上的高电平或低电平状态才允许变化(如图3.3)。
如图3.3时钟与数据变化规律
SCL线为高电平期间,SDA线由高电平向低电平的变化(下降沿)表示起始信号,SCL线为高电平期间,SDA线由低电平向高电平的变化(上升沿)表示终止信号(如图3.4)。
如图3.4起始信号与终止信号
在传送数据时,要求每一个字节必须保证是8位长度。
数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)。
如果一段时间内没有收到从机的应答信号,则自动认为从机已正确接收到数据,如图3.5。
图3.5应答与非应答信号
所有I2C总线设备的驱动方法都是一致的,它只是提供传输数据的一种机制,也就是说驱动程序只提供用两条数据线实现通信的一种方法。
这种方法的实现步骤在互联网和相关书籍中有大量详细的介绍,在此不做更详细的说明,具体的实现方法也可以参考附录的程序代码部分。
在本系统中我们更为关心的是用I2C总线来传递什么数据,这些数据有什么意义,这就是一种操作I2C总线的策略,它与机制完全不相同,可由用户自己来设定,从而让I2C总线上的不同设备实现不同的功能。
在本系统中,这种策略体现在对A/D转换芯片PCF8591的操作上,详细内容在上文中介绍到了。
3.2温度检测模块
对储油罐温度的监测是靠温度传感器DS18B20来完成的,DS18B20数字温度计是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。
因此用它来组成一个测温系统,具有线路简单,在一根通信线上可以挂很多这样的数字温度计,十分方便。
DS18B20温度差传感器是一个数字传感器,这就省去了A/D转换的麻烦,在硬件电路上只有一根数据线,占用硬件资源很少,硬件上的节约同样需要软件来补偿,这就注定了操作DS18B20的繁琐性。
通常情况下我们采用的是TO-92封装的DS18B20,如图3.6。
图3.6DS18B20封装
由于DS18B20采用的是1-Wire总线协议方式,即在一根数据线实现数据的双向传输,而对51单片机来说,跟I2C总线设备一样,硬件上并不支持单总线协议,因此,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。
DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。
DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。
该协议定义了几种信号的时序:
初始化时序、读时序、写时序,如图3.7-3.9所示。
所有时序都是将主机作为主设备,单总线器件作为从设备。
而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。
数据和命令的传输都是低位在先。
图3.7DS18B20的复位时序
图3.8DS18B20的读时序
DS18B20的读时序分为读0时序和读1时序两个过程。
对于DS18B20的读时隙是从主机把单总线拉低之后,在15us之内就得释放单总线,以让DS18B20把数据传输到单总线上。
DS18B20在完成一个读时序过程,至少需要60us才能完成。
图3.9DS18B20的写时序
DS18B20的写时序仍然分为写0时序和写1时序两个过程。
对于DS18B20写0时序和写1时序的要求不同,当要写0时序时,单总线要被拉低至少60us,保证DS18B20能够在15us到45us之间能够正确地采样IO总线上的“0”电平,当要写1时序时,单总线被拉低之后,在15us之内就得释放单总线。
在本系统中,DS18B20的2引脚DQ与主控器STC90C516RD+的P2^3引脚相连,这条I/O线上只挂载了一个DS18B20,所以在操作时不必去理会DS18B20的ROM编码,在单器件的情况下,为了节省时间则可以选择跳跃ROM指令(#definejump_ROM0xCC),即向DS18B20写入指令:
0xCC。
如过多芯片挂载使用此指令将会出现数据冲突,出现错误。
对DS18B20的整体操作如下:
1.复位;
2.写跳跃ROM指令:
0xcc;
3.写温度转换指令:
0x44;
4.复位;
5.写跳跃ROM指令:
0xcc;
6.写数据读取指令:
0xbe;
7.读取温度值的低八位;
8.读取温度值的高八位;
最后将读到的温度数据以十进制的表示方法返回给主调函数。
3.3串口数据发送模块
串口数据发送模块的主要功能是将温度,压力等数据用串口发送给上位机,实现对储油罐的远端检测功能。
在本系统中采用的串口数据通信芯片是MAX485。
PC机一般接收的RS232电平,不识别RS485的电平信号,所以在接收端需要将RS485电平转换为RS232电平。
利用MAX485的主要原因是它的有效传输距离能达到1500m,而普通RS-232电平信号的有效距离最多也超不过20m。
在一个大型的炼油厂,储油罐与上位机的距离不可能在20m之内,RS232电平无法满足长距离传输数据的功能。
操作单片机发送串口数据时,要利用定时器来设置波特率。
主要的操作步骤:
选择好工作方式,设置好串口的相应的寄存器,设置好定时器的寄存器,将要发送的数据放入串口缓存区。
串口发送的数据顺序是:
0x00,0xff,油罐编号,温度,底端压力,上端压力;
其中0x00,和0xff是数据校验标志,当上位机收到一个数组后,先判断第一位是0x00,且第二位是0xff后,就知道从第三位开始就是编号,温度,压力这些有效数据了,因为事先知道数据长度,就不用结束标志位了。
向上位机发送的数据是源源不断的发送上去,每秒钟能发好几次,上位机再选择性的接收数据并做出相应的处理。
在windows下使用串口调试工具,收到的数据如图3.10所示。
图3.10串口调试工具
用串口调试工具查看串口数据时,这些数据是以十六进制显示的,而且是一连串的数据,不知道它们代表的是什么意思。
用一定的方法将这些数据解析完毕后,我们就可以很清楚的理解他们的意思了,在linux平台的终端中,显示解析后的数据如图3.11:
图3.11linux平台的终端数据
3.4显示模块
显示模块的功能是:
将各传感器检测到的值经其他相应功能模块处理之后,以数值的形式显示在数码管上。
相对而言,显示模块在本系统中是一个比较简单的模块,硬件上由一个八位的八段数码管、一个3-8译码器(74H138)和一个锁存器(74H373)构成,如图3.12所示。
图3.12显示电路
锁存器的输入端接单片机的P0口,将P0输出的电平保存起来,防止其跳变。
输出端接数码显示管的段选信号。
3-8译码器输入端接单片机P2.1P2.1P2.2三端,8个输出端分别接8位数码管上的位选信号。
位选的电平逻辑可参考3-8译码器的真值表,在此不再赘述。
特别强调的是,在操作单片机给P2.1P2.1P2.2三端赋值时,应只给这三个端口赋值,尽量不要采用“P2=XXX”的形式。
这样虽然可以改变这三个端口的值,达到操作3-8译码器的效果,但同时也改变了P2口其他五个端口的值,这就意味着对显示模块的操作可能会导致其他与P2口相连模块的功能产生错误。
可以这样赋值:
P2^0=X;
P2^1=X;
P2^2=X;
但这种赋值方式在这三个端口值不断变化的情况下,较为繁琐,所以利用C语言按位与,按位或,左右位移等方法较为简便,例如:
P2&=0xf8;/*给P2口赋位选值前,先将p2与(11111000)逻辑与,将P2^0,P2^1,P2^2清零,从而不影响其他位原来的电平*/
P2|=weitable[w];/*将位选信号放进P2口的低三位,只改
变P2口低三位的值,不影响其他位*/
显示模块的程序代码中对外提供一个接口:
display(d,w)函数。
其中d是段选参数,作用是显示什么数字;w是位选信号,作用是在那一位上显示。
调用起来相当方便。
显示的方法是动态扫描显示,即每次只能在数码管的某一位上