VB控件Mscomm控件与PLC进行RSModbus通讯源码

合集下载

Modbus 通讯协议编程(VB源代码)

Modbus 通讯协议编程(VB源代码)

最近,本人为了实现电脑与Delta V FD-M变频器通讯,特意用VB6.0编了一个Modbus协议通讯软件。

这只是一个测试版,但Modbus的ASCII协议和RTU协议都已经实现。

现在将源程序上传,希望可以帮助到有需要的朋友,谢谢!另外,假如你觉得有更好的想法,欢迎指教。

如果对本程序有任何意见和建议,也可以一起讨论,共同进步。

大家多多支持俺啊。

附:VB6源程序Option ExplicitPrivate Text1text As StringPrivate RTUCRC As String'串口选择Private Sub Combo1_Click()mPort = Combo1.ListIndex + 1End Sub'数据位改变< span style="color: #008000;">Private Sub Combo2_Click()Call settingEnd Sub'波特率改变< span style="color: #008000;">Private Sub Combo3_Click()Call settingEnd Sub'奇偶校验改变< span style="color: #008000;">Private Sub Combo4_Click()Call settingEnd Sub'停止位改变< span style="color: #008000;">Private Sub Combo5_Click()Call settingPrivate Sub setting()MSComm1.Settings = CStr(Combo3.Text) & ","& CStr(Combo4.Text) & ","& CStr(C ombo2.Text) _& ","& CStr(Combo5.Text)End Sub'打开关闭串口< span style="color: #008000;">Private Sub Command1_Click()On Error Resume NextIf MSComm1.PortOpen = False ThenMSComm1.PortOpen = TrueElseMSComm1.PortOpen = FalseEnd IfIf MSComm1.PortOpen Then'打开关闭按钮显示文字及combo1使能Command1.Caption = "关闭串口"Combo1.Enabled = FalseElseCommand1.Caption = "打开串口"Combo1.Enabled = TrueEnd IfIf Err Then'打开串口失败,则显示出错信息MsgBox Error$, 48, "错误信息"Exit SubEnd IfEnd Sub'10转16进制< span style="color: #008000;">Private Sub Command2_Click(Index As Integer)On Error Resume NextText4.Text = Hex(Text3.Text)If Err Then''则显示出错信息< span style="color: #008000;">MsgBox Error$, 48, "错误信息"Exit SubEnd If'16转10进制< span style="color: #008000;">Private Sub Command3_Click()Dim a As Longa = Val("&H"& CStr(Text4.Text))Text3.Text = aEnd Sub'手动串口发送< span style="color: #008000;">Private Sub Command4_Click()If MSComm1.PortOpen = False ThenMsgBox"请先打开串口< span style="color: #800000;">", , "错误信息" Exit SubEnd IfCall sentsubEnd Sub'清除接收窗< span style="color: #008000;">Private Sub Command5_Click()Text2.Text = ""End SubPrivate Sub Command6_Click()Unload MeEnd SubPrivate Sub Command7_Click()On Error Resume NextDim STP As StringSTP = CStr(Chr(2)) & "010001"& CStr(Chr(3)) & "25"MSComm1.Settings = "9600,N,7,2"MSComm1.PortOpen = TrueMSComm1.Output = STPMSComm1.PortOpen = FalseIf Err Then'打开串口失败,则显示出错信息MsgBox Error$, 48, "错误信息"Exit SubEnd IfEnd SubPrivate Sub Command8_Click()On Error Resume NextDim FWD As StringFWD = CStr(Chr(2)) & "010101"& CStr(Chr(3)) & "26" MSComm1.Settings = "9600,N,7,2"MSComm1.PortOpen = TrueMSComm1.Output = FWDMSComm1.PortOpen = FalseIf Err Then'打开串口失败,则显示出错信息MsgBox Error$, 48, "错误信息"Exit SubEnd IfEnd SubPrivate Sub Command9_Click()On Error Resume NextDim REV As StringREV = CStr(Chr(2)) & "010201"& CStr(Chr(3)) & "27" MSComm1.Settings = "9600,N,7,2"MSComm1.PortOpen = TrueMSComm1.Output = REVMSComm1.PortOpen = FalseIf Err Then'打开串口失败,则显示出错信息MsgBox Error$, 48, "错误信息"Exit SubEnd IfEnd Sub'窗口加载Private Sub Form_Load()Dim d%For d = 1To16Combo1.AddItem ("COM"& CStr(d))NextCombo1.ListIndex = 0Combo2.AddItem "6"Combo2.AddItem "7"Combo2.AddItem "8"Combo2.ListIndex = 2Combo3.AddItem "110" Combo3.AddItem "330" Combo3.AddItem "1200" Combo3.AddItem "2400" Combo3.AddItem "4800" Combo3.AddItem "9600" Combo3.AddItem "19200" Combo3.AddItem "38400" Combo3.AddItem "56000" Combo3.AddItem "57600" Combo3.AddItem "115200" Combo3.ListIndex = 5Combo4.AddItem "n" Combo4.AddItem "o" Combo4.AddItem "e" Combo4.ListIndex = 0Combo5.AddItem "1" Combo5.AddItem "2" Combo5.ListIndex = 0For d = 0To254Combo6.AddItem dNextCombo6.ListIndex = 1Text1.Text = "010*********" Text2.Text = ""Text3.Text = ""Text4.Text = ""Text5.Text = "1000"Text6.Text = "06"Text7.Text = "0"Text8.Text = "1"Option1.value = TrueOption3.value = TrueOption7.value = TrueOption9.value = TrueIf MSComm1.PortOpen = False ThenCommand1.Caption = "打开串口"ElseCommand1.Caption = "关闭串口"End IfEnd Sub'串口接收程序< span style="color: #008000;">Private Sub MSComm1_OnComm()Dim Hexchr As String, hexstring As String, i As Integer, j As Integer, hexdisp As Str ingIf Option8.value Thenhexstring = MSComm1.Input '十六进制显示< span style="color: #008000;">i = Len(hexstring)For j = 1To iHexchr = Mid(hexstring, j, 1)If Hex(Asc(Hexchr)) < 16ThenText2.Text = Text2.Text & "0"& Hex(Asc(Hexchr)) & " "ElseText2.Text = Text2.Text & Hex(Asc(Hexchr)) & " "End IfNext jText2.Text = Text2.Text & CStr(Chr(13)) & CStr(Chr(10))ElseText2.Text = Text2.Text & MSComm1.Input & CStr(Chr(13)) & CStr(Chr(10)) 'ASCII 码显示< span style="color: #008000;">End IfEnd Sub'手动发送选择< span style="color: #008000;">Private Sub Option1_Click()If Option1.value = True ThenTimer1.Enabled = FalseCommand4.Enabled = TrueElseTimer1.Enabled = TrueCommand4.Enabled = FalseEnd IfEnd Sub'Delta ASCII发送协议Private Sub Option10_Click()Combo6.Enabled = TrueText6.Enabled = TrueText7.Enabled = TrueText8.Enabled = TrueLabel10.Enabled = TrueLabel11.Enabled = TrueLabel12.Enabled = TrueLabel13.Enabled = TrueOption6.Enabled = FalseOption7.Enabled = FalseOption11.value = TrueCombo2.ListIndex = 1Combo5.ListIndex = 1Text1.Enabled = FalseLabel14.Enabled = FalseFrame7.Visible = TrueEnd Sub'自动发送选择< span style="color: #008000;"> Private Sub Option2_Click()If Option2.value = True ThenTimer1.Enabled = TrueCommand4.Enabled = FalseElseTimer1.Enabled = FalseCommand4.Enabled = TrueEnd IfEnd SubPrivate Sub Option3_Click() 'Non选项< span style="color: #008000;"> Combo6.Enabled = FalseText6.Enabled = FalseText7.Enabled = FalseText8.Enabled = FalseLabel10.Enabled = FalseLabel11.Enabled = FalseLabel12.Enabled = FalseLabel13.Enabled = FalseOption6.Enabled = TrueOption7.Enabled = TrueCombo2.ListIndex = 2Combo5.ListIndex = 0Text1.Enabled = TrueLabel14.Enabled = TrueFrame7.Visible = FalseEnd SubPrivate Sub Option4_Click() 'ASCII选项< span style="color: #008000;"> Combo6.Enabled = TrueText6.Enabled = TrueText7.Enabled = TrueText8.Enabled = TrueLabel10.Enabled = TrueLabel11.Enabled = TrueLabel12.Enabled = TrueLabel13.Enabled = TrueOption6.Enabled = FalseOption7.Enabled = FalseCombo2.ListIndex = 1Combo5.ListIndex = 1Text1.Enabled = FalseLabel14.Enabled = FalseFrame7.Visible = FalseEnd SubPrivate Sub Option5_Click() 'RTU选项< span style="color: #008000;"> Combo6.Enabled = TrueText6.Enabled = TrueText7.Enabled = TrueText8.Enabled = TrueLabel10.Enabled = TrueLabel11.Enabled = TrueLabel12.Enabled = TrueLabel13.Enabled = TrueOption6.Enabled = FalseOption7.Enabled = FalseCombo2.ListIndex = 2Combo5.ListIndex = 1Text1.Enabled = FalseLabel14.Enabled = FalseFrame7.Visible = FalseEnd Sub'发送时间间隔调整输入< span style="color: #008000;">Private Sub Text5_Change()Dim number As StringDim num As IntegerDim numcyc As Integernum = Len(Text5.Text)For numcyc = 1To numnumber = Mid(Text5.Text, numcyc, 1)Select Case InStr("0123456789", number)Case0MsgBox"输入时间间隔错误,请重新输入", , "错误信息"Exit SubEnd SelectNextTimer1.Interval = Text5.TextEnd Sub'自动发送定时器< span style="color: #008000;">Private Sub Timer1_Timer()If MSComm1.PortOpen ThenCall sentsubEnd IfEnd Sub'状态刷新定时器< span style="color: #008000;">Private Sub Timer2_Timer()StatusBar1.Panels(1).Text = "串口选择:< span style="color: #800000;">" & CStr(Comb o1.Text)StatusBar1.Panels(2).Text = "串口设置:< span style="color: #800000;">" & CStr(MSC omm1.Settings)StatusBar1.Panels(3).Text = "串口状态:< span style="color: #800000;">" & CStr(MSC omm1.PortOpen)End Sub'串口发送子程序Private Sub sentsub()Dim optioncase%If Option3.value Then optioncase = 1If Option4.value Then optioncase = 2If Option5.value Then optioncase = 3If Option10.value Then optioncase = 4Select Case optioncaseCase1If Option6.value ThenText1text = Text1.TextCall HexsentElseText1text = Text1.TextCall ASCIIsentEnd IfCase2Call incorporate '将输入的十进制从机地址、命令、资料地址和资料内容合并成字符串Call ASCIIcheckCall ASCIIsentCase3Call incorporate '将输入的十进制从机地址、命令、资料地址和资料内容合并成字符串Call RTUcheckCall HexsentCase4Call incorporate1 '将输入的十进制从机地址、命令、资料地址和资料内容合并成字符串Call deltaASCIICall ASCIIsentEnd SelectEnd Sub'十六进制发送< span style="color: #008000;">Private Sub Hexsent()Dim hexchrlen%, Hexchr As String, hexcyc%, hexmid As Byte, hexmiddle As String Dim hexchrgroup() As Byte, i As Integerhexchrlen = Len(Text1text)For hexcyc = 1To hexchrlen '检查Text1文本框内数值是否合适Hexchr = Mid(Text1text, hexcyc, 1)If InStr("0123456789ABCDEFabcdef", Hexchr) = 0ThenMsgBox"无效的数值,请重新输入< span style="color: #800000;">", , "错误信息" Exit SubEnd IfNextReDim hexchrgroup(1To hexchrlen \ 2) As ByteFor hexcyc = 1To hexchrlen Step2'将文本框内数值分成两个、两个i = i + 1Hexchr = Mid(Text1text, hexcyc, 2)hexmid = Val("&H"& CStr(Hexchr))hexchrgroup(i) = hexmid'MSComm1.Output = CStr(hexmid)NextMSComm1.Output = hexchrgroupEnd Sub'ASC码发送< span style="color: #008000;">Private Sub ASCIIsent()MSComm1.Output = Text1textEnd Sub'ASC校验,此段程序计算出LRC校验值,并加上字头和字尾Private Sub ASCIIcheck()Dim a%, b%, chrnum%, Lrcbyte As StringDim checksum%, char%, AscLrc%, Lrc%chrnum = Len(Text1text)For a = 1To chrnum Step2char= Val("&H"& CStr(Mid(Text1text, a, 2))) '两个两个的取字符< span style="color: #008000;">checksum = checksum + char'全部加起来< span style="color: #008000;">NextAscLrc = checksum Mod&H100 '取255的余数< span style="color: #008000;">Lrc = (&HFF - AscLrc) + 1'取二次补If Lrc < 16Then'此段程序是判断Hex(lrc)是否是一位数,Lrcbyte = "0"+ CStr(Hex(Lrc)) '如果是的话,前面加0;否则不加零ElseLrcbyte = CStr(Hex(Lrc))End IfText1text = CStr(Chr(58)) & CStr(Text1text) & Lrcbyte & CStr(Chr(13)) & CStr(Chr(1 0))End Sub'DeltaASCII校验,此段程序计算出LRC校验值,并加上字头和字尾Private Sub deltaASCII()Dim a%, b%, chrnum%, Lrcbyte As StringDim checksum%, char%, Lrc%chrnum = Len(Text1text)For a = 1To chrnumchar= Asc(Mid(Text1text, a, 1)) '两个两个的取字符< span style="color: #008000;"> checksum = checksum + char'全部加起来< span style="color: #008000;">NextLrc = (checksum + &H3) Mod&H100 '取255的余数< span style="color: #008000;"> If Lrc < 16Then'此段程序是判断Hex(lrc)是否是一位数,Lrcbyte = "0"+ CStr(Hex(Lrc)) '如果是的话,前面加0;否则不加零ElseLrcbyte = CStr(Hex(Lrc))End IfText1text = CStr(Chr(2)) & CStr(Text1text) & CStr(Chr(3)) & LrcbyteEnd Sub'RTU校验< span style="color: #008000;">Private Sub RTUcheck()Dim CRC() As ByteDim d(5) As ByteDim string1 As StringDim j As Integer, chrlength As Integer, temp As Stringstring1 = Text1textchrlength = Len(string1)For j = 0To chrlength / 2- 1temp = Mid(string1, j * 2+ 1, 2)d(j) = Val("&H"& temp)NextRTUCRC = CRC16(d) '调用CRC16计算函数, CRC(0)为高位, CRC(1)为低位Text1text = Text1text & RTUCRCEnd SubPrivate Sub incorporate() '将输入的十进制从机地址、命令、资料地址和资料内容合并成字符串Dim wholechar As String, wc%, wcyc%, wchar As StringDim SID As String, Cmd As String, InfoAdd As String, data As StringDim SIDnum%, Cmdnum%, InfoAddNum%, Datanum%On Error Resume Nextwholechar = CStr(Combo6.Text) & CStr(Text6.Text) & CStr(Text7.Text) & CStr(Text8.T ext)wc = Len(wholechar)For wcyc = 1To wcwchar = Mid(wholechar, wcyc, 1)If InStr("0123456789", wchar) = 0ThenMsgBox"输入错误,请重新输入< span style="color: #800000;">", , "错误提示"Exit SubEnd IfNextSIDnum = Len(CStr(Hex(Combo6.Text)))Select Case SIDnumExit SubCase1SID = "0"& CStr(Hex(Combo6.Text)) Case2SID = CStr(Hex(Combo6.Text))End SelectCmdnum = Len(CStr(Hex(Text6.Text))) Select Case CmdnumCase0Exit SubCase1Cmd = "0"& CStr(Hex(Text6.Text)) Case1Cmd = CStr(Hex(Text6.Text))End SelectInfoAddNum = Len(CStr(Hex(Text7.Text))) Select Case InfoAddNumCase0Exit SubCase1InfoAdd = "000"& CStr(Hex(Text7.Text)) Case2InfoAdd = "00"& CStr(Hex(Text7.Text)) Case3InfoAdd = "0"& CStr(Hex(Text7.Text)) Case4InfoAdd = CStr(Hex(Text7.Text))End SelectDatanum = Len(CStr(Hex(Text8.Text))) Select Case DatanumCase0Exit Subdata = "000"& CStr(Hex(Text8.Text))Case2data = "00"& CStr(Hex(Text8.Text))Case3data = "0"& CStr(Hex(Text8.Text))Case4data = CStr(Hex(Text8.Text))End SelectIf Err Then'显示出错信息< span style="color: #008000;">MsgBox Error$, 48, "错误信息"Exit SubEnd IfText1text = CStr(SID) & CStr(Cmd) & CStr(InfoAdd) & CStr(data)End SubPrivate Sub incorporate1() '将输入的十进制从机地址、命令、资料地址和资料内容合并成字符串Dim wholechar As String, wc%, wcyc%, wchar As StringDim SID As String, Cmd As String, InfoAdd As String, data As StringDim SIDnum%, Cmdnum%, InfoAddNum%, Datanum%On Error Resume Nextwholechar = CStr(Combo6.Text) & CStr(Text7.Text) & CStr(Text8.Text)wc = Len(wholechar)For wcyc = 1To wcwchar = Mid(wholechar, wcyc, 1)If InStr("0123456789", wchar) = 0ThenMsgBox"输入错误,请重新输入< span style="color: #800000;">", , "错误提示"Exit SubEnd IfNextSIDnum = Len(CStr(Hex(Combo6.Text)))Select Case SIDnumCase0Case1SID = "0"& CStr(Hex(Combo6.Text)) Case2SID = CStr(Hex(Combo6.Text))End Select'Cmdnum = Len(CStr(Hex(Text6.Text)))'Select Case Cmdnum'Case 0' Exit Sub'Case 1' Cmd = "0" & CStr(Hex(Text6.Text))'Case 1' Cmd = CStr(Hex(Text6.Text))'End SelectInfoAddNum = Len(CStr(Hex(Text7.Text))) Select Case InfoAddNumCase0Exit SubCase1InfoAdd = "0"& CStr(Hex(Text7.Text)) Case2InfoAdd = CStr(Hex(Text7.Text))End SelectDatanum = Len(CStr(Hex(Text8.Text))) Select Case DatanumCase0Exit SubCase1data = "000"& CStr(Hex(Text8.Text)) Case2data = "00"& CStr(Hex(Text8.Text)) Case3data = "0"& CStr(Hex(Text8.Text))Case4data = CStr(Hex(Text8.Text))End SelectIf Err Then'显示出错信息< span style="color: #008000;">MsgBox Error$, 48, "错误信息"Exit SubEnd IfIf Option11.value ThenCmd = "08"Text1text = CStr(SID) & CStr(Cmd) & CStr(InfoAdd)ElseCmd = "07"Text1text = CStr(SID) & CStr(Cmd) & CStr(InfoAdd) & CStr(data)End IfEnd SubPrivate Function CRC16(data() As Byte) As StringDim CRC16Lo As Byte, CRC16Hi As Byte'CRC寄存器< span style="color: #00800 0;">Dim CL As Byte, CH As Byte'多项式码&HA001Dim CRCLo As String, CRCHi As StringDim SaveHi As Byte, SaveLo As ByteDim i As IntegerDim Flag As IntegerCRC16Lo = &HFFCRC16Hi = &HFFCL = &H1CH = &HA0For i = 0To UBound(data)CRC16Lo = CRC16Lo Xor data(i) '每一个数据与CRC寄存器进行异或For Flag = 0To7SaveHi = CRC16HiSaveLo = CRC16LoCRC16Hi = CRC16Hi \ 2'高位右移一位< span style="color: #008000;">CRC16Lo = CRC16Lo \ 2'低位右移一位< span style="color: #008000;">If((SaveHi And&H1) = &H1) Then'如果高位字节最后一位为1< span style="color: #008000;">CRC16Lo = CRC16Lo Or&H80 '则低位字节右移后前面补1< span style="color: #008 000;">End If'否则自动补0< span style="color: #008000;">If((SaveLo And&H1) = &H1) Then'如果LSB为1,则与多项式码进行异或CRC16Hi = CRC16Hi Xor CHCRC16Lo = CRC16Lo Xor CLEnd IfNext FlagNext iIf Len(Hex(CRC16Hi)) = 1ThenCRCHi = "0"+ Hex(CRC16Hi)ElseCRCHi = Hex(CRC16Hi)End IfIf Len(Hex(CRC16Lo)) = 1ThenCRCLo = "0"+ Hex(CRC16Lo)ElseCRCLo = Hex(CRC16Lo)End IfCRC16 = CRCLo + CRCHiEnd Function。

