用VB编程实现计算机通讯

时间:2022-06-20 05:53:46

用VB编程实现计算机通讯

【摘要】vb是一种具有很好的图形用户接口(Graphic user interface,简写为GUI)的程序设计语言, 同时又是一种完全支持结构化程序设计的面向对象的程序设计语言。其特点不仅语法口语化,浅显易懂,易于掌握,而且编程界面友好,操作简便,模块化结构化程度高。尤其其功能强大,编程面广。本文根据作者长期使用VB进行工业控制的编程经验,并结合热力发电厂化学水车间的运作过程,介绍如何用VB来编程实现计算机与下位机之间的通讯

【关键词】下位机、ADAM模块、模拟量、开关量。

中图分类号:G201

一、工作原理

热力发电厂为确保发电机组运转正常,化学水车间必须24小时对机组的化学水性质进行监视测量。需要测量的数据项很多,根据热电厂的规模和设备情况的不同而不同。比如有:凝结水电导值,凝结水溶氧值、疏水电导值,除氧水溶氧值、给水电导值、给水PH值,炉水PH值,饱和汽电导值,过热汽电导值等,这些值测出来的都是一些离散性的数值,统称模拟量。而象“凝结水超温阀”、“过热汽超温阀”、“冷却水压力低”等这种状态量数据测出来只有两种值:“正常”用“-1”表示, “不正常”用“0 ”表示,这些数据统称开关量。这些模拟量和开关量首先经过一种智能仪表转换成电信号.一般,模拟量为电流信号,开关量为电压信号。这些信号再由模数转换器转换成数字信号送到计算机端口(如com1口)。用户编制的监控程序其功能便是要能准确及时地从计算机端口捕获这些数据,再按用户的量程要求转换成数值进行显示并生成数据文件进行报表管理。

二、模数转换器

在整个控制流程中,我们通常把计算机称为上位机,模数转换器称为下位机。ADAM系列模块在计算机工业控制应用中是一种常用的A/D转换器。它具有性能稳定、精确度高、量程宽等特性。其中ADAM 4520 用于地址管理和通讯。ADAM 4017用于连接模拟量,ADAM 4053用于连接开关量,其连接图如下,Vc一般为+12伏电压。

一般来说明,4520只须一个,而4017和4053的个数要须根据具体模拟量和开关量的个数来确定。一个4053可连接16路开关量,一个4017可连接8路模拟量。 使用前还必须用ADAM专用测试程序设置模块的量程档,并对多个模块进行地址分配。如若要用到2个4017,则将其中一个地址设定为01H,另一个地址设置为02H。用VB编程时,程序中的接口地址必须与这个设定一致,否则将导致捕获的数据张冠李戴,不合实际而失去意义。模块的地址和量程设定好后,由ADAM测试程写入模块中的EPROM中.

三、程序实例

窗体中要建立定时器对象(名为timer1)和通讯对象(名为comm1)。假设目前有10个模拟量,10个开关量,有一个机组。下位机有:一个4520,两个4017,地址分别为01H和02H,每个4017只用到5路端口; 一个开关量,地址为03H。并假设ADAM4017用0--20毫安档,模量实际电流信号的变化范围是4--20毫安,先定义如下变量:

CONST mnlnum=10 '模拟量个数

const kglnum=10 '开关量个数

CONST jznum=1 '机组个数

Dim bi(1 To 8) As Integer '开关量转换后的值

Dim aM4000(1 To mnlnum) as String '用于存放从端口捕获到的字串

Dim currkgl(1 To kglnum, 1 To jznum) As Integer '最后得到的开关量的值

Dim currmnl(1 To mnlnum, 1 To jznum) As Integer '最后得到的模拟量的值

Dim lcmax(1 to mnlnum,1 to jznum) '用户最大量程

Dim lcmin(1 to mnlnum,1 to jznum) '用户最小量程

编制时钟事件,以便程序定时去端口采集数据。定时器对象Timer1的interval值可设置为60000,目的是让程序每分钟采集一次数据。

Sub Timer1_Timer ()

Dummy = DoEvents() '响应Windows的其它任务

getmnl '捕获模拟量的值

mnlzh '模拟量根据量程转换

Dummy = DoEvents()

kgin '开关量转换

Dummy = DoEvents()

End Sub

Sub getmnl () 'ADAM 通讯

