发表于:2008/8/1 11:27:00
#0楼
基于RS232/485协议的多机通信系统的方案及实现
在工业领域,主从式的设备监控管理模式应用越来越来广泛。一台上位机同时监控多台下位机(1:N),相比一台上位机监控一台下位机(1:1)的模式,更具有经济性、方便性和时效性。在一对多的通信模式中,由于下位机与上位机、下位机与下位机之间的物理位置相距较远,运行环境复杂、干扰大,使用RS232串口通讯协议完全不能达到要求,易出现错码。而通讯距离远(最长1200m),抗干扰能力强的RS485串口协议倍受到青睐。
RS232只能实现一对一的通信。RS485总线可挂接32台设备,实现一对多的通信。因为上位机具有较强的数据分析处理能力,良好的人机界面及大容量历史数据存储空间,用户通常希望使用PC机来充当上位机,来监控下位机的运行状况。而一般的PC机上只有RS232C串口,要使用RS485来进行实现1:N通信,必须将RS232通信协议与RS485通信协议进行双向转换。此时,通常可选用一个转换器(RS232/RS485),如:LD2101无源转换器。借助它,上位机软件无需重新设计,就可实现无缝衔接。
下位机通常采用单片机来实现,也可用可编程序控制器(PLC)。MCS51系列单片机具有价格低,功能强,抗干扰能力好,温限宽和面向控制等特点。Visual Basic 6.0以其强大的功能、使用简单、能在短时间内开发出高效的通信程序而成为Windows系统开发的主要编程语言。首先表现在VB可直接使用用户自定义控件VBX或OCX文件;其次表现在VB可通过调用动态链接库(DLL,Dynamic Link Library)或Win32 API函数来加快应用程序关键部件的执行速度;再次VB支持面向对象编程,支持链表存储数据对象,在编程过程中,程序更具结构化,模块化。
0 系统设计
图1 系统结构图
如图1所示,其为典型的一对多的主从通信控制模式,PC机充当主机,多台下位机充当从机。由于RS232串口逻辑电平为-15V~-3V(逻辑1)和+3V~+15V(逻辑0),传送距离最大为15m,而RS485采用RS422A的通信电平,为±2V~±6V,当速率为9600BPS时,传送距离可达1500m【2】。因此,这两种总线必须通过一个电平转换装置来进行互联。同时,由于下位机使用单片机如AT89S52芯片,只有串行接收(RXD)、发送(TXD)引脚,只支持TTL电平,与RS485总线电平不匹配,因此不能直接与RS485总线相连,在电路设计中需增加一MAX487转换芯片来驱动。与RS422不同,RS485总线只能处于半双工模式,“收”和“发”不能同时进行,系统的工作模式只能是一种“应答”工作模式。系统结构如图1所示。
1 系统通信软件设计
整个多机通信系统设计的关键在于系统通信模块的实现。一对多的通信模式有别于单一的一对一通信,它采用主从工作模式。由于通信总线上并挂着多台下位机,每一台下位机都是平等的。上位机为了能识别下位机,需要对每一台下位机进行编址,即一个类似于以太网卡MAC地址的十六进制编号。这个地址编号在该RS485总线上是独一无二的。当上位机需要监控目标下位机时,首先发出具有编号的地址帧于RS485总线上,此时总线上的每一台下位机都将接收到这个地址帧,并进行判断。若目标地址与自身相符,说明该下位机被选中,要求接收发送监控数据,即收发数据帧信息,否则,退出并回到接收地址帧状态。数据的交换过程(包括建立连接和交换数据) 采用一问一答的方式,上位机询问了下位机,下位机才给予应答,收到应答后,数据交换才继续进行下去。这样的方式可以避免多个下位机间没有次序的数据通信,扰乱整个网络上数据的传输。
那么下位机如何才能判断上位机发来是地址帧还是数据帧?我们知道,串型数据以高低电平来区分0或者1,以一个字节(Byte)为最小单位进行发送,一个Byte为8个二进制位(Bit),另外附加三个位作为起始位、停止位和奇偶校验位。在选择不使用奇偶校验的情况下,串口一次最小传送10个BIT,如果需要奇偶校验,则是11个BIT,排列为:【起始位】 【数据位1到8】 【奇偶校验位】 【停止位】。起始位和停止位是必不可少的,可利用的只有奇偶校验位,即习惯中的最9位。令第9位为1,代表该数据为地址帧,令第9位为0代表数据帧。MCS51系列的单片机中的串行通信模式2、3都支持区分地址帧和数据帧,幸运的是PC机同样支持。
2.1 下位机通信程序设计
下位机采用AT89S52芯片,通信程序采用主从工作模式,机被动地接收上位机的指令。其程序流程如图2所示。该程序的关键点在于判断查询地址是否是已方。若是,一是发回确定数据,二是紧接进行相应的数据接收和发送;否则再次回到接收地址帧状态。
图2 下位机通信中断处理流程图
下位机通信中断程序如下:
RS232INT:
PUSH ACC
PUSH PSW
CLR RI
ACALL SCONDELAY
MOV A,SBUF ‘读串口数据
CJNE A,01H,OUTRS232 ‘判断地址编号是否与该机编号相符否
CLR SM2
MOV A,#055H ‘相符,则返回一个55H数据回,说明查到设备。
ACALL SENDDATA
ACALL RECIVEDATA
JB 2FH.6,OUTRS232
MOV 40H,A
ACALL RECIVEDATA ‘接收数据
JB 2FH.6,OUTRS232
MOV 41H,A
ACALL RECIVEDATA
JB 2FH.6,OUTRS232
MOV 2DH,A
MOV A,42H
ACALL SENDDATA
MOV A,43H
ACALL SENDDATA ‘发送数据
MOV A,44H
ACALL SENDDATA
MOV A,45H
ACALL SENDDATA
MOV A,2EH
ACALL SENDDATA
SETB SM2
OUTRS232:
SETB SM2
POP PSW
POP ACC
RETI
2.2上位机通信程序设计
上位机通信程序作为整个系统中的主机,肩负着系统数据采集、指令下达,同时提供信息系统管理功能的多重任务。其中通信模块是系统中的核心部件。通信模块的实现方法有多种,在VB6.0中,可用:1)MSCOMM控件,2)直接调用动态链接库(DLL,Dynamic Link Library),3)调用API函数的方式。
MSCOMM是微软提供的标准通信控件。利用该控件可对串行通信的数据发送和接收进行设置,还可对串口状态及串行通信的信息格式和协议进行设置。在通信过程中可以通过触发OnComm事件来追踪、处理通信和错误事件的发生。或通过查询的方式,在每个重要的程序功能之后检查CommEvent属性值来检测事件和通信错误。程序设计简单方便,快捷。但是MSCOMM控件中关于通信的很多参数的设置没有提供,致使特殊情况下,如多机通信,无法通信握手。调用动态链接库与调用MSCOMM控件相似。第三种方法通过调用Windows底层通信API函数,如WriteFile 和ReadFile函数,来发送和接收数据。程序中对串口通信的操作,与文件操作类似。同时,通信中,可利用DCB(Device Control Block)串口设备控制块,来配置串口参数和串行通信驱动程序,从而灵活地实现多机通信。
在VB6中的,专门设计了一个通信类,并定义它的属性和方法,如表1所示。在类的定义中,按照要求将系统API函数进行包装,对外提供统一的接口。
表1 通信类
Comm
-HCF: long
-typDCB: DCB
+commOpenPort(comPort:byte):Boolean
+commInit():Boolean
+clearBuffer():Boolean
+commSetPara(strSettings:String):Boolean
+ commSendData(data() :Byte):Boolean
+commReceiveData(Buffer():Byte):Boolean
+commClose()
调用时,可按如下步骤进行:
1)首先将类进行实类化,创建一个通信类(Comm)对象:dim AComm as New Comm
2)打开一串行端口,如打开COM1,runResult= AComm.commOpenPort(1)
3) 调用初始化方法,如:runResult=AComm. commInit()
4)设置参数,如runResult= AComm.commSetPara(” 9600,M,8,1”),这是设置通信波特率9600,标志位M (置串行通信数据格式中的第9位为1,表示地址帧),数据长度8位,停止位1位。若要发送数据帧时,参数设置方法调用时,实参应为”9600,S,8,1”,S表示空位,即第9位设置为0。
5) 发送或接收数据。在发送和接收之前,首先将要发送的数据存放在一个数组中或定义一个空的数组单元以用于存放接收到的数据。如:runResult=AComm.commSendData(data)
6)结束通信。AComm.commClose()
通过实验,在通信初始化方法commInit()中,串口设备控制块的参数设置如下参数值时可以成功进行多机通信连接,而采用系统默认的参数不行。
flag = GetCommState(HCF, typDCB)
'======================================
typDCB.BaudRate = 9600
typDCB.ByteSize = 8
typDCB.DCBlength = 28
typDCB.EofChar = 0
typDCB.ErrorChar = 0
typDCB.EvtChar = 0
typDCB.fBitFields = 4113
typDCB.Parity = 4
typDCB.StopBits = 0
typDCB.wReserved = 0
typDCB.XoffChar = 19
typDCB.wReserved1 = 0
typDCB.XoffLim = 512
typDCB.XonChar = 17
typDCB.XonLim = 2048
typDCB.XonLim = 2048
'==========================================
flag = SetCommState(HCF, typDCB) '设置DCB块
其中,typDCB为设备控制块,HCF为通信控制句柄,
2 实现实例
基于上述系统结构,我们实现了电镀槽数据采集与控信息管理系统软件,如图3所示。上位机系统采用VB6.0编写,程序大量使用了面向对象的编程思想,并利用数据链表来存放和遍历数据对象(clsDataofObject)和参数设置对象(clsSetValueofObject)。系统每隔10秒,上位机依次向下位机发送一条查询指令。下位机接收到指令,返回成功应答数据55H,表明主机与从机之间已经成功建立连接,交换数据开始。最终各个下位机传送来的电压电流数据及工作状态信息都显示在表格中。图中显示了两个下位机的工作状态。图中绿色,说明工作状态正常,如果显示红色,说明下位机有过流或过热现象。
图3 电镀槽数据采集与控信息管理系统软件主界面
3 结论
系统硬件采用AT89S52单片机和RS-485驱动芯片MAX487组网,通过转换器,将RS485总线与RS232串口对接。软件采用主从通信协议,下位机采用通信模式2,上位机利用第9位奇偶校验位区分成地址帧和数据帧。通过软件硬件的结合,成功实现了一对多通信。在给出的信息系统案例可以对下位机进行管理,包括删除、添加和修改下位机的参数信息。主机根据这些信息来与地址匹配的从机通信,完成对整个网络中所有设备的监控。
在工业领域,主从式的设备监控管理模式应用越来越来广泛。一台上位机同时监控多台下位机(1:N),相比一台上位机监控一台下位机(1:1)的模式,更具有经济性、方便性和时效性。在一对多的通信模式中,由于下位机与上位机、下位机与下位机之间的物理位置相距较远,运行环境复杂、干扰大,使用RS232串口通讯协议完全不能达到要求,易出现错码。而通讯距离远(最长1200m),抗干扰能力强的RS485串口协议倍受到青睐。
RS232只能实现一对一的通信。RS485总线可挂接32台设备,实现一对多的通信。因为上位机具有较强的数据分析处理能力,良好的人机界面及大容量历史数据存储空间,用户通常希望使用PC机来充当上位机,来监控下位机的运行状况。而一般的PC机上只有RS232C串口,要使用RS485来进行实现1:N通信,必须将RS232通信协议与RS485通信协议进行双向转换。此时,通常可选用一个转换器(RS232/RS485),如:LD2101无源转换器。借助它,上位机软件无需重新设计,就可实现无缝衔接。
下位机通常采用单片机来实现,也可用可编程序控制器(PLC)。MCS51系列单片机具有价格低,功能强,抗干扰能力好,温限宽和面向控制等特点。Visual Basic 6.0以其强大的功能、使用简单、能在短时间内开发出高效的通信程序而成为Windows系统开发的主要编程语言。首先表现在VB可直接使用用户自定义控件VBX或OCX文件;其次表现在VB可通过调用动态链接库(DLL,Dynamic Link Library)或Win32 API函数来加快应用程序关键部件的执行速度;再次VB支持面向对象编程,支持链表存储数据对象,在编程过程中,程序更具结构化,模块化。
0 系统设计
图1 系统结构图
如图1所示,其为典型的一对多的主从通信控制模式,PC机充当主机,多台下位机充当从机。由于RS232串口逻辑电平为-15V~-3V(逻辑1)和+3V~+15V(逻辑0),传送距离最大为15m,而RS485采用RS422A的通信电平,为±2V~±6V,当速率为9600BPS时,传送距离可达1500m【2】。因此,这两种总线必须通过一个电平转换装置来进行互联。同时,由于下位机使用单片机如AT89S52芯片,只有串行接收(RXD)、发送(TXD)引脚,只支持TTL电平,与RS485总线电平不匹配,因此不能直接与RS485总线相连,在电路设计中需增加一MAX487转换芯片来驱动。与RS422不同,RS485总线只能处于半双工模式,“收”和“发”不能同时进行,系统的工作模式只能是一种“应答”工作模式。系统结构如图1所示。
1 系统通信软件设计
整个多机通信系统设计的关键在于系统通信模块的实现。一对多的通信模式有别于单一的一对一通信,它采用主从工作模式。由于通信总线上并挂着多台下位机,每一台下位机都是平等的。上位机为了能识别下位机,需要对每一台下位机进行编址,即一个类似于以太网卡MAC地址的十六进制编号。这个地址编号在该RS485总线上是独一无二的。当上位机需要监控目标下位机时,首先发出具有编号的地址帧于RS485总线上,此时总线上的每一台下位机都将接收到这个地址帧,并进行判断。若目标地址与自身相符,说明该下位机被选中,要求接收发送监控数据,即收发数据帧信息,否则,退出并回到接收地址帧状态。数据的交换过程(包括建立连接和交换数据) 采用一问一答的方式,上位机询问了下位机,下位机才给予应答,收到应答后,数据交换才继续进行下去。这样的方式可以避免多个下位机间没有次序的数据通信,扰乱整个网络上数据的传输。
那么下位机如何才能判断上位机发来是地址帧还是数据帧?我们知道,串型数据以高低电平来区分0或者1,以一个字节(Byte)为最小单位进行发送,一个Byte为8个二进制位(Bit),另外附加三个位作为起始位、停止位和奇偶校验位。在选择不使用奇偶校验的情况下,串口一次最小传送10个BIT,如果需要奇偶校验,则是11个BIT,排列为:【起始位】 【数据位1到8】 【奇偶校验位】 【停止位】。起始位和停止位是必不可少的,可利用的只有奇偶校验位,即习惯中的最9位。令第9位为1,代表该数据为地址帧,令第9位为0代表数据帧。MCS51系列的单片机中的串行通信模式2、3都支持区分地址帧和数据帧,幸运的是PC机同样支持。
2.1 下位机通信程序设计
下位机采用AT89S52芯片,通信程序采用主从工作模式,机被动地接收上位机的指令。其程序流程如图2所示。该程序的关键点在于判断查询地址是否是已方。若是,一是发回确定数据,二是紧接进行相应的数据接收和发送;否则再次回到接收地址帧状态。
图2 下位机通信中断处理流程图
下位机通信中断程序如下:
RS232INT:
PUSH ACC
PUSH PSW
CLR RI
ACALL SCONDELAY
MOV A,SBUF ‘读串口数据
CJNE A,01H,OUTRS232 ‘判断地址编号是否与该机编号相符否
CLR SM2
MOV A,#055H ‘相符,则返回一个55H数据回,说明查到设备。
ACALL SENDDATA
ACALL RECIVEDATA
JB 2FH.6,OUTRS232
MOV 40H,A
ACALL RECIVEDATA ‘接收数据
JB 2FH.6,OUTRS232
MOV 41H,A
ACALL RECIVEDATA
JB 2FH.6,OUTRS232
MOV 2DH,A
MOV A,42H
ACALL SENDDATA
MOV A,43H
ACALL SENDDATA ‘发送数据
MOV A,44H
ACALL SENDDATA
MOV A,45H
ACALL SENDDATA
MOV A,2EH
ACALL SENDDATA
SETB SM2
OUTRS232:
SETB SM2
POP PSW
POP ACC
RETI
2.2上位机通信程序设计
上位机通信程序作为整个系统中的主机,肩负着系统数据采集、指令下达,同时提供信息系统管理功能的多重任务。其中通信模块是系统中的核心部件。通信模块的实现方法有多种,在VB6.0中,可用:1)MSCOMM控件,2)直接调用动态链接库(DLL,Dynamic Link Library),3)调用API函数的方式。
MSCOMM是微软提供的标准通信控件。利用该控件可对串行通信的数据发送和接收进行设置,还可对串口状态及串行通信的信息格式和协议进行设置。在通信过程中可以通过触发OnComm事件来追踪、处理通信和错误事件的发生。或通过查询的方式,在每个重要的程序功能之后检查CommEvent属性值来检测事件和通信错误。程序设计简单方便,快捷。但是MSCOMM控件中关于通信的很多参数的设置没有提供,致使特殊情况下,如多机通信,无法通信握手。调用动态链接库与调用MSCOMM控件相似。第三种方法通过调用Windows底层通信API函数,如WriteFile 和ReadFile函数,来发送和接收数据。程序中对串口通信的操作,与文件操作类似。同时,通信中,可利用DCB(Device Control Block)串口设备控制块,来配置串口参数和串行通信驱动程序,从而灵活地实现多机通信。
在VB6中的,专门设计了一个通信类,并定义它的属性和方法,如表1所示。在类的定义中,按照要求将系统API函数进行包装,对外提供统一的接口。
表1 通信类
Comm
-HCF: long
-typDCB: DCB
+commOpenPort(comPort:byte):Boolean
+commInit():Boolean
+clearBuffer():Boolean
+commSetPara(strSettings:String):Boolean
+ commSendData(data() :Byte):Boolean
+commReceiveData(Buffer():Byte):Boolean
+commClose()
调用时,可按如下步骤进行:
1)首先将类进行实类化,创建一个通信类(Comm)对象:dim AComm as New Comm
2)打开一串行端口,如打开COM1,runResult= AComm.commOpenPort(1)
3) 调用初始化方法,如:runResult=AComm. commInit()
4)设置参数,如runResult= AComm.commSetPara(” 9600,M,8,1”),这是设置通信波特率9600,标志位M (置串行通信数据格式中的第9位为1,表示地址帧),数据长度8位,停止位1位。若要发送数据帧时,参数设置方法调用时,实参应为”9600,S,8,1”,S表示空位,即第9位设置为0。
5) 发送或接收数据。在发送和接收之前,首先将要发送的数据存放在一个数组中或定义一个空的数组单元以用于存放接收到的数据。如:runResult=AComm.commSendData(data)
6)结束通信。AComm.commClose()
通过实验,在通信初始化方法commInit()中,串口设备控制块的参数设置如下参数值时可以成功进行多机通信连接,而采用系统默认的参数不行。
flag = GetCommState(HCF, typDCB)
'======================================
typDCB.BaudRate = 9600
typDCB.ByteSize = 8
typDCB.DCBlength = 28
typDCB.EofChar = 0
typDCB.ErrorChar = 0
typDCB.EvtChar = 0
typDCB.fBitFields = 4113
typDCB.Parity = 4
typDCB.StopBits = 0
typDCB.wReserved = 0
typDCB.XoffChar = 19
typDCB.wReserved1 = 0
typDCB.XoffLim = 512
typDCB.XonChar = 17
typDCB.XonLim = 2048
typDCB.XonLim = 2048
'==========================================
flag = SetCommState(HCF, typDCB) '设置DCB块
其中,typDCB为设备控制块,HCF为通信控制句柄,
2 实现实例
基于上述系统结构,我们实现了电镀槽数据采集与控信息管理系统软件,如图3所示。上位机系统采用VB6.0编写,程序大量使用了面向对象的编程思想,并利用数据链表来存放和遍历数据对象(clsDataofObject)和参数设置对象(clsSetValueofObject)。系统每隔10秒,上位机依次向下位机发送一条查询指令。下位机接收到指令,返回成功应答数据55H,表明主机与从机之间已经成功建立连接,交换数据开始。最终各个下位机传送来的电压电流数据及工作状态信息都显示在表格中。图中显示了两个下位机的工作状态。图中绿色,说明工作状态正常,如果显示红色,说明下位机有过流或过热现象。
图3 电镀槽数据采集与控信息管理系统软件主界面
3 结论
系统硬件采用AT89S52单片机和RS-485驱动芯片MAX487组网,通过转换器,将RS485总线与RS232串口对接。软件采用主从通信协议,下位机采用通信模式2,上位机利用第9位奇偶校验位区分成地址帧和数据帧。通过软件硬件的结合,成功实现了一对多通信。在给出的信息系统案例可以对下位机进行管理,包括删除、添加和修改下位机的参数信息。主机根据这些信息来与地址匹配的从机通信,完成对整个网络中所有设备的监控。