VB串口通信程序代码

VB串口通信程序代码

vb中怎样用mscomm控件实现串口通信本问分两部分均来自第一部分jessezappy(晶晶)================================================================================== If MSComm1.PortOpen Then MSComm1.PortOpen = FalsemPort = 1 '假定是用COM1口' 设定传输速率等,可依照您的需求更改MSComm1.Settings = "9600,N,8,1"MSComm1.PortOpen = True'---------初始化Modem-------------MSComm1.Output = "ATZ"MSComm1.Output = "AT&F"MSComm1.Output = "ATE0"MSComm1.Output = "ATM1"MSComm1.Output = "ATQ0"MSComm1.Output = "ATV0"'--------------------------拨号-------------MSComm1.Output ="ATDT163" '拨163'---------------------------接通后MSComm1.Output ="SDFJDKSJLKFA" '发送字符串'---------------------Private Sub MSComm1_OnComm() '用串口事件捕捉数据..If MSComm1.InBufferCount Then' 通讯埠中假如有资料的话, 则读取进来InStringB = InStringB & MSComm1.Input' 如果资料中有Chr(13) 和Chr(10) 的话, 则显示出来If InStr(InStringB, vbCrLf) Theninstring = instring & InStringBAddText Text3, InStringB, FalseInStringB = ""End IfEnd IfEND SUB'-------------------------挂断--------MSComm1.PortOpen = False '这个挂断方法不能适用所有MODEM,我正在研究...通用办法================================================================================================第二部分:===========================================================================最后借你一篇文章看,作者不是我,里面的不一定都对..'-----------------------------------------------------------VB Mscomm控件应用江苏戚墅堰机车车辆厂设计处(213011) 李秉璋--------------------------------------------------------------------------------Visual Basic 6.0(以下简称VB) 是一种功能强大、简单易学的程序设计语言。

