广东顺德顺龙中密度纤维板有限公司 冼业雄
摘要:利用Delphi开发工业上位机控制系统软件已成为越来越多工控开发人员的选择,而怎么便当快速实现串口数据的收罗成为问题的要害,本文着重讨论了Delphi6与Comport通信组件所实现的与多个AI仪表实时数据收罗,同时对收罗到的数据作相应的处理。
要害词:串口通信;Delphi6.0;Comport控件
1 引言
日前,随着现代信息技术的生长,盘算机串口通信技术已日趋成熟。由于微机处理速度快、剖析能力强、使用灵活等特点,而单独的二次仪表仅仅作为显示控制功效也不可满足生产的需要,更多是要收罗和纪录现场有用的数据,作为生产剖析和存档,利用PC作为仪表功效拓展的上位机监控系统已在工业控制领域中被广泛接纳。
PC机与仪表的串口通信可以接纳语言编程实现,如Delphi、VC、VB等。Delphi是新一代面向工具的可视编程工具,它具有功效强大、简单易用、执行速度快和有富厚的第三方控件支持,使得开发历程变得如搭积木般简单易用,特别是对我们一些搞工控没有特别深厚编程基础的人使用。下位机仪表接纳的是带485通信功效的3377体育AI系列仪表,因为3377体育的AI仪表所用的是AIBUS通讯协议,具有通信指令简单、通信速度快等特点,允许上位机指令读写仪表的数据,利用RS485总线功效可以实现多个仪表数据的串口通信。
2 Comport串口通信组件简介
用DelphiI实现串口通信,常用的要领有:使用控件,如Mscomm和Comport控件等;使用API函数对串口读写。使用API要领比较适合编写较为庞大的低条理通信程序,但缺点是编写串口通信程序较为庞大,需要掌握大宗的通信和编程知识。而用串口控件,我们可以不睬会它的内部性能,主要挪用它的相关的属性和事件,就可以对串口实现种种操作,且编程简单、通常性强、可移植性好。在Delphi串口通信中我们选择用Comport控件,它直接编译在开发的工程文件里,不需要在运行的PC上另外装置控件。将Comport组件装置到DELPHI后可以看到多了一个Cportlib的组件页,Cportlib下面有多个组件,我们在这里主要应用的是Comport组件,对Comport控件的操作主要有:端口设置、翻开端口、往端口写指令、读接收数据、关闭端口。
3 3377体育AIBUS通讯协议说明
AIBUS是3377体育为AI系列显示控制仪表开发的通讯协议,能用简单的指令实现强大的功效,AIBUS接纳了16位的求和校正码,通讯可靠,支持4800、9600、19200等多种波特率,仪表允许连续写参数,写给定值或输出值,AI系列仪表使用异步串行通讯接口,接口电平切合RS232C或RS485标准中的划定。数据花样为1个起始位,8位数据,无校验位,1个或2个停止位。AI仪表接纳多机通讯协议,接纳RS485通讯接口,则可将32台的仪表同时连接在一个通讯接口上。AI仪表接纳16进制数据花样来体现种种指令代码及数据。AI仪表软件通讯指令经过优化设计,标准的通讯指令只有两条,一条为读指令,一条为写指令,两条指令使得上位机软件编写容易,不过却能*完整地对仪表进行操作;标准读和写指令划分如下:
读: 地点代号+52H(82)+要读的参数代号+0+0+校验码
写: 地点代号+43H(67)+要写的参数代号+写入数低字节+写入数高字节+校验码
地点代号:为了在一个通讯接口上连接多台AI仪表,需要给每台AI仪表编一个互不相同的通讯地点。AI仪表通讯协议划定,地点代号为两个相同的字节,数值为(仪表地点+80H)。例如:仪表参数Addr=10(16进制数为0AH,0A+80H=8AH),则该仪表的地点代号为:8AH 8AH
校验码:校验码接纳16位求和校验方法,其中读指令的校验码盘算要领为:要读参数的代号×256+82+ADDR
好比要读地点1的参数0的数据,就是0*256+82+1=83;转成十六制就是53 00;
如果是读OC的数据,就是十进制(C)*256+82+1= (十六制的)C53,校验码为53 0C;
写指令的校验码盘算要领为以下公式做16位二进制加法盘算得出的余数(溢出部分不处理):要写的参数代号×256+67+要写的参数值+ADDR
返回数据:无论是读照旧写,仪表都返回以下10个字节数据,丈量值PV+给定值SV+输出值MV及报警状态+所读/写参数值+校验码;其中PV、SV及所读参数值均各占2个字节,代表一个16位二进制有符号补码整数,低位字节在前,高位字节在后,整数无法体现小数点,要求用户在上位机处理;MV占一个字节,按8位有符号二进制数花样,数值规模-110~+110,状态位占一个字节,校验码占2个字节,共10个字节。
4 Comport控件与多个AI仪表通信的实现
4.1 硬件的组态
硬件组态主要由带串口的上位机PC、485转232转换器和AI仪表组成的485总线系统,AI仪表设置差别的通信地点,波特率设为9600。如下图:
总线结构 |
![]() |
4.2 软件通信程序的实现
通过Comport控件与AI仪表实现通信是接纳问答的方法进行的,所行我们在与多个仪表同时通信时应该接纳轮询的通信方法。首先我们要在DELPHI里初始化串口,然后再用读写命令与每一个仪表轮询通信。通信结束后要关闭串口,释放串口资源。主要实现历程如下:
4.2.1 初始化串口并翻开串口
选择好本次与AI通信的串口,该串口不可同时被其它程序引用,确定通信协议,如波特率、数据位、停止位和校验方法等属性,翻开该串口。初始化可以在Comport的属性页里界说,也可以在程序运行时动态设置。属性页里的静态界说为:
BaudRate: br9600//界说波特率
DataBits:dbEight//8位数据位
Port: COM1//本例用串口1
StopBits:sbOneStopBit//1位停止位
…
其它属性可以参阅Comport的在线资助文件。如果要在程序动态运行中修改设置串口参数,可以直接在程序中挪用Comport的串口设置窗口函数:Comport. ShowSetupDialog。在弹出的设置窗口中设置串口属性。完成串口初始设置后就可心翻开串口与AI通信,翻开串口用如下命令:
Comport.open;//翻开串口
4.2.2 数据转换函数
凭据AI仪表的通信协议,上位机与AI通信时都是以十六进制的方法进行的,所以我们在程序里要做十六进制的花样转换,主要实现的函数如下:
function HexStrToStr(const S:string):string;
//16进制字符转换成字符串。 将要发送的十六进制花样字符转换成十六进制花样发送
var
t:Integer;
ts:string;
M,Code:Integer;
begin
t:=1;
Result:='';
while t<=Length(S) do
begin
while not (S[t] in ['0'..'9','A'..'F','a'..'f']) do
inc(t);
if (t+1>Length(S))or(not (S[t+1] in ['0'..'9','A'..'F','a'..'f'])) then
ts:='$'+S[t]
else
ts:='$'+S[t]+S[t+1];
Val(ts,M,Code);
if Code=0 then
Result:=Result+Chr(M);
inc(t,2);
end;
end;
function StrToHexStr(const S:string):string;
//字符串转换成16进制字符串,,将接收到的字符数转换成16进制数。
var
I:Integer;
begin
for I:=1 to Length(S) do
begin
if I=1 then
Result:=IntToHex(Ord(S[1]),2)
else Result:=Result+' '+IntToHex(Ord(S[I]),2);
end;
end;
function Hex2Dec(Hexs: string): string; //十六制转十制数
var
i,j: integer;
res,base: LongWord;
begin
res := 0;
for i:=1 to Length(Hexs) do
begin
base := 1;
for j:=1 to Length(Hexs)-i do
base := base * 16;
case Hexs[i] of
'0'..'9': res := res + (Ord(Hexs[i]) - Ord('0')) * base;
'a'..'f': res := res + (Ord(Hexs[i]) - Ord('a') + 10) * base;
'A'..'F': res := res + (Ord(Hexs[i]) - Ord('A') + 10) * base;
end;
end;
result := inttostr(res);
end;
4.2.3 送接收数据
上位机与多个AI通信,遵循一问一答的轮询方法进行,所读取到的数据是不含小数位的,所以我们要发送读取小数位的命令,同时也可以返回丈量值。我们假定与四个AI仪表通过485总线通信的主程序实现如下:
procedure RXdata;
var
i:integer;
dot,dot2,dot3,dot4 :double;
obj:PAsync;
str,str2,a1,a2,a7,b1,b2,b7,c1,c2,c7,d1,d2,d7:string;
begin
InitAsync(obj);
try ///////////读*通道地点1的小数位和丈量值
ComPort.WriteStrAsync(HexStrToStr('81 81 52 0C 0 0 53 0C'),obj);
ComPort.WaitForAsync(obj);
sleep(100);//发送命令后期待100MS,包管数据的完整性;
ComPort.ReadStr(Str, 20);//读取接收缓存区20个字节数;
comport.ClearBuffer(true,true);//清除发送区和接收区,准备下一个通道通信;
for I:=1 to Length(str) do//将接收到的数据作处理
begin
str2:=IntToHex(Ord(Str[i]),2) ;
if i= 1 then a1:= str2;//丈量值的低位字节
if i= 2 then a2 :=str2;//丈量值的高位字节
if i=7 then a7 := str2;//小数点的位数
end;
dot := Exp(ln(10)*(strtoint(hex2dec(a7))));
dot :=strtofloat(hex2dec(a2+a1))/dot;//崎岖位字节合并后转换成带小数点的十进制数;
//开始读第二通道地点二的数据,其它通道的要领以此一致。
ComPort.WriteStrAsync(HexStrToStr('82 82 52 0C 0 0 54 0C'),obj); //读地点0C的小数点;
ComPort.WaitForAsync(obj);
Sleep(100);
ComPort.ReadStr(Str, 20);
comport.ClearBuffer(true,true);
``````
//四通道全部读完,如果要读取更多地点的数据,也如此类推;
finally
DoneAsync(obj);
end;
end;
到此为止,对AI仪表的数据收罗基本完成,把上面的历程放在delphi的一个定器时控件TIMMER里就可以实现自动收罗了。如要在上位机操作AI仪表的其它参数,也可以参考AI仪表的通信协议对程序进行编写实现。
4.2.4 关闭串口
在系统开发中,应注意在不使用串口时实时关闭串口,释放系统资源,不然可能会影响系统的其它应用。关闭串口的代码如下:
Comport.close;
5 结论
实践证明,利用Comport控件在DELPHI中开发串口与下位机通信程序,具有灵活、便当、的特点。同时利用DELPHI中图表曲线和数据库的功效,可以收罗实时生产中的数据生成实时曲线和历史曲线,便当对生产历程的剖析存档。把相关的数据转存入数据库可以与企业的MIS系统整合,实现数据共享。
参考文献:
1.李庆亮.2006.SPCOMM控件在Delphi7.0串口通信中的应用.微盘算机信息-嵌入式SOC. 22(5-2):8-10。
2.林枫,王月忠.2005.智能化锂离子电池治理系统的设计与实现.微盘算机信息.(3):78-79。
3.范逸之,陈立元.2002.VB与RS-232串行通信控制.中国青年出书社,327-334。