搜档网
当前位置:搜档网 › SerialPort串口通信

SerialPort串口通信

Dim Afx() As Byte '待发送数据数组1
Dim Bfx() As Byte '待发送数据数组2
Dim Cfx() As Byte '待发送数据数组3
Dim Dfx() As Byte '待发送数据数组4
Dim Efx() As Byte '待发送数据数组5
Dim Ffx() As Byte '待发送数据数组6
Dim Fx() As Byte '发送数据数组
Dim Rc() As Byte '接收数据数组


'初始化串口配置
Private Sub intcom()
Try
If SerialPort1.IsOpen Then
SerialPort1.Close()
openbtn.Enabled = True
openbtn.Text = "连接"
End If
portnamebox.Items.Clear()
baudratebox.Items.Clear()
datac.Items.Clear()
stopc.Items.Clear()

'获取计算机有效串口
Dim ports As String() = SerialPort.GetPortNames() '必须用命名空间,用SerialPort,获取计算机的有效串口
Dim port As String
For Each port In ports
portnamebox.Items.Add(port) '向combobox中添加项
Next port


baudratebox.Items.Add(115200)
baudratebox.Items.Add(19200)
baudratebox.Items.Add(9600)
baudratebox.Items.Add(4800)
baudratebox.Items.Add(1200)
datac.Items.Add(8)
datac.Items.Add(7)
datac.Items.Add(6)
datac.Items.Add(5)
stopc.Items.Add(1)
stopc.Items.Add(1.5)
stopc.Items.Add(2)
'初始化界面
baudratebox.SelectedIndex() = 2
portnamebox.SelectedIndex() = 0
datac.SelectedIndex() = 0
stopc.SelectedIndex() = 0
parc.SelectedIndex() = 0

'设置串口参数
SerialPort1.BaudRate = Val(baudratebox.Text) '波特率
SerialPort1.PortName = portnamebox.Text '串口名称
SerialPort1.DataBits = Val(datac.Text) '数据位
SerialPort1.StopBits = Val(stopc.Text) '停止位
If Val(parc.Text) = 0 Then
SerialPort1.Parity = IO.Ports.Parity.None '校验位
Else
SerialPort1.Parity = Val(parc.Text) '校验位
End If
SerialPort1.ReadBufferSize = Val(bsize.Text) '缓冲区大小

Catch ex As Exception
MessageBox.Show(ex.Message, "串口设备故障")
openbtn.Enabled = False
End Try
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ’串口启动按钮
If SerialPort1.IsOpen Then
Timer2.Stop() '停止发送数据
SerialPort1.Close() ' 先判断串口是否打开,如果打开则先关闭
ToolStripStatusLabel1.Text = "STATUS:COM Port Cloced" ' 串口状

态显示
Button1.Text = "连接串口"
Else
Try
'初始化串口
SerialPort1.BaudRate = Val(ComboBox2.Text) '波特率
SerialPort1.PortName = ComboBox1.Text '串口名称
SerialPort1.DataBits = 8 '数据位
SerialPort1.StopBits = IO.Ports.StopBits.One '停止位
SerialPort1.Parity = IO.Ports.Parity.None '校验位
SerialPort1.ReadBufferSize = 1024 '缓冲区大小
SerialPort1.Open()
Button1.Text = "断开串口"
ToolStripStatusLabel1.Text = "STATUS:" + ComboBox1.Text + " Port Opened" ' 串口状态显示

'发送指令
send()

Catch ex As Exception
Timer2.Stop()
SerialPort1.Close()
Button1.Text = "连接串口"
ToolStripStatusLabel1.Text = "STATUS:" + ComboBox1.Text + "COM Port ERROR:"
End Try
End If
End Sub