On Error Resume Next

Comm1.PortOpen = True

For i = 1 To 5 '01H只用5路通道

Select Case i

Case 1

aab$ = "#010" '通道的具体地址

Case 2

aab$ = "#011"

Case 3

aab$ = "#012"

Case 4

aab$ = "#013"

Case 5

aab$ = "#014"

End Select

ccb$ = adam_mnli(aab$)

If ccb$ "fail" Then aM4000(i) = ccb$

Dummy = DoEvents()

Next i

For j = 1 To 5 '02H只用5路通道

Select Case j

Case 1

aab$ = "#020"

Case 2

aab$ = "#021"

Case 3

aab$ = "#022"

Case 4

aab$ = "#023"

Case 5

aab$ = "#024"

End Select

ccb$ = adam_mnli(aab$)

If ccb$ "fail" Then

aM4000(j + 5) = ccb$

End If

Dummy = DoEvents()

Next j

Comm1.PortOpen = False

End Sub

Function adam_mnli(mnlo As String) As String

'模拟量输入4017 address 01,02H

On Error Resume Next

Comm1.Output = mnlo & Chr$(13)

rx$ = ""

flag = 0

Do

Dummy = DoEvents()

flag = flag + 1

Loop Until Comm1.InBufferCount > 1 Or flag > 600

If flag > 600 Then

adam_mnli = "fail"

Exit Function

Else

rx$ = Comm1.Input '捕获到的字串放rx$变量中

End If

If Mid$(rx$, Len(rx$), Len(rx$)) = Chr$(13) Then

adam_mnli=Mid$(rx$, 3, 6) '截取有效部分赋给函数

End If

End Function

Sub mnlzh () '下位机组模拟量转换

ReDim pmnl(1 To mnlnum, 1 To jznum) As Single

For i = 1 To mnlnum

pmnl(i, 1) = (Val(aM4000(i)) - 4) / (20# - 4) '根据毫安档转换

currmnl(i,1)=pmnl(i,1)*(lcmax(i,1)-lcmin(i, 1) )+lcmin(i,1)

'根据最大和最小量程转换成显示需要的值

Next i

End Sub

Sub kgin () '4053 地址03H

h_kgl1$ = adam_kglin("$03")

ssY% = Val("&H" & Mid$(h_kgl1$, 3, 2)) '低8路开关

kglzh(ssY%) '开关量转换

currkgl(1, 1) = bi(1)

currkgl(2, 1) = bi(2)

currkgl(3, 1) = bi(3)

currkgl(4, 1) = bi(4)

currkgl(5, 1) = bi(5)

currkgl(6, 1) = bi(6)

currkgl(7, 1) = bi(7)

currkgl(8, 1) = bi(8)

ssY% = Val("&H" & Mid$(h_kgl1$, 1, 2))

kglzh(ssY%)

currkgl(9, 1) = bi(1)

currkgl(10, 1) = bi(2)

End Sub

Function adam_kglin (kin As String) As String

'ADAM 开关量输入变频器 4053,捕获开关量数据

On Error Resume Next

Comm1.PortOpen = True

Comm1.Output = kin & Chr$(13)

flag = 0

Do

Dummy = DoEvents()

flag = flag + 1

Loop Until Comm1.InBufferCount > 1 Or flag > 1300

If flag > 1300 Then

adam_kglin = "fail"

Comm1.PortOpen = False: Exit Function

Else

rx$ = Comm1.Input

End If

If Mid$(rx$, Len(rx$), Len(rx$)) = Chr$(13) Then

'取前四位

adam_kglin = Mid$(rx$, 2, 4)

'每个4053有16路开关通道,因此函数值是个四位16进制数,16位二

'进制数,1表示正常,0表示故障

End If

Comm1.PortOpen = False

End Function

Sub kglzh (t As Integer) '开关量转换

For i = 1 To 8

dd = t Mod 2

If dd 0 Then

bi(i) = 1

Else

bi(i) = 0

End If

t = t \ 2

Next i

End Sub

以上程序从端口捕获到的数据经程序处理后得到的最终有效值存放在数组currmnl( )和currkgl( )中,在具体应用中,用户可以编制其它程序对放在数组currmnl( )和currkgl( )中数据进行报表管理。

上一篇:大学何处去 下一篇:Findings of Phonological Fossilization of C...