VB与永宏PLC通信源码要点

VB与永宏PLC通信源码要点

VB与PLC之实时控制系统詹金万、陈嘉龙一、前言随着IT产业的进步及因特网的发展,传统工业控制所使用之PLC控制器,具有高度的稳定性及抗噪声的特性且配线容易及价格便宜,因此被大量应用在自动化的场所,已由单机操作朝向网络控制化发展,本文在探讨网络控制化的核心技术,使PC藉由RS-232通讯协议(注1)控制PLC(如图一),并透过VB程序语言,达到远程控制及网络自动化控制的功能。

本文以手动/自动红绿灯控制为主题,所使用之PLC为国内永宏电机公司所制FB-PLC,内含通讯模块,因此不需额外增购,且可由该公司网站免费下载及更新阶梯图发展软件(Winproladder)。

二、FB-PLC通讯协议FB-PLC藉由RS-232与PLC取得接口的传输,其传输格式(注2)如图二所示,以起始字符(ASCII 02H)与结束字符(ASCII 03H)作为整个命令传输及响应讯息的传输封包,FB-PLC总计提供15种命令格式(ASCII 40H~4EH),当主系统将命令传至PLC后,PLC 将依据命令自动回传所对应的讯息,如图三所示范例:将PLC启动(RUN)Master 命令PLC回应三.手动/自动红绿灯控制阶梯图程序利用缓存器R0,R4作为绿灯时间的计数器,R1,R2作为绿灯闪烁次数及闪烁时间的计数器,R3作为黄灯停留时间计数器,Y0、Y1、Y2分别代表东西向红、黄、绿三个灯,Y3、Y4、Y5分别代表南北向红、黄、绿三个灯。