'触发接收事件
Public Sub Sp_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Me.Invoke(New EventHandler(AddressOf Sp_Receiving)) '调用接收数据函数
End Sub
'接收数据(只接收16进制并比对协议版本)
Private Sub Sp_Receiving(ByVal sender As Object, ByVal e As EventArgs)
Dim temperr As String = ""
Try
Dim StrRc As String
Dim i As Integer
Dim n As Integer
n = SerialPort1.BytesToRead '读缓冲区数据量,有数据则接收
If n >= 7 Then '最小通信数据长度
ReDim Rc(n)
StrRc = ""
For i = 1 To n
Rc(i) = SerialPort1.ReadByte
If CStr(Hex(Rc(i))).Length < 2 Then
StrRc += "0" & CStr(Hex(Rc(i))) & " " '数据转为16进制显示
Else
StrRc += CStr(Hex(Rc(i))) & " " '数据转为16进制显示
End If
Next
' Threading.Thread.Sleep(200) '添加的延时
' StrRc = SerialPort1.ReadExisting.ToString '读取缓冲区中的数据
SerialPort1.DiscardInBuffer()
temperr = StrRc
ToolStripStatusLabel2.Text = " || Received:" & StrRc & "长度:" & n.ToString ' 接收数据显示
'接收数据内容:
'02 03 02 03 10 FD 78
'02 03 02 02 F1 3C A0
'04 03 02 00 EF 35 C8
'04 03 02 00 EF 35 C8
Dim a As String = StrRc.Substring(3, 2) '标志1:03
Dim b As S

tring = StrRc.Substring(6, 2) '标志2:02
Dim c As String = StrRc.Substring(0, 2) '地址
Dim d As String = StrRc.Substring(9, 2) '数值1
Dim g As String = StrRc.Substring(12, 2) '数值2
Dim f As Integer = Val("&H" & d) * 256 + Val("&H" & g)
If String.Equals(a, "03") And String.Equals(b, "02") Then '判断协议
'储存数值
Select Case Int(c)
Case 1
temNum(0) = f
Case 2
temNum(1) = f
Case 3
temNum(2) = f
Case 4
temNum(3) = f
Case 5
temNum(4) = f
Case 6
temNum(5) = f
Case Else
ToolStripStatusLabel2.Text = " || Received: Error:(" & c & ")" & StrRc ' 接收数据显示 地址码错误
End Select
Else
ToolStripStatusLabel2.Text = " || Received: Error:(" & a & "||" & b & ")" & StrRc ' 接收数据显示 协议错误
End If
End If
Catch ex As Exception
ToolStripStatusLabel2.Text = "STATUS:数据接收有误:" + temperr ' 串口状态显示
https://www.sodocs.net/doc/8f13704956.html,puter.FileSystem.WriteAllText("log.txt", Now.ToString & "数据接收有误:" & temperr & ":" & ex.Message.ToString & vbCrLf, True) '记录日志
End Try
End Sub
'接收数据(标准版本:接收16进制或者字符串)
Private Sub Sp_Receiving(ByVal sender As Object, ByVal e As EventArgs)
' Dim strIncoming As String
Dim strIncoming As Integer '读入的原始数据
Dim str1() As String '转换为16进制字符数组
Dim str2() As String '去除尾部空字符的数组
Dim i As Integer
Try
SerialPort1.ReadTimeout = CInt(ComboBox2.Text) '读取操作未完成时发生超时之前的毫秒数。
Threading.Thread.Sleep(100) '添加的延时
If SerialPort1.BytesToRead > 0 Then '接收缓冲区中有数据时执行
ReDim Rc(SerialPort1.BytesToRead)
'strIncoming = Convert.ToByte(SerialPort1.ReadByte())
If hexcheck.Checked = True Then '十六进制接收
'strIncoming = SerialPort1.ReadTo(" ") ' 一直读取到输入缓冲区中的指定 value 的字符串
' strIncoming = SerialPort1.ReadChar() '从 SerialPort 输入缓冲区中同步读取一个字符。
'strIncoming = SerialPort1.ReadByte() '从 SerialPort 输入缓冲区中同步读取一个字节
For i = 0 To SerialPort1.BytesToRead - 1
strIncoming = S

erialPort1.ReadByte() '读取缓冲区中的数据
Rc(i) = strIncoming
Next
If CheckBox2.Checked Then
SerialPort1.Write(TextBox1.Text.Trim) '接收完毕,回复数据
End If
str1 = Split(BitConverter.ToString(Rc), "-")
ReDim str2(str1.Length - 1) '去除str1中最后的字符
For i = 0 To str1.Length - 2
str2(i) = str1(i)
Next
receivebox.Text = receivebox.Text & Join(str2, " ")
'BitConverter.ToString(Rc)
Else
'char(9) 水平制表符
'char(10)换行键
'char(13)回车键
receivebox.Text = receivebox.Text & SerialPort1.ReadExisting() '在编码的基础上,读取 SerialPort 对象的流和输入缓冲区中所有立即可用的字节。
End If
receivebytes.Text = Str(Val(receivebytes.Text) + Rc.Length - 1)
SerialPort1.DiscardInBuffer() '丢弃来自串行驱动程序的接收缓冲区的数据
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub


'发送数据(无参数版本)
Private Sub send()
If SerialPort1.IsOpen = False Then '判断端口是否打开
Exit Sub
End If
'自动发送查询数据
Timer2.Tag = Timer2.Tag + 1
Select Case Timer2.Tag
Case 1
ReDim Fx(UBound(Afx) + 1)
Fx = Afx
Case 2
ReDim Fx(UBound(Bfx) + 1)
Fx = Bfx
Case 3
ReDim Fx(UBound(Cfx) + 1)
Fx = Cfx
Case 4
ReDim Fx(UBound(Dfx) + 1)
Fx = Dfx
Case 5
ReDim Fx(UBound(Efx) + 1)
Fx = Efx
Case 6
ReDim Fx(UBound(Ffx) + 1)
Fx = Ffx
Case Else
ReDim Fx(UBound(Afx) + 1)
Fx = Afx
'默认修改第一组
End Select
SerialPort1.Write(Fx, 1, Fx.Count - 1) '发送数组fx第1到n数据,十六进制发送
SerialPort1.DiscardOutBuffer() '清除缓存
'显示发送数据
Dim STRDATA As String = ""
For i = 1 To UBound(Fx)
If Len(Hex(Fx(i))) = 1 Then
STRDATA = STRDATA & "0" & Hex(Fx(i)) & " "
Else
STRDATA = STRDATA & Hex(Fx(i)) & " "
End If
Next
ToolStripStatusLabel1.Text = "STATUS:Send:NO." & Timer2.Tag.ToString & ":" & STRDATA ' 串口状态显示

End If
End Sub
'发送数据(含参数Cmd 待发送数据)
Private Sub send(ByVal Cm

d As String)
'Dim databyte() As Byte
Dim str1() As String '发送文本框字符串装换为数组
Dim str2 As String '去空格后偶数长度的字符串(标准16进制)
Dim str3 As String '去空格后奇数长度的字符串 (末尾字符补0)
Dim i As Integer
' Dim Cmd As String = sendbox.Text '发送数据
Try
SerialPort1.WriteTimeout = CInt(ComboBox2.Text) '发送操作未完成时发生超时之前的毫秒数。
If hexcheck.Checked = False Then '不按照16进制发送
If linecheck.Checked = False Then '判断是否选中分行发送
SerialPort1.Write(Cmd)
Else
SerialPort1.WriteLine(Cmd)
End If
sendbytes.Text = Str(Val(sendbytes.Text) + Cmd.Length)
Else '按照16进制发送
If InStr(Cmd, " ") Then '判断是否有空格
str1 = Split(Cmd)
str2 = Join(str1, "")
Else
str2 = Cmd
End If
If str2.Length Mod 2 = 0 Then '判断字符串字节数是否为偶数
ReDim fx(str2.Length / 2) '重新定义数组
For i = 0 To str2.Length / 2 - 1
fx(i) = Convert.ToByte(Mid(str2, 2 * i + 1, 2), 16) '两个字符转换为一个16进制字节
Next
Else
str3 = Mid(str2, 1, (str2.Length - 1)) & "0" & Mid(str2, str2.Length)
ReDim fx(str3.Length / 2)
For i = 0 To str3.Length / 2 - 1
fx(i) = Convert.ToByte(Mid(str3, 2 * i + 1, 2), 16)
Next
End If
'fx = System.Text.Encoding.Default.GetBytes(Cmd) ‘把每个字符转换成字节
SerialPort1.Write(fx, 0, fx.Length - 1)
sendbytes.Text = Str(Val(sendbytes.Text) + fx.Length - 1)
End If
SerialPort1.DiscardOutBuffer() '丢弃来自串行驱动程序的传输缓冲区的数据
Catch ex As Exception
If hexcheck.Checked = True Then
MessageBox.Show("输入字符不属于十六进制字符,请核对!")
Else
MessageBox.Show(ex.Message)
End If
End Try
End Sub

相关主题