300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > VB.net写一个简易串口RS485调试助手

VB.net写一个简易串口RS485调试助手

时间:2019-11-09 07:40:46

相关推荐

VB.net写一个简易串口RS485调试助手

最近在调试带rs485串口通讯的设备,项目上主要是用PLC和串口通讯,因为PLC有集成好的串口块,使用起来比较容易,为了方便测试,就想着用上位机写一个简易的串口通讯程序,用于调试。

在网上查找了一些资料后,基本上选择了两个方式,和python,python来写串口通讯程序,我在另一篇博客里面已经发了:

/normer123456/article/details/124402399

本文中介绍一下使用来写串口程序的示例。

图片是UI界面,相对来说,界面比python要友好一点,控件可以直接拖放到窗体,而python制作界面,需要利用pyqt这类UI模块,有点麻烦。

软件:Microsoft Visual Studio Community 版本 16.11.3

硬件:windows10电脑

rs485串口设备(流量计)

串口通讯在逻辑步骤上,基本上差不多,无非是初始化参数,打开串口,读写数据,关闭串口,就不多赘述了。

直接看程序吧。

01 初始化:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.LoadDim baud_installs() As String = New String() _{"9600", "19200", "38400", "115200"}baudcombox.Items.AddRange(baud_installs)baudcombox.Text = baudcombox.Items(0)databitcombox.Items.AddRange({"8", "7"})databitcombox.Text = databitcombox.Items(0)stopbitcombox.Items.AddRange({"0", "1"})stopbitcombox.Text = stopbitcombox.Items(0)paritycombox.Items.AddRange({"无", "偶校验", "奇校验"})paritycombox.Text = paritycombox.Items(0)ToolStripStatusLabel1.Text = "当前无可用串口。。。"huayuan(PictureBox1, Color.Gray)End Sub

这里参数利用combox控件来进行选择,根据所选择不同,传入不同的值来进行初始化,所以,程序启动后,必须先设置参数值,然后才能点击“打开按钮,否则会提示错误。

02 打开串口:

Private Sub portopen()TrySerialPort1.Open()Call portstart()If SerialPort1.IsOpen ThenToolStripStatusLabel1.Text = SerialPort1.PortName + "已打开"ToolStripStatusLabel1.ForeColor = Color.Greenhuayuan(PictureBox1, Color.Green)Console.WriteLine(SerialPort1.PortName)Console.WriteLine("ok!")End IfCatch ex As UnauthorizedAccessExceptionMsgBox("串口被占用或串口错误!", MsgBoxStyle.Information, "tips!")End TryEnd Sub

打开串口就是serial.open即可。

03 写入数据:

Private Sub comsend()Dim senddata As StringDim senddata_byte(8) As Byte'datestr = Format(Now(), "yyyy/MM/dd H:mm:ss ffff")datestr = Format(Now(), "yyyy/MM/dd H:mm:ss")'TextBox1.Clear()'senddata_byte(0) = &H1 '一种表示16进制数的方式'senddata_byte(1) = &H3'senddata_byte(2) = &H0'senddata_byte(3) = &H10'senddata_byte(4) = &H0'senddata_byte(5) = &H2'senddata_byte(6) = &HC5'senddata_byte(7) = &HCEsenddata_byte = strtohex(TextBox1.Text)senddata = ""TrySerialPort1.Write(senddata_byte, 0, 8)TextBox1.AppendText(senddata)TextBox2.AppendText(vbCrLf + "[" + datestr + "]" + " " + senddata + vbCrLf)comrec()Console.WriteLine("send ok!")Catch ex As ExceptionMsgBox(ex.Message, MsgBoxStyle.YesNoCancel, "tips!")End TryEnd Sub

写入数据或者说发送数据,就是serial.write,这里需要注意的是,发送的数据是字节数组形式,因此,需要进行字符串到字节的转换。

关于字符串和字节数组之间的互相转换,我在测试的时候,在网上找了不少资料,许多博客虽然写了,但大多是抄来的,或者就是不够实用,很多人是利用字符转成ASCII码,在对应转16进制,程序比较麻烦。

然后我找了半天,发现一个利用正则表达式来进行转换的, 比较简单有效,感谢网络。

string to byte 转换程序:

Private Function strtohex(s As String) '将字符串转成16进制数值Dim mc As MatchCollection = Regex.Matches(s, "(?i)[\da-f]{2}") '使用正则表达式从输入文本框的字符串中提取16进制数Dim buf As New List(Of Byte)()Dim bt As Byte()For Each m As Match In mcbuf.Add(Byte.Parse(m.Value, System.Globalization.NumberStyles.HexNumber))Nextbt = buf.ToArray()Return bt'Console.WriteLine(bt)End Function

至于16进制转字符串比较简单, 有个Hex函数直接就可以转换,不多说了。

04 读取数据:

Private Sub comrec()Dim rxstr As IntegerDim recstr As StringDim recbyte(20) As Bytedatestr = Format(Now(), "yyyy/MM/dd H:mm:ss")Tryrxstr = SerialPort1.Read(recbyte, 0, 10)For i = 0 To rxstr - 1recstr = recstr + hextostr(recbyte(i)) + " "NextTextBox2.AppendText(vbCrLf + "[" + datestr + "]" + " " + recstr + vbCrLf)Console.WriteLine(recstr)Application.DoEvents()'TextBox1.AppendText(recstr)Catch ex As ExceptionMsgBox(ex.Message + "or 无可用串口", MsgBoxStyle.YesNo, "tips!")'rxstr = SerialPort1.ReadExisting'TextBox1.AppendText(vbCrLf + "[" + datestr + "]" + " " + rxstr + vbCrLf)'Application.DoEvents()End TryEnd Sub

读取就是使用serial.read,或者readall、readline都行。read的话,需要设置缓冲区、偏移量、接收长度,比较简单。

读写完成后,如果不想一直读写。可以关闭串口:

Private Sub portclose()TryIf SerialPort1.IsOpen ThenSerialPort1.Close()If SerialPort1.IsOpen = 0 ThenToolStripStatusLabel1.Text = SerialPort1.PortName + "已关闭"ToolStripStatusLabel1.ForeColor = Color.Redhuayuan(PictureBox1, Color.Gray)End IfElseMsgBox("无可用串口", MsgBoxStyle.Information, "tips!")End IfCatch ex As ExceptionMsgBox("串口未打开或串口异常!", MsgBoxStyle.Information, "tips!")End TryEnd Sub

serial.close即可。

关于程序的一些细节,我这边就不多说了,基本上都是在网上找了很多资料,然后自己一点点试出来的,网上虽然有很多资料,但很少有直接拿过来能用的,想要满足自己使用,还是得自己摸索半天。我把完整程序也发出来,需要说明的是,程序是经过我测试,完全可用的,但我不确定如果有朋友想直接使用,是否是和我一样的。

完整程序:

Imports System.TextImports System.Text.RegularExpressionsImports Public Class Form1Dim ser_br As IntegerDim ser_db As IntegerDim ser_stopbit As IntegerDim ser_parity As IntegerDim datestr As String = ""Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.LoadDim baud_installs() As String = New String() _{"9600", "19200", "38400", "115200"}baudcombox.Items.AddRange(baud_installs)baudcombox.Text = baudcombox.Items(0)databitcombox.Items.AddRange({"8", "7"})databitcombox.Text = databitcombox.Items(0)stopbitcombox.Items.AddRange({"0", "1"})stopbitcombox.Text = stopbitcombox.Items(0)paritycombox.Items.AddRange({"无", "偶校验", "奇校验"})paritycombox.Text = paritycombox.Items(0)ToolStripStatusLabel1.Text = "当前无可用串口。。。"huayuan(PictureBox1, Color.Gray)End SubPrivate Sub portstart()SerialPort1.BaudRate = ser_brSerialPort1.DataBits = ser_dbSerialPort1.StopBits = ser_stopbitSerialPort1.Parity = ser_paritySerialPort1.ReadTimeout = 1000SerialPort1.NewLine = vbCrLfEnd SubPrivate Sub getserialportname()For Each sp As String In puter.Ports.SerialPortNamesComboBox1.Items.Add(sp)NextComboBox1.Text = ComboBox1.Items(0)'Console.WriteLine(ComboBox1.Text)End SubPrivate Sub portopen()TrySerialPort1.Open()Call portstart()If SerialPort1.IsOpen ThenToolStripStatusLabel1.Text = SerialPort1.PortName + "已打开"ToolStripStatusLabel1.ForeColor = Color.Greenhuayuan(PictureBox1, Color.Green)Console.WriteLine(SerialPort1.PortName)Console.WriteLine("ok!")End IfCatch ex As UnauthorizedAccessExceptionMsgBox("串口被占用或串口错误!", MsgBoxStyle.Information, "tips!")End TryEnd SubPrivate Sub portclose()TryIf SerialPort1.IsOpen ThenSerialPort1.Close()If SerialPort1.IsOpen = 0 ThenToolStripStatusLabel1.Text = SerialPort1.PortName + "已关闭"ToolStripStatusLabel1.ForeColor = Color.Redhuayuan(PictureBox1, Color.Gray)End IfElseMsgBox("无可用串口", MsgBoxStyle.Information, "tips!")End IfCatch ex As ExceptionMsgBox("串口未打开或串口异常!", MsgBoxStyle.Information, "tips!")End TryEnd SubPrivate Sub comrec()Dim rxstr As IntegerDim recstr As StringDim recbyte(20) As Bytedatestr = Format(Now(), "yyyy/MM/dd H:mm:ss")Tryrxstr = SerialPort1.Read(recbyte, 0, 10)For i = 0 To rxstr - 1recstr = recstr + hextostr(recbyte(i)) + " "NextTextBox2.AppendText(vbCrLf + "[" + datestr + "]" + " " + recstr + vbCrLf)Console.WriteLine(recstr)Application.DoEvents()'TextBox1.AppendText(recstr)Catch ex As ExceptionMsgBox(ex.Message + "or 无可用串口", MsgBoxStyle.YesNo, "tips!")'rxstr = SerialPort1.ReadExisting'TextBox1.AppendText(vbCrLf + "[" + datestr + "]" + " " + rxstr + vbCrLf)'Application.DoEvents()End TryEnd SubPrivate Sub comsend()Dim senddata As StringDim senddata_byte(8) As Byte'datestr = Format(Now(), "yyyy/MM/dd H:mm:ss ffff")datestr = Format(Now(), "yyyy/MM/dd H:mm:ss")'TextBox1.Clear()'senddata_byte(0) = &H1 '一种表示16进制数的方式'senddata_byte(1) = &H3'senddata_byte(2) = &H0'senddata_byte(3) = &H10'senddata_byte(4) = &H0'senddata_byte(5) = &H2'senddata_byte(6) = &HC5'senddata_byte(7) = &HCEsenddata_byte = strtohex(TextBox1.Text)senddata = ""TrySerialPort1.Write(senddata_byte, 0, 8)TextBox1.AppendText(senddata)TextBox2.AppendText(vbCrLf + "[" + datestr + "]" + " " + senddata + vbCrLf)comrec()Console.WriteLine("send ok!")Catch ex As ExceptionMsgBox(ex.Message, MsgBoxStyle.YesNoCancel, "tips!")End TryEnd SubPrivate Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Clickgetserialportname()End SubPrivate Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.ClickTrySerialPort1.PortName = ComboBox1.SelectedItem()Console.WriteLine("you choose:" & SerialPort1.PortName)portopen()Catch ex As ExceptionMsgBox(ex.Message, MsgBoxStyle.YesNoCancel, "tips!")End TryEnd SubPrivate Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Clickportclose()End SubPrivate Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChangedToolStripStatusLabel1.Text = "当前选择串口号:" + ComboBox1.SelectedItem()'Console.WriteLine(ComboBox1.Text)End SubPrivate Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Clickcomsend()End SubPrivate Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Clickcomrec()End SubPrivate Sub paritycombox_SelectedIndexChanged(sender As Object, e As EventArgs) Handles paritycombox.SelectedIndexChangedSelect Case paritycombox.TextCase "无"ser_parity = 0Case "偶校验"ser_parity = 1Case "奇校验"ser_parity = 2End Select'Console.WriteLine(ser_parity)End SubPrivate Sub baudcombox_SelectedIndexChanged(sender As Object, e As EventArgs) Handles baudcombox.SelectedIndexChangedSelect Case baudcombox.TextCase "9600"ser_br = 9600Case "19200"ser_br = 19200Case "38400"ser_br = 38400Case "115200"ser_br = 115200End Select'Console.WriteLine(ser_br)End SubPrivate Sub databitcombox_SelectedIndexChanged(sender As Object, e As EventArgs) Handles databitcombox.SelectedIndexChangedSelect Case databitcombox.TextCase "8"ser_db = 8Case "7"ser_db = 7End SelectEnd SubPrivate Sub stopbitcombox_SelectedIndexChanged(sender As Object, e As EventArgs) Handles stopbitcombox.SelectedIndexChangedSelect Case stopbitcombox.TextCase "0"ser_stopbit = 0Case "1"ser_stopbit = 1End SelectEnd Sub''' <summary>''' 16进制转字符函数''' 本函数为自定义函数''' </summary>''' <param name="h">字节</param>Private Function hextostr(h As Byte) '将16进制数值转成字符串,且二者等效转换Dim x As StringIf h < 10 Thenx = "0" + Hex(h)Elsex = Hex(h)End IfReturn xEnd Function''' <summary>''' 字符转16进制函数''' 本函数为自定义函数''' </summary>''' <param name="s">字符串</param>Private Function strtohex(s As String) '将字符串转成16进制数值Dim mc As MatchCollection = Regex.Matches(s, "(?i)[\da-f]{2}") '使用正则表达式从输入文本框的字符串中提取16进制数Dim buf As New List(Of Byte)()Dim bt As Byte()For Each m As Match In mcbuf.Add(Byte.Parse(m.Value, System.Globalization.NumberStyles.HexNumber))Nextbt = buf.ToArray()Return bt'Console.WriteLine(bt)End Function''' <summary>''' 画圆函数''' 本函数为自定义函数''' </summary>''' <param name="pb">图形容器</param>''' <param name="c">颜色</param>Private Sub huayuan(pb As PictureBox, c As Color) '在picturebox中绘制圆形的函数Dim b As Bitmap = New Bitmap(pb.Width, pb.Height)Dim g As Graphics = Graphics.FromImage(b)Dim mybrush As New SolidBrush(c)g.FillEllipse(mybrush, 0, 0, pb.Width, pb.Height)g.Dispose()pb.Image = bEnd SubPrivate Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.ClickDim buf As Byte()Dim n As IntegerConsole.WriteLine(strtohex(TextBox1.Text))End SubEnd Class

如果有朋友有什么问题,可以评论区问,我知道的,会回复,不懂的,就没办法了。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。