利用输入X2作手动/自动的切换控制。

当PLC处于自动模式时,绿灯交换分别由缓存器R0、R4控制;当PLC处于手动模式时,由输入X1决定绿灯交换程序。

红绿灯阶梯图的设计程序如图四所示。

图四手动/自动红绿灯控制阶梯图程序四、VB 实时监程序架构及程序设计PC藉由RS232与PLC取得联机,传送速度设定为9600bps,整个联机设定请参考VB程序Form_Load()段。

实时监控画面设计如图五所示,当执行实时侦测状态按钮时,桌面将呈现如图六~图九所示实时状态图,状态的侦测采用轮询(polling)方式,依序读取PLC输出及输入的实时状态,程序执行请参考VB程序SendFrame(Data, No)段;执行参数传递按钮时,桌面将呈现如图十画面,当使用者修改参数后,执行传递参数按钮,PLC 将依据新的数据执行其程序,程序执行请参考VB程序Send_Ref_Click()段。

应用MSComm控件实现计算机与PLC间的串行通讯

应用MSComm控件实现计算机与PLC间的串行通讯

应用MSComm控件实现计算机与PLC间的串行通讯摘要本文应用S7-200系列PLC的RS-485接口,通过PC/PPI电缆与计算机的RS-232接口连接,软件方面应用Visual Basic提供的串行通讯控件(MSComm)实现PC机对可编程序控制器的监控与管理。

本文主旨在于探讨应用可视化编程语言实现PC机与PLC网络之间数据通讯的技术以及实现方案,利用PC机的管理与监控功能实现对PLC的自动化控制。

关键词可编程序控制器;串行通讯;中断0 引言可编程序控制器(PLC)专门用于工业控制,它的核心是以微处理器的结构为基础,在硬件结构上和普通的计算机基本一致。

它在基本的计算机结构当中,加入了传统的继电器控制系统,使其具有了高度的可靠性,更好的适应工业现场的环境,而且具备了强大的联网处理功能,广泛地应用在工业控制生产过程中。

微软的Visual Basic提供了MSComm控件,通过硬件的串行端口传送和接收数据,实现了PC机与PLC之间的通信,为可视化程序对PLC的控制提供了可能。

本文基于西门子公司生产的S7-200型PLC,应用MSComm控件,编写了计算机与PLC通讯程序,包括了上位机和下位机相应的程序代码。

提出了应用编程语言实现PC/PLC网络之间数据通信的软件解决方案,实现了用PC机对PLC 的监控及控制。

1 PLC与计算机间的通讯S7-200型PLC可以连接编程器、人机接口设备,甚至连接其他的PLC或PC机,组成PLC网络,可以实现PC与PLC、PLC与PLC的各种通信功能。

同时可以应用PC的管理功能实现对PLC的编程、监控和联网的功能。

S7-200系列PLC具有9针的RS-485接口,可以通过PC/PPI电缆与计算机连接,PLC之间可以通过SINEC-L2接口连接成PLC网络。

S7-200系列PLC主要有两种通信模式:一种为点对点(PPI)通信协议模式,用在PLC与编程器或人机接口产品之间通讯;另一种是自由口通讯模式,此模式对用户完全开放,用户可以自行设定通讯协议,使用程序控制串行通讯接口。

VB实现PC与欧姆龙PLC通讯的串口编程

VB实现PC与欧姆龙PLC通讯的串口编程

VB实现PC与欧姆龙PLC通讯的串口编程第一篇:VB实现PC与欧姆龙PLC通讯的串口编程Private Sub Form_Load()Dim i As Integer'OPEN COM1If ComTrue(1)= 0 ThenIf ComOpen(1, 38400, 7, 1, 1, “sjh”)= 1 Then 'MsgBox(“已注册”)'sjh为你的注册账号Call SetDelayNum(64)End IfEnd Ifjisujisu1jisu2End Sub第二篇:VB中串口通讯的实现VB中串口通讯的实现.txt VB中串口通讯的实现------------------一、概述串口通讯作为一种古老而又灵活的通讯方式,被广泛地应用于PC 间的通讯以及PC和单片机之间的通讯之中。

提到串口通讯的编程,人们往往立刻想到C、汇编等对系统底层操作支持较好的编程语言以及大串繁琐的代码。

实际上,只要我们借助相关ActiveX控件的帮助,即使是在底层操作一向不被人看好的VB中,一样能够实现串口通讯,甚至其实现方法和C、汇编相比,要更加快捷方便。

下面,笔者就介绍一下在VB 中实现串口通讯的方法。

在Visual Basic中有一个名为Microsoft Communication Control(简称MSComm)的通讯控件。

我们只要通过对此控件的属性和事件进行相应编程操作,就可以轻松地实现串口通讯。

下面,笔者就简要地介绍一下MSComm控件的使用方法。

二、MSComm控件的主要属性、事件1、MSComm的属性由于MSComm控件属性很多,在此笔者仅介绍与实现串口通讯密切相关的核心属性。

