高志杨 于新刚
摘要:Modbus协议在电子控制器通讯上有广泛的应用,对其必要的掌握和应用是广大相关工程技术人员必备的能力,使用VB6.0进行程序开发有简单易学,开发周期短的特点,利用其MSComm控件通过串口通讯可以轻松实现与智能仪表等电子控制器的通讯。主要介绍了温控表通过Modbus-RTU协议模式进行通讯的方法,并以一款霍尼韦尔温控表为具体控制对象,VB6.0为程序开发平台,通过实例编程,介绍了串口与MSComm控件实现可变参数通讯和对温控表编程温控的过程。
关键词:Modbus协议;VB6.0; RS-485;MSComm控件
中图分类号:TP302 文献标识码:A 文章编号:1009-3044(2017)31-0095-06
Control Program Realization of Honeywell Temperature Control Meter Based on VB
GAO Zhi-Yang,YU Xin-Gang
(Jiamusi University, Teaching Experiment Equipment Management Center, Jiamusi 154007,China)
Abstract: The Modbus protocol has a wide range applications in the communication of electronic controllers, the mastering and application are the necessary capabilities of the relevant engineering and technical personnel. The feauture of VB6.0 is easy to learn and develop the programg, its MSComm control through the serial communication can easily achieve communication with intelligent instruments and other electronic controller. This paper mainly introduces the method of communication between the temperature control meter and the Modbus-RTU protocol mode, and takes a Honeywell temperature control meter as the concrete control object. VB6.0 is the program development platform, through the example programming, introducing variable parameter communication and temperature control process between the serial port and the MSComm Control.
Key words: Modbus protocol; VB6.0; RS-485; MSComm control
本文从实际应用角度介绍了利用VB6.0的串口通信控件和RS485总线通过Modbus-RTU协议,实现与霍尼韦尔温控表通讯,读取、显示现场温度与程序设定值,并对温控表目标温度进行设定的过程,编程实现了温度控制的目的。
1 Modbus-RTU协议模式简介
Modbus-RTU是Modbus协议下的一个协议传输模式。Modbus是一个工业上常用的通讯协议,通过Modbus协议,控制器相互之间、控制器经由网络和其他设备之间可以实现通信。Modbus协议已经成为一种 通用工业标准。用于控制器时,通常选择设置其中的ASCII传输模式或RTU传输模式中一种。通过Modbus协议控制器组成的网络通信通常使用主-从技术,即一设备(主设备)能初始化查询传输(查询),从设备返回消息作为回应,主从设备发送的消息报文格式都要符合Modbus协议的要求。
控制程序设计中采用了常用的Modbus-RTU协议模式,表1是协议规定其报文结构:
表1 Modbus-RTU报文结构
[地址码 功能码 数据地址码 数据区 CRC校验码 一个字节 一个字节 2字节 N个字節 2个字节 ]
其中报文中的每个字节都是2个十六进制字符组成。地址码表明标明从机的地址,每个从机都必须有唯一的地址码,并且只有符合地址码的从机才能响应主机回送信息;功能码告诉从机应执行什么动作;数据地址码标明动作执行的起始寄存器或线圈地址;数据区包括需要由从机返回何种信息或执行什么动作;CRC校验码用于信息的正确性检验。
2 霍尼韦尔温控表的参数设置
温度控制程序控制对象是型号为DC1040CT的霍尼韦尔温控表,温控表内部已经固化了Modbus协议,根据温控表说明书的技术参数说明可知:表内集成有Modbus-RTU和Modbus-ASCII两种协议模式,在本温控程序设计中,设置表的参数PSL为RTU,即采用Modbus-RTU模式;设置参数BITS为E_81,即偶校验、8位数据位、1位停止位;设置表的地址参数ID.NO为1,即仪表的协议地址为1;设置波特率参数BAUD为48,即波特率为4800kps;小数点设置参数DP设为1,即1位小数点。
3 温控程序软件的设计与实现
温度控程序使用的编程软件是微软的Visual Basic 6.0,利用其中的Mscomm串口通信控件实现与温控表的通讯与温度控制。Visual Basic 6.0中的Mscomm控件主要是为RS-232通用串口设计的。现在的计算机上普遍已经不再配置RS-232串口,可以在USB串口上接一个USB转RS-232的转接口,再配置一个RS-232串口到RS-485总线的转换器,即可实现Mscomm与RS-485总线上的设备通讯。
温度控制程序通过USB串口转换到RS-232串口,再转换到RS-485总线与温控表相连接,通过温控表被配置唯一的地址码和Modbus-RTU协议完成数据通讯连接,实现控制程序对温控表的相关数据写入与读取。
3.1 温度控制软件的界面设计
运行VB6.0,新建一个命名为Honeywell控制的工程,主窗体名为:控制窗口,然后在工具箱中添加Microsoft Comm Control 6.0控件和Microsoft Windows Common Controls 6.0控件,在窗体设计界面中分别加入Frame、Label、MScomm、ComboBox、CommandButton、Timer、Slider、TextBox等控件,分别命名,并将TextBox控件Text属性都设置为空,设计界面如图1:
3.2 界面的窗体Form_load()事件程序设计
利用窗体事件Form_load(),对窗体上的各控件进行参数设置。用各ComboBox控件的AddItem属性设置各个ComboBox控件的待选参数,用各ComboBox控件的ListIndex属性设置各默认初始参数,Form_Load()过程中如下代码:
Private Sub Form_Load()
'仪表地址选择设置
AddressNo.AddItem "1", 0
AddressNo.AddItem "2", 1
AddressNo.AddItem "3", 2
AddressNo.AddItem "4", 3
AddressNo.AddItem "5", 4
AddressNo.AddItem "6", 5
'串口号设置
ComNo.AddItem "COM1", 0
ComNo.AddItem "COM2", 1
ComNo.AddItem "COM3", 2
ComNo.AddItem "COM4", 3
ComNo.AddItem "COM5", 4
'波特率设置
BaudeRate.AddItem "4800", 0
BaudeRate.AddItem "9600", 1
BaudeRate.AddItem "19200", 2
BaudeRate.AddItem "115200", 3
'校验位设置
Parity.AddItem "N", 0
Parity.AddItem "E", 1
Parity.AddItem "O", 2
'数据位设置
DataBit.AddItem "7", 0
DataBit.AddItem "8", 1
'停止位设置
StopBit.AddItem "1", 0
StopBit.AddItem "2", 1
'预置串口参数默认值
AddressNo.ListIndex = 0
ComNo.ListIndex = 0
BaudeRate.ListIndex = 1
Parity.ListIndex = 1
DataBit.ListIndex = 1
StopBit.ListIndex = 0
'初始串口未打开提示信息
Indic_Conn.Caption = " 串口未打开"
'设置Timer1为不可用
Timer1.Enabled = False
End Sub
注意,AddressNo.AddItem即设备地址参数,可以根据实际需要参照Modbus协议规定继续添加。同时,在过程中关闭了Timer1控件对象,因为本程序在Timer1_Timer事件中有数据通讯请求过程,若在串口未连接的情况下执行数据通讯请求,会出现错误,所以在Form_load()中將其关闭,待串口打开后再将其打开,执行数据通讯请求。
3.3 按钮互锁的过程设计
本控制程序中的串口连接与断开两个按钮要实现互锁,即串口成功打开后,则打开按钮状态变为无效,直到按断开按钮,使串口成功断开为止。断开按钮也是如此,断开串口后,则断开按钮状态也变为无效,要等串口成功连接后,断开按钮才有效。按钮互锁子过程放在窗体代码中,按钮互锁子过程代码如下:
Public Sub button_manage(button As Variant)
Select Case button
'参数为连接按钮
Case CMDConn
'断开按钮有效
CMDDisconn.Enabled = True
'连接按钮无效
CMDConn.Enabled = False
'参数为断开按钮
Case CMDDisconn
'连接按钮有效
CMDConn.Enabled = True
'断开按钮无效
CMDDisconn.Enabled=False
End Select
End Sub
其中,被锁定的按钮控件名作为调用过程的参数,锁定管理过程根据参数判断被锁定按钮,并打开对应的另一按钮。
3.4 打开与关闭串口的程序设计
CMDConn_Click()是串口打开事件过程,首先在过程中设置一条On Error Goto Errline语句,功能是若串口打开不成功则跳转至Errline行,进行打开错误提示,并退出串口连接过程。其后是串口各参数设置并打开串口过程。执行完打开串口指令后,继续执行提示串口打开成功指令、执行打开关闭按钮互锁过程、执行使Frame控件无效指令和打开Timer1控件指令,实现各个控件对应的功能。串口打开过程代码如下:
Private Sub CMDConn_Click()
On Error GoTo Errline
'配置、确定打开串口各项参数
MSComm1.CommPort = ComNo.ListIndex + 1
MSComm1.Settings = BaudeRate.Text
+ "," + Parity.Text + "," + DataBit.Text +
"," + StopBit.Text
MSComm1.InputMode = 1
MSComm1.InputLen = 0
MSComm1.InBufferCount = 0
MSComm1.OutBufferCount = 0
MSComm1.RThreshold = 7
MSComm1.InBufferSize = 1024
MSComm1.OutBufferSize = 1024
' 根据以所确定参数打开串口
MSComm1.PortOpen = True
'提示串口成功打开
Indic_Conn.Caption = " 串口成功打开"
'调用按钮互锁程序,使打开无效关闭按钮
'有效
button_manage (CMDConn)
'使各通讯参数不可更改
Commpara.Enabled = False
'使Timer1控件工作
Timer1.Enabled = True
Exit Sub
Errline:
Indic_Conn.Caption = "串口未打开,请检查串口参数重新连接.."
End Sub
关闭串口过程代码如下:
Private Sub CMDDisconn_Click()
'关闭Timer1使数据通讯请求指令无效
Timer1.Enabled = False
'使串口通讯各参数可调整
Commpara.Enabled = True
'关闭串口
MSComm1.PortOpen = False
'显示串口关闭信息
Indic_Conn.Caption = " 串口已关闭"
'关闭断开按钮,打开连接按钮
button_manage (CMDDisconn)
End Sub
3.5 数据写入与读取过程程序设计
根据霍尼韦尔温控表的技术资料可知,温控表保存设定温度数据的寄存器地址为000,保存程序温度数据的寄存器地址为138,要在控制程序中分别显示温控表的设定温度值和程序温度值,本程序采用的是读取设定温度数据请求和读取程序温度数据分开发送和读取的方法,程序中定义了一个公共变量,用于判断Modbus-RTU传输协议应答报文中传输的是设定温度寄存器数据还是程序温度寄存器数据,同时定义了一个保存设定温度寄存器数据的变量,供温度设定控件Slider1和温度写入过程共同使用。将以上两个公共变量,定义在公共模块中,并将公共模块命名为PublicFUN,PublicFUN模块中设置以上两公共变量的代码如下:
'定义数据请求寄存器地址变量
Public addressVal As Integer
'定義设定温度值数据变量
Public SSetVal As Long
由Modbus-RTU协议规范模式可知,传输的报文的最后两个字节存放的是计算后的CRC校验码,程序中必须有CRC校验码计算程序,供系统发送请求数据和接受数据进行数据正确性检验时使用,因为CRC校验码计算是公用的函数,我们将也其放在公共模块中,CRC校验码计算函数代码如下:
Public Function CRC16(data() As Byte, no As Integer, btLoCRC As Byte, _
btHiCRC As Byte) As String
Dim CL As Byte, CH As Byte
Dim SaveHi As Byte, SaveLo As Byte
Dim i As Integer
Dim Flag As Integer
btHiCRC = &HFF
btLoCRC = &HFF
CL = &H1
CH = &HA0
For i = 0 To (no - 1)
btHiCRC = btHiCRC Xor data(i)
For Flag = 0 To 7
SaveHi = btLoCRC
SaveLo = btHiCRC
btLoCRC = btLoCRC \ 2
btHiCRC = btHiCRC \ 2
If ((SaveHi And &H1) = &H1) Then
btHiCRC = btHiCRC Or &H80
End If
If ((SaveLo And &H1) = &H1) Then
btLoCRC = btLoCRC Xor CH
btHiCRC = btHiCRC Xor CL
End If
Next Flag
Next i
Dim ReturnData(1) As Byte
ReturnData(0) = btHiCRC
ReturnData(1) = btLoCRC
CRC16 = ReturnData
End Function
Public Function CRC16Tbl(data() As Byte, no As Integer, btLoCRC As Byte, btHiCRC As Byte) As String
'Dim btLoCRC As Byte
'Dim btHiCRC As Byte
btLoCRC = &HFF
btHiCRC = &HFF
Dim i As Integer
Dim iIndex As Long
For i = 0 To (no - 1)
iIndex = btHiCRC Xor data(i)
btHiCRC = btLoCRC Xor GetCRCLo(iIndex)
btLoCRC = GetCRCHi(iIndex)
Next i
Dim ReturnData(1) As Byte
ReturnData(0) = btHiCRC
ReturnData(1) = btLoCRC
CRC16Tbl = ReturnData
End Function
'CRC低位字節值表
Function GetCRCLo(Ind As Long) As Byte
GetCRCLo=Choose(Ind+1, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40,&H1,&HC0,&H80,&H41,&H0,&HC1,&H81,&H40,&H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81,&H40,&H0,&HC1,&H81,&H40,&H1,&HC0,&H80,
&H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0,&HC1,&H81,&H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81,&H40,&H1,&HC0,&H80,&H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1,&HC0,&H80,&H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0,&HC1,&H81,&H40,&H0,&HC1,&H81,&H40,&H1,&HC0,&H80,&H41, &H0, &HC1, &H81, &H40, &H1,&HC0, &H80, &H41, &H1,&HC0, &H80,&H41, &H0, &HC1, &H81, &H40)
End Function
'CRC高位字节值表
Function GetCRCHi(Ind As Long) As Byte
GetCRCHi=Choose(Ind+1,&H0, &HC0, &HC1, &H1, &HC3, &H3, &H2, &HC2, &HC6, &H6, &H7, &HC7, &H5, &HC5, &HC4, &H4, &HCC, &HC, &HD, &HCD, &HF, &HCF, &HCE, &HE, &HA, &HCA, &HCB, &HB, &HC9, &H9, &H8, &HC8, &HD8, &H18, &H19, &HD9, &H1B, &HDB, &HDA, &H1A, &H1E, &HDE, &HDF, &H1F, &HDD, &H1D, &H1C, &HDC, &H14, &HD4, &HD5, &H15, &HD7, &H17, &H16, &HD6, &HD2, &H12, &H13, &HD3, &H11, &HD1, &HD0, &H10, &HF0, &H30, &H31, &HF1, &H33, &HF3, &HF2, &H32, &H36, &HF6, &HF7, &H37, &HF5, &H35, &H34, &HF4, &H3C, &HFC, &HFD, &H3D, &HFF, &H3F, &H3E, &HFE, &HFA, &H3A, &H3B, &HFB, &H39, &HF9, &HF8, &H38, &H28, &HE8, &HE9, &H29, &HEB, &H2B, &H2A, &HEA, &HEE, &H2E, &H2F, &HEF, &H2D, &HED, &HEC, &H2C, &HE4, &H24, &H25, &HE5, &H27, &HE7, &HE6, &H26, &H22, &HE2, &HE3, &H23, &HE1, &H21, &H20, &HE0, &HA0, &H60, &H61, &HA1, &H63, &HA3, &HA2,&H62,&H66,&HA6,&HA7,&H67,&HA5,&H65, &H64, &HA4, &H6C, &HAC, &HAD, &H6D, &HAF, &H6F, &H6E, &HAE, &HAA, &H6A, &H6B, &HAB, &H69, &HA9, &HA8, &H68, &H78, &HB8, &HB9, &H79, &HBB, &H7B, &H7A, &HBA, &HBE, &H7E, &H7F, &HBF, &H7D, &HBD, &HBC, &H7C, &HB4, &H74, &H75, &HB5, &H77, &HB7, &HB6, &H76, &H72, &HB2, &HB3, &H73, &HB1, &H71, &H70, &HB0, &H50, &H90, &H91, &H51, &H93, &H53, &H52, &H92,&H96,&H56,&H57, &H97, &H55, &H95, &H94, &H54, &H9C, &H5C, &H5D, &H9D, &H5F, &H9F, &H9E, &H5E, &H5A, &H9A, &H9B, &H5B, &H99, &H59, &H58, &H98, &H88, &H48, &H49, &H89, &H4B, &H8B, &H8A, &H4A, &H4E, &H8E, &H8F, &H4F, &H8D, &H4D, &H4C, &H8C,&H44,&H84,&H85,&H45,&H87,&H47,&H46,&H86,&H82,&H42,&H43,&H83,&H41,&H81,&H80, &H40)
End Function
在發送设定温度数据过程开始前,需要先根据Modbus-RTU协议模式规范,设计好所发送数据报文并赋值。本程序采的是协议中的多寄存器写入功能码16,并且所读取寄存器数量为1,根据协议规范定义一个以字节型(Byte)数据为元素类型,元素个数为11的数组,将其各位元素经过计算和赋值,通过MSComm控件发送到RS485总线。设计的报文如表2:
写入设定温度寄存器数据过程实现代码如下:
Private Sub WRdata(DataToWR As Long)
'定义过程数组与所需变量
Dim WRsend(10) As Byte
Dim crc
Dim btLoCRC As Byte, btHiCRC As Byte
'写入设备ID位赋值
WRsend(0) = "&h" + Hex(AddressNo.ListIndex + 1)
'写入功能码位赋值
WRsend(1) = "&h" + Hex(16)
'写入寄存器地址高、低位地址位赋值
WRsend(2) = "&h" + Hex(0)
WRsend(3) = "&h" + Hex(0)
'写入寄存器数量数高、低位赋值
WRsend(4) = "&h" + Hex(0)
WRsend(5) = "&h" + Hex(1)
'发送字节数位赋值
WRsend(6) = "&h" + Hex(2)
'写入寄存器数据位赋值
WRsend(7) = "&h" + Hex(DataToWR \ 256)
WRsend(8) = "&h" + Hex(DataToWR Mod 256)
'计算CRC值
crc = CRC16(WRsend, 9, btLoCRC, btHiCRC)
'待发送帧CRC校验码位赋值
WRsend(9) = "&h" + Hex(btHiCRC)
WRsend(10) = "&h" + Hex(btLoCRC)
'发送数据写入请求
MSComm1.Output = WRsend
'清缓存
MSComm1.InBufferCount = 0
End Sub
数据读取报文的设计过程与写入报文设计类似,只不过依照协议计算出的帧长度和各位的赋值情况有所不同,根据协议Modbus-RTU规定,寄存器数据读取功能码为03,并且所读寄存器数量为1,根据协议规范,定义一个以字节型(Byte)数据为元素类型,元素个数为8的数组,将其各位元素经过计算和赋值,通过MSComm控件发送到RS485总线。设计的报文如表3:
读取过程实现代码如下:
Public Function SendRequest(addval As Integer)
'定义发送数组与相关变量
Dim QRsend(7) As Byte
Dim crc
Dim btLoCRC As Byte, btHiCRC As Byte
If MSComm1.PortOpen = True Then
'被读取设备地址赋值
RQsend(0) = "&h" + Hex(AddressNo.ListIndex + 1)
'寄存器读取功能码赋值
RQsend(1) = "&h" + Hex(3)
'被读取寄存器高、低位赋值
RQsend(2) = "&h" + Hex(0)
RQsend(3) = "&h" + Hex(addval)
'读取寄存器数量高、低位赋值
RQsend(4) = "&h" + Hex(0)
RQsend(5) = "&h" + Hex(1)
'计算CRC值
crc = CRC16(RQsend, 6, btLoCRC, btHiCRC)
'待发送报文CRC位赋值
RQsend(6) = "&h" + Hex(btHiCRC)
RQsend(7) = "&h" + Hex(btLoCRC)
'发送数据读取请求
MSComm1.Output = RQsend
'清缓存
MSComm1.InBufferCount = 0
End If
End Function
程序中在Timer1控件的Timer1_Timer事件中分别调用数据设定温度数据读取过程、设定温度数据读取过程和设定温度数据写入过程,使温控程序循环进行以上三个数据的读取和写入。先设置Timer1的Interval值为100,即设定Timer1的循环周期为0.1秒,温度数据的读取和写入实现代码如下:
Private Sub Timer1_Timer()
'设置一静态计数变量并循环递增
Static TMCount as integer
TMCount = TMCount + 1
If TMCount < 3 Then
'TMCount為1时,读取程序温度数据
If TMCount = 1 Then
addressVal = 138
SendRequest (138)
'TMCount为2时,读取设定温度数据
Else
addressVal = 0
SendRequest (0)
End If
Else
'TMCount为3时,写入设定温度数据
Call WRdata(SSetVal)
'TMCount清零,重新启动读取与写入循环
TMCount = 0
End If
End Sub
程序中串口通讯控件MSComm1的MSComm1_OnComm()事件用于读取温控表相应数据,并将相关数据进行显示,实现代码如下:
Private Sub MSComm1_OnComm()
'定义过程相关变量
Dim RDdata() As Byte
Dim btLoCRC As Byte, btHiCRC As Byte
Dim data As Integer
Dim crc
Select Case MSComm1.CommEvent
Case comEvReceive
RDdata = MSComm1.Input
If RDdata (1) = 3 Then
'计算并返回CRC码值
crc = CRC16(RDdata, 5, btLoCRC, btHiCRC)
If RDdata (5) = btHiCRC And
RDdata (6) = btLoCRC Then
'CRC值正确则显示数据
Select Case addressVal
Case 138
PV.Text = 0.1 * (256 * Val(RDdata (3)) + Val(RDdata (4)))
Case 0
SV.Text = 0.1 * (256 * Val(RDdata (3))
+ Val(RDdata (4)))
End Select
End If
End If
End Select
End Sub
程序中的Slider控件用于温度设定,过程代码如下:
Private Sub Slider1_scroll()
'将设定温度值换算为寄存器数据并赋值给公共变量
SSetVal = 10 * Slider1.Value
End Sub
至此,本控制程序的界面与程序代码设计完毕。程序运行后,可以得到如图2所示的温控程序界面:
可以通过ComboBox控件对设备地址、串口号、波特率、校验位、数据位、停止位分别设置相关参数,操作系统中串口的各参数也要和被控的温控表通讯参数一致。点击连接按钮进行连接,连接成功后,当前温控表的程序温度值与设定温度值被显示出来,可以通过Slider1控件进行温控表设定温度值的设置,并在程序界面中及时显示出来。如图3。
在串口成功连接后,相关的通讯参数是不能被更改的,若要重新设置相关的通讯参数,点击断开按钮断开通讯连接,重新设置相关参数并再次进行连接即可。
4 结论与展望
通过上述温控控制程序的设计与实现,可知其重点是通讯的实现与对协议的掌握,温控程序中通讯模块实现了通讯参数的随需调整设置,方法具有较强的实用价值;VB6.0通过数组数据结构可轻松实现Modbus-RTU协议报文结构,过程方法易于理解;该程序的内容侧重点是通讯和协议的实现,整体温控过程完整,界面的完善设计可进一步随需实现。
参考文献:
[1] 李江全.现代测控系统典型应用实例[M].北京:电子工业出版社,2010.
[2] 李江全.Visual Basica数据采集与串口通信测控应用实战[M].北京:人民邮电出版社,2010.
[3] 张辉.Visual Basic串口通信及编程实例[M].北京:化学工业出版社,2017.
[4] 董立君,劉书伟,侯逸青.VB下基于Modbus规约的串口通信[J].工业控制计算机,2006,19(8):8-9,11.