Commport:设置通讯所占用的串口号。

如设成1(默认值),表示对Com1进行操作。

Setting:对串口通讯的相关参数。

包括串口通讯的比特率,奇偶校验,数据位长度、停止位等。

其默认值是“9600,N,8,1”,表示串口比特率是9600bit/s,不作奇偶校验,8位数据位,1个停止位。

用VB实现Modbus串行通讯

用VB实现Modbus串行通讯

如何用VB实现Modbus串行通讯在一些应用中可能需要使用诸如VB来进行上位机监控程序的开发,而Modbus协议是这类应用中首选的通讯协议;Modbus协议以其简单易用,在工业领域里已广泛的为其他第三方设备所支持。

这里对VB和Twido PLC间的通讯进行说明。

对于大部分应用,Twido PLC作为从站,它不需要编制通讯程序,只要把通讯口的参数设置好即可,例如下图表示此Twido通过编程口和上位机连接,其站号地址为2;波特率、数据位、校验、停止位和上位机设置保持一致。

VB程序通过利用MSComm控件很容易就能够实现。

1.通讯口初始化:MSComm1.Settings = "9600,n,8,1"mPort = 1MSComm1.SThreshold = 0If Not MSComm1.PortOpen Then MSComm1.PortOpen = True2.CRC校验码的计算方法,如以下函数,可以得到字节数组变量cmdstring指向的字符串的CRC校验码。

Function crc16_1(ByRef cmdstring() As Byte, ByVal j As Integer)Dim data As IntegerDim i As IntegerAddressreg_crc = &HFFFFFor i = 0 To jAddressreg_crc = Addressreg_crc Xor cmdstring(i)For j = 0 To 7data = Addressreg_crc And &H1If data ThenAddressreg_crc = Int(Addressreg_crc / 2)Addressreg_crc = Addressreg_crc And &H7FFFAddressreg_crc = Addressreg_crc Xor &HA001ElseAddressreg_crc = Addressreg_crc / 2Addressreg_crc = Addressreg_crc And &H7FFFEnd IfNext jNext iIf Addressreg_crc < 0 ThenAddressreg_crc = Addressreg_crc - &HFFFF0000End IfHiByte = Addressreg_crc And &HFFLoByte = (Addressreg_crc And &HFF00) / &H100End Function3.读多个字的命令(本例是从2号站读%MW10起始的4个字):Dim SendStr(7) As ByteDim RcvStr() As ByteSendStr(0) = 2 ,从站号是2SendStr(1) = &H3 ,读多个字的命令代码SendStr(2) = 0 ,起始地址高字节SendStr(3) = 10,起始地址低字节SendStr(4) = &H0,数据长度高字节SendStr(5) = 4 ,数据长度低字节Call crc16(SendStr(), 5) ,CRC计算SendStr(6) = HiByteSendStr(7) = LoByte,读命令发送后,当接收5 + SendStr(5) * 2 个字节时产生中断CmdLenth = 5 + SendStr(5) * 2MSComm1.RThreshold = CmdLenthMSComm1.Output = SendStr ,发送命令4.写多个字的命令(本例是写2号站%MW20起始的3个字):Dim WriteStr() As Bytek = 6 ,写6个字节ReDim WriteStr(8 + k)WriteStr(0) = 2 ,从站号是2WriteStr(1) = &H10 ,写多个字的命令代码WriteStr(2) = 0 ,起始地址高字节WriteStr(3) = 20 ,起始地址低字节WriteStr(4) = &H0 ,数据长度高字节<字的个数> WriteStr(5) = k / 2 ,数据长度低字节<字的个数>WriteStr(6) = k ,数据长度<字节的个数> WriteStr(7) = &H12,写的第1个字的高字节WriteStr(8) = &H34,写的第1个字的低字节WriteStr(9) = &H56,写的第2个字的高字节WriteStr(10) = &H78,写的第2个字的低字节WriteStr(11) = &H9A,写的第3个字的高字节WriteStr(12) = &HBC,写的第3个字的低字节Call crc16(WriteStr(), 6 + k)WriteStr(9 + (k / 2 - 1) * 2) = HiByteWriteStr(10 + (k / 2 - 1) * 2) = LoByteMSComm1.InBufferCount = 0MSComm1.Output = WriteStr,写命令发送后,当接收到8个字节时中断CmdLenth = 8MSComm1.RThreshold = CmdLenth5.通讯事件中断产生时的数据处理:Private Sub MSComm1_OnComm()Dim inx() As ByteSelect Case mEventCase comEvReceive ,判断为接收事件MSComm1.InputLen = CmdLenth ,接收数据的长度inx = MSComm1.Input ,接收数据MSComm1.InBufferCount = 0For k = 3 To CmdLenth - 3tmpstr = tmpstr & "/" & Hex(inx(k))NextText1.Text = tmpstr ,以十六进制显示所接收长度的数据BeepEnd SelectEnd Sub。

modbus与plc通讯 vb程序caoxi

modbus与plc通讯 vb程序caoxi

该程序可以实现实时数据采集显示,以及能对寄存器进行设置。

程序很简单,想用的可以完善,现在只能实时采集显示一个地址的数据,只要修改一下,就可以实时采集多个地址的数据。

现在也只能一次对一个寄存器进行设置,也可以更加完善。

下面是运行界面,采集的模块的地址为75,是一个温湿度采集模块。

有3个寄存器,显示的数据上是温度,湿度,露点温度。

modbusPrivate Sub Command1_Click() '设置按钮Dim bisend() As ByteDim crcDim btLoCRC As Byte, btHiCRC As ByteDim Data As IntegerIf MSComm1.PortOpen = True ThenIf Combo5.ListIndex = 0 ThenReDim bisend(7) '重新定义数组长度bisend(0) = "&h" + Hex(V al(Text1.Text)) '地址码bisend(1) = "&h" + Hex(3) '功能码读寄存器bisend(2) = "&h" + Hex(0) '起始地址高位bisend(3) = "&h" + Hex(0) '起始地址低位bisend(4) = "&h" + Hex(0) '寄存器个数高位bisend(5) = "&h" + Hex(Combo6.ListIndex + 1) '寄存器个数低位crc = CRC16(bisend, 6, btLoCRC, btHiCRC)bisend(6) = "&h" + Hex(btLoCRC) 'CRC高位bisend(7) = "&h" + Hex(btHiCRC) 'CRC低位'发送数据MSComm1.Output = bisendElseReDim bisend(10) '一次只能写一个寄存器bisend(0) = "&h" + Hex(V al(Text1.Text)) '地址码bisend(1) = "&h" + Hex(16) '功能码写寄存器bisend(2) = "&h" + Hex(0) '起始地址高位bisend(3) = "&h" + Hex(0) '起始地址低位bisend(4) = "&h" + Hex(0) '寄存器个数高位bisend(5) = "&h" + Hex(1) '寄存器个数低位bisend(6) = "&h" + Hex(2) '字节数Data = Val(Trim(Text3.Text))bisend(7) = "&h" + Hex(Data \ 256) '要写入寄存器的值的高字节bisend(8) = "&h" + Hex(Data Mod 256) '要写入寄存器的值的低字节crc = CRC16(bisend, 9, btLoCRC, btHiCRC)bisend(9) = "&h" + Hex(btLoCRC) 'CRC高位bisend(10) = "&h" + Hex(btHiCRC) 'CRC低位MSComm1.Output = bisendEnd IfElseMsgBox "串口没有打开"End IfEnd SubPrivate Sub Command2_Click() '实时采集按钮Timer1.Enabled = Not Timer1.Enabled '进行状态切换End SubPrivate Sub Command3_Click()'初始化,并打开串口With MSComm1If .PortOpen = False Then.CommPort = Combo7.ListIndex + 1 '打开串口1.Settings = Combo1.Text + "," + Combo2.Text + "," + Combo3.Text + Combo4.Text.InputMode = 1.InputLen = 50 '一次性从接收缓冲区中读取所有数据(8个字节为一组!!).InBufferCount = 0 '清空接收缓冲区.OutBufferCount = 0 '清空发送缓冲区.RThreshold = 5 + (Combo6.ListIndex + 1) * 2.InBufferSize = 1024.OutBufferSize = 1024.PortOpen = TrueElseMsgBox "串口已经打开"End IfEnd WithEnd SubPrivate Sub Command4_Click() '关闭串口按钮If MSComm1.PortOpen = True ThenMSComm1.PortOpen = FalseEnd IfEnd SubPrivate Sub Form_Load()Dim i As Integer'波特率设置Combo1.AddItem "4800", 0 Combo1.AddItem "9600", 1 Combo1.AddItem "115200", 2'校验位设置Combo2.AddItem "N", 0Combo2.AddItem "E", 1Combo2.AddItem "O", 2'数据位设置Combo3.AddItem "7", 0Combo3.AddItem "8", 1'停止位设置Combo4.AddItem "1", 0Combo4.AddItem "2", 1'功能码选择Combo5.AddItem "读寄存器03", 0 Combo5.AddItem "写寄存器16", 1'寄存器个数设置Combo6.AddItem "1", 0Combo6.AddItem "2", 1Combo6.AddItem "3", 2Combo6.AddItem "4", 3Combo6.AddItem "5", 4 Combo6.AddItem "6", 5Combo6.AddItem "7", 6Combo6.AddItem "8", 7Combo6.AddItem "9", 8Combo6.AddItem "10", 9 Combo6.AddItem "11", 10 Combo6.AddItem "12", 11 Combo6.AddItem "13", 12 Combo6.AddItem "14", 13Combo6.AddItem "15", 14Combo6.AddItem "16", 15Combo6.AddItem "17", 16Combo6.AddItem "18", 17Combo6.AddItem "19", 18Combo6.AddItem "20", 19Combo6.AddItem "21", 20Combo6.AddItem "22", 21'串口选择Combo7.AddItem "串口1", 0Combo7.AddItem "串口2", 1Combo7.AddItem "串口3", 2Combo7.AddItem "串口4", 3'初始赋值Combo1.ListIndex = 1Combo2.ListIndex = 1Combo3.ListIndex = 1Combo4.ListIndex = 0Combo5.ListIndex = 0Combo6.ListIndex = 2Combo7.ListIndex = 0'初始化串口End SubPrivate Sub Form_Unload(Cancel As Integer)If MSComm1.PortOpen = True ThenMSComm1.PortOpen = FalseEnd IfEnd SubPrivate Sub MSComm1_OnComm()Dim INByte() As ByteDim Buf As StringDim btLoCRC As Byte, btHiCRC As ByteDim Data As IntegerIf mEvent = comEvReceive Then '接收到数据以后INByte = MSComm1.InputIf INByte(1) = 3 Then '读寄存器'CRC校验crc = CRC16(INByte, UBound(INByte) - LBound(INByte) - 1, btLoCRC, btHiCRC)If INByte(UBound(INByte) - 1) = btLoCRC And INByte(UBound(INByte)) = btHiCRC Then'校验正确'////////////////////////////////////For i = 3 To UBound(INByte) - 2 Step 2Data = "&h" + Hex(INByte(i)) + Hex(INByte(i + 1))' Buf = Buf + Hex(INByte(i)) + Chr(32)Buf = Buf + Str(Data) '转换为十进制显示Next iList1.AddItem BufEnd IfEnd IfMSComm1.InBufferCount = 0 '请缓存End IfEnd SubPrivate Sub Timer1_Timer()'定时发送命令Dim tbisend(7) As ByteDim crc '定时1sDim btLoCRC As Byte, btHiCRC As ByteDim Buf As StringIf MSComm1.PortOpen = True Thentbisend(0) = "&h" + Hex(Val(Text1.Text)) '地址码tbisend(1) = "&h" + Hex(3) '功能码读寄存器tbisend(2) = "&h" + Hex(0) '起始地址高位tbisend(3) = "&h" + Hex(0) '起始地址低位tbisend(4) = "&h" + Hex(0) '寄存器个数高位tbisend(5) = "&h" + Hex(Combo6.ListIndex + 1) '寄存器个数低位crc = CRC16(tbisend, 6, btLoCRC, btHiCRC)tbisend(6) = "&h" + Hex(btLoCRC) 'CRC高位tbisend(7) = "&h" + Hex(btHiCRC) 'CRC低位'发送数据MSComm1.Output = tbisendEnd IfEnd Sub////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////Function CRC16(Data() As Byte, no As Integer, CRC16Lo As Byte, CRC16Hi As Byte) As String Dim CL As Byte, CH As Byte '多项式码&HA001Dim SaveHi As Byte, SaveLo As ByteDim i As IntegerDim Flag As IntegerCRC16Lo = &HFFCRC16Hi = &HFFCL = &H1CH = &HA0For i = 0 To no - 1CRC16Lo = CRC16Lo Xor Data(i) '每一个数据与CRC寄存器进行异或For Flag = 0 To 7SaveHi = CRC16HiSaveLo = CRC16LoCRC16Hi = CRC16Hi \ 2 '高位右移一位CRC16Lo = CRC16Lo \ 2 '低位右移一位If ((SaveHi And &H1) = &H1) Then '如果高位字节最后一位为1CRC16Lo = CRC16Lo Or &H80 '则低位字节右移后前面补1End If '否则自动补0If ((SaveLo And &H1) = &H1) Then '如果LSB为1,则与多项式码进行异或CRC16Hi = CRC16Hi Xor CHCRC16Lo = CRC16Lo Xor CLEnd IfNext FlagNext iDim ReturnData(1) As ByteReturnData(0) = CRC16Hi 'CRC高位ReturnData(1) = CRC16Lo 'CRC低位CRC16 = ReturnDataEnd Function'CRC低位字节值表Function GetCRCLo(ind As Long) As ByteGetCRCLo = Choose(ind + 1, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, _&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, &HC1, &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, &H81, &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 ByteGetCRCHi = 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, &O33, &;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。

用VB写的modbusrtu模式通讯源码

用VB写的modbusrtu模式通讯源码

用VB写的modbusrtu模式通讯源码‘用VB 写的modbus rtu模式通讯源码,已在台达PLC上调试通过Private Sub CmdOpen_Click()On Error Resume NextIf (MSComm1.PortOpen) Then ‘打开/关闭串口MSComm1.PortOpen = FalseElseMSComm1.PortOpen = TrueEnd IfIf (MSComm1.PortOpen) ThenCmdOpen.Caption = "关闭串口"Shape5.FillStyle = vbFSSolidElseCmdOpen.Caption = "打开串口"Shape5.FillStyle = vbFSTransparentEnd IfIf Err ThenMsgBox Error$, 48, "错误码信息"Exit SubEnd IfEnd SubPrivate Sub Combo1_Click()/doc/df18763589.html,mPort = Combo1.ListIndex + 1End SubPrivate Sub Combo2_Click()Call SettingEnd SubPrivate Sub Combo3_Click()Call SettingEnd SubPrivate Sub Combo4_Click()Call SettingEnd SubPrivate Sub Combo5_Click()Call SettingEnd SubPrivate Sub Command1_Click()‘S hape1.FillStyle = vbFSSolidDim Y0_status As ByteDim Sendstr As StringDim i As Integer, j As IntegerSendstr = "01 01 05 00 00 10 "HexSend (Sendstr)Sleep (30)HexSend (Sendstr)End SubPrivate Function HexSend(Sendstr As String) As Integer Dim outbuf() As ByteDim Temp(0) As ByteDim crc As String, Sendstrls As StringDim sendlen As IntegerDim i As Integer, j As IntegerIf Sendstr = "" ThenMsgBox "发送数据不能为空!"HexSend = 0Exit FunctionEnd IfS endstrls = Trim(Sendstr) ‘去掉空格sendlen = Len(Sendstrls) + 1 ‘取长度j = 0ReDim outbuf(1 To sendlen \ 3) As ByteFor i = 1 To sendlen Step 3j = j + 1outbuf(j) = Val("&H" & CStr(Mid(Sendstrls, i, 2)))Next icrc = Crc16(outbuf)ReDim Preserve outbuf(1 T o (sendlen \ 3 + 2)) As Byte ‘加上CRC校验码outbuf(sendlen \ 3 + 1) = Val("&H" & CStr(Mid(crc, 1, 2)))outbuf(sendlen \ 3 + 2) = Val("&H" & CStr(Mid(crc, 3, 2)))For i = 1 To (sendlen \ 3 + 2)Temp(0) = outbuf(i)MSComm1.Output = TempNext iFor i = 1 To 2000Next iHexSend = 1End FunctionPrivate Function Setting()MSComm1.Settings = CStr(Combo2.Text) & "," & CStr(Combo3.Text) & "," & CStr(Combo4.Text) & "," & CStr(Combo5.Text) End FunctionPrivate Sub Command2_Click()‘If (MSComm1.RThreshold = 0) Then‘MSComm1.RTh reshold = 1‘Else‘MSComm1.RThreshold = 0‘End IfLabel11.Caption = "接收个数:" & CStr(ReceCount) & " " & "接收帧数:" & CStr(Framecount) End SubPrivate Sub Form_Load()Combo1.AddItem ("COM1")Combo1.AddItem ("COM2")Combo1.AddItem ("COM3")Combo1.AddItem ("COM4")Combo1.AddItem ("COM5")Combo1.ListIndex = 0Combo2.AddItem ("2400")Combo2.AddItem ("4800")Combo2.AddItem ("9600")Combo2.AddItem ("11520")Combo2.ListIndex = 0Combo3.AddItem ("E")Combo3.AddItem ("O")Combo3.AddItem ("N")Combo3.ListIndex = 2Combo4.AddItem ("6")Combo4.AddItem ("7")Combo4.AddItem ("8")Combo4.ListIndex = 2Combo5.AddItem ("1")Combo5.AddItem ("2")Combo5.ListIndex = 0ReceCount = 0End SubPrivate Function Crc16(data() As Byte) As StringDim CRC16Lo As Byte, CRC16Hi As Byte ‘CRC寄存器Dim CL As Byte, CH As Byte ‘多项式码&HA001Dim CrcLo As String, CrcHi As StringDim SaveHi As Byte, SaveLo As ByteDim i As IntegerDim Flag As IntegerCRC16Lo = &HFFCRC16Hi = &HFFCL = &H1CH = &HA0For i = 1 To UBound(data)CRC16Lo = CRC16Lo Xor data(i) ‘每一个数据与CRC寄存器进行异或For Flag = 0 To 7SaveHi = CRC16HiSaveLo = CRC16LoCRC16Hi = CRC16Hi \ 2 ‘高位右移一位CRC16Lo = CRC16Lo \ 2 ‘低位右移一位If ((SaveHi And &H1) = &H1) Then ‘如果高位字节最后一位为1CRC16Lo = CRC16Lo Or &H80 ‘则低位字节右移后前面补1 End If ‘否则自动补0If ((SaveLo And &H1) = &H1) Then ‘如果LSB为1,则与多项式码进行异或CRC16Hi = CRC16Hi Xor CHCRC16Lo = CRC16Lo Xor CLEnd IfNext FlagNext iIf Len(Hex(CRC16Hi)) = 1 ThenCrcHi = "0" + Hex(CRC16Hi)ElseCrcHi = Hex(CRC16Hi)End IfIf Len(Hex(CRC16Lo)) = 1 ThenCrcLo = "0" + Hex(CRC16Lo)ElseCrcLo = Hex(CRC16Lo)End IfCrc16 = CrcLo & CrcHiEnd FunctionPrivate Sub MSComm1_OnComm()Dim inpu() As ByteDim i As IntegerDim tempstr As String, Strdata As StringSelect Case /doc/df18763589.html,mEvent Case comEvReceive ‘接收事件tempstr = MSComm1.Inputinpu() = tempstrFramecount = Framecount + 1 ‘帧个数加1If (Framecount = 1) Thenframepoint(Framecount) = UBound(inpu) + 1 ‘第一帧帧尾Elseframepoint(Framecount) = framepoint(Framecount - 1) + UBound(inpu) + 1 ‘第二帧开始指针End IfFor i = 0 To UB ound(inpu) ‘将字符转换为数组If (Len(Hex(inpu(i))) = 1) ThenStrdata = Strdata & "0" & Hex(inpu(i)) & " "ElseStrdata = Strdata & Hex(inpu(i)) & " "End IfNext iFor i = ReceCount + 1 To UBound(inpu) + 1 ‘数据进入缓冲区Recebuf(i) = inpu(i - 1)NextReceCount = ReceCount + UBound(inpu) + 1TextReceive.Text = TextReceive.Text & StrdataStrdata = ""Case comEvSendEnd SelectEnd SubPrivate Function RtuCheck(data() As Byte) As IntegerDim CrcHi As Byte, CrcLo As ByteDim Checkdata() As ByteDim i As IntegerDim crc As StringCrcHi = data(UBound(data))CrcLo = data(UBound(data) - 1)ReDim Checkdata(1 To (UBound(data) - 1)) As ByteFor i = 1 To (UBound(data) - 1) ‘附值Checkdata(i) = data(i - 1)Nextcrc = Crc16(Checkdata)If (CrcLo = Val("&H" & CStr(Mid(crc, 1, 2))) And CrcHi = Val("&H" & CStr(Mid(crc, 3, 2)))) Then RtuCheck = 1ElseRtuCheck = 0End IfEnd Function。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

V B控件M s c o m m控件与P L C进行R S M o d b u s通讯源码集团企业公司编码:(LL3698-KKI1269-TM2483-LUI12689-ITT289-V B控件M s c o m m控件与P L C进行R S485(M o d b u s)通讯源码本人用的是ModbusRTU通讯模式,通过计算机串口转RS485与外围设备通行通讯,读写外围设备指定地址里的数据,从而达到自动化控制远端设备。

DimHiByteAsByteDimLoByteAsByteDimCRC16LoAsByteDimCRC16HiAsByteDimReturnData(1)AsByteDimKAsIntegerDimCmdLenthAsIntegerPrivateSubCommand1_Click()K=Text9.Text'写6个字节Text13.Text=""'===========数组赋值输入代码=============================================================== ========================'<<算法一>>DimWriteStr()AsByteDimuAsIntegerReDimWriteStr(K+2)Foru=0ToKWriteStr(u)=Val("&H"&Text1(u).Text)Next'<<算法二>>DimCRC_2()AsByteDimvAsIntegerReDimCRC_2(K)Forv=0ToKCRC_2(v)=Val("&H"&Text1(v).Text)Next'============================================================== ====================================CallCRC161(CRC_2())CallCRC16(WriteStr(),K)MSComm1.InBufferCount=0'==========显示发送代码=============================================================== =========================DimmAsIntegerForm=0To23Ifm<=KThenText8(m).Text=Hex(WriteStr(m))ElseText8(m).Text=""EndIfNext'============================================================== ====================================WriteStr(K+1)=LoByteWriteStr(K+2)=HiByte'发送代码Text4.Text=""DimgAsIntegerForg=0ToK+2Text4.Text=Text4.Text+""+Hex(WriteStr(g))Next'写命令发送后,当接收到8个字节时中断CmdLenth=8MSComm1.RThreshold=CmdLenthMSComm1.Output=WriteStrEndSubPrivateSubCommand2_Click()EndEndSubPrivateSubCommand3_Click()Label34.Caption="="Text13.Text=""K=Text9.Text'写6个字节'===========数组赋值输入代码=============================================================== ========================'<<算法>>DimCRC_2()AsByteDimvAsIntegerReDimCRC_2(K)Forv=0ToKCRC_2(v)=Val("&H"&Text1(v).Text)Next'============================================================== ====================================CallCRC161(CRC_2())CallCRC16(WriteStr(),K)MSComm1.InBufferCount=0'==========显示发送代码=============================================================== =========================DimmAsIntegerForm=0To23Ifm<=KThenText8(m).Text=Hex(WriteStr(m))ElseText8(m).Text=""EndIfNext'============================================================== ====================================WriteStr(K+1)=LoByteWriteStr(K+2)=HiByte'发送代码Text4.Text=""DimgAsIntegerForg=0ToK+2Text4.Text=Text4.Text+""+Hex(WriteStr(g))Next'读命令发送后,当接收5+SendStr(5)*2个字节时产生中断CmdLenth=5+WriteStr(5)*2MSComm1.RThreshold=CmdLenthMSComm1.Output=WriteStr'发送命令'************************************************************** *************************************************************** ***********'************************************************************** *****************************************************'************************************************************** *************************************************************** ***********'DimsAddrAsString''DimCheckStringAsString'DimCheckCodeAsString'DimCmdCodeAsString'DimSumAsInteger'DimaAsInteger'DimtmpAsString'a=0'tmp=0''''DoWhileLen(tmp)<8''tmp=tmp+MSComm1.Input'testNO.Caption=testNO.Caption+""+Str(Hex(Asc(tmp)))'a=a+1'Ifa>=3000Then'MSComm1.PortOpen=False'ExitFunction'ExitDo'EndIf'Loop'Label33.Caption=tmp'Text16.Text=Len(tmp)'DimnsAsInteger'Forns=1ToLen(tmp)'Label34.Caption=Label34.Caption+"+"+Str(Asc(Mid(tmp,ns,1))) ''Next'Label35.Caption=Str(Val(Asc(Mid(tmp,6,1)))/10)'''tmp=Mid$(tmp,6,4)'''DimstrHexAsString'DimHex2DecAsLong'DimstrTmpAsString'DimlongTmpAsLong'DimlongDecAsLong'DimintLenAsInteger'Dimn1AsInteger''strHex=Right$(tmp,2)+Left$(tmp,2) ''intLen=Len(strHex)'Forn1=1TointLen'strTmp=Mid(strHex,n1,1)'SelectCaseAsc(strTmp)'Case48To57'longTmp=Val(strTmp)'Case65To70'longTmp=Asc(strTmp)-55'CaseElse'Hex2Dec=0''ExitFunction'EndSelect'Text13.Text=Text13.Text+"+"+Str(Asc(strTmp))'longDec=longDec+longTmp*16^(intLen-n1)'Nextn1''Hex2Dec=longDec'Text13.Text=Hex2Dec'************************************************************** *************************************************************** ***********'************************************************************** *****************************************************'************************************************************** *************************************************************** ***********EndSubPrivateSubMSComm1_OnComm()DimNeAsIntegermEventCasecomEvReceiveDimBufferAsVariantMSComm1.InputMode=comInputModeBinaryMSComm1.InputLen=0Buffer=MSComm1.InputForNe=LBound(Buffer)ToUBound(Buffer)Text13.Text=Text13.Text&"+"&Buffer(Ne)Label34.Caption=Buffer(3)&""&Buffer(4)NextNeCaseElseEndSelectBeepEndSubPrivateSubCommand4_Click()EndSubPrivateSubCommand5_Click()Label34.Caption="="EndSubPrivateSubForm_Load()MSComm1.Settings="9600,N,8,1"mPort=1MSComm1.SThreshold=0IfNotMSComm1.PortOpenThenMSComm1.PortOpen=True EndSubPrivateSubTimer1_Timer()'显示<<算法一>>结果Text2.Text=Hex(HiByte)Text3.Text=Hex(LoByte)'显示<<算法二>>结果Text6.Text=Hex(CRC16Hi)Text7.Text=Hex(CRC16Lo)IfText5.Text<>""Then'十进制转十六进制Text10.Text=Hex(Text5.Text)EndIfIfText11.Text<>""Then'十六进制转十进制Text12.Text=Val("&H"&Text11.Text)EndIfText14.Text=MSComm1.OutBufferCountEndSub'==========CRC校验<<算法二>>=========================================================== =============================FunctionCRC161(data()AsByte)AsString'CRC计算函数'DimCRC16LoAsByte,CRC16HiAsByte'CRC寄存器DimCLAsByte,CHAsByte'多项式码&HA001DimSaveHiAsByte,SaveLoAsByteDimIAsIntegerDimFlagAsIntegerCRC16Lo=&HFFCRC16Hi=&HFFCL=&H1CH=&HA0ForI=0ToUBound(data)CRC16Lo=CRC16LoXordata(I)'每一个数据与CRC寄存器进行异或ForFlag=0To7CRC16Hi=CRC16Hi\2'高位右移一位CRC16Lo=CRC16Lo\2'低位右移一位If((SaveHiAnd&H1)=&H1)Then'如果高位字节最后一位为1CRC16Lo=CRC16LoOr&H80'则低位字节右移后前面补1EndIf'否则自动补0If((SaveLoAnd&H1)=&H1)Then'如果LSB为1,则与多项式码进行异或CRC16Hi=CRC16HiXorCHCRC16Lo=CRC16LoXorCLEndIfNextFlagNextIDimReturnData(1)AsByteReturnData(0)=CRC16Hi'CRC高位ReturnData(1)=CRC16Lo'CRC低位asd=Right("00"+Hex(CRC16Lo),2)+Right("00"+Hex(CRC16Hi),2) EndFunctionPrivateSubmscomm_OnComm()EndSub。

相关文档
最新文档