537 lines
19 KiB
VB.net
537 lines
19 KiB
VB.net
Imports System.IO.Ports
|
|
Imports System.Threading
|
|
Imports _485_BurningTool.BLV_Bootloader
|
|
|
|
Public Class SerialController
|
|
Inherits Transmitter
|
|
|
|
Public m_Serial As SerialPort
|
|
|
|
Public m_SerialComfig As SerialComfig
|
|
Public m_Control As Control
|
|
Private Timer1 As System.Windows.Forms.Timer
|
|
'接收数据队列
|
|
Public m_ReceiveQueue As List(Of Cmdconfig) = New List(Of Cmdconfig)
|
|
'特殊接收处理标志
|
|
Public m_SpecialReceiveFlag As Integer
|
|
|
|
Sub New(gControl As Control)
|
|
|
|
CommunicationTypeindex = 1
|
|
m_SerialComfig = New SerialComfig
|
|
m_ReceiveQueue = New List(Of Cmdconfig)
|
|
m_ReceiveQueue.Clear()
|
|
m_Control = gControl
|
|
'm_Serial = New SerialPort
|
|
'CreateSerial(m_SerialComfig)
|
|
'创建定时器绑定定时器函数
|
|
'Timer1 = New System.Windows.Forms.Timer
|
|
'Timer1.Interval = 1000
|
|
'AddHandler Timer1.Tick, AddressOf TimerTick
|
|
'Timer1.Start()
|
|
recvBufferli = New List(Of Byte)
|
|
m_SpecialReceiveFlag = -1
|
|
End Sub
|
|
'定时器函数 定时查看接收队列是否接收超时
|
|
Public Sub TimerTick()
|
|
Dim len As Integer = m_ReceiveQueue.Count
|
|
For i = 0 To len - 1
|
|
'从尾部倒序查看节点是否超时
|
|
Dim item As Cmdconfig = m_ReceiveQueue(len - 1 - i)
|
|
If (Now - item.CmdSendTime).TotalSeconds > item.CmdReceiveTimeout Then
|
|
m_ReceiveQueue.RemoveAt(len - 1 - i)
|
|
End If
|
|
Next
|
|
End Sub
|
|
|
|
'创建串口连接
|
|
Public Function CreateSerial(g_SerialComfig As SerialComfig) As Boolean
|
|
|
|
Try
|
|
If IsNothing(m_Serial) Then
|
|
m_Serial = New SerialPort(g_SerialComfig.PortName, g_SerialComfig.BaudRate, g_SerialComfig.Parity, g_SerialComfig.DataBits, g_SerialComfig.StopBits)
|
|
AddHandler m_Serial.DataReceived, AddressOf DataReceivedHandler
|
|
m_Serial.Open()
|
|
Return True
|
|
Else
|
|
Dim m_SerialIsOpen As Boolean = False
|
|
If m_Serial.IsOpen Then
|
|
isread = True
|
|
While isListen
|
|
Application.DoEvents()
|
|
Thread.Sleep(10)
|
|
End While
|
|
Thread.Sleep(10)
|
|
m_Serial.Close()
|
|
m_SerialIsOpen = True
|
|
End If
|
|
m_Serial.PortName = g_SerialComfig.PortName
|
|
m_Serial.BaudRate = g_SerialComfig.BaudRate
|
|
m_Serial.Parity = g_SerialComfig.Parity
|
|
m_Serial.DataBits = g_SerialComfig.DataBits
|
|
m_Serial.StopBits = g_SerialComfig.StopBits
|
|
m_Serial.Handshake = g_SerialComfig.Handshake
|
|
If m_SerialIsOpen Then
|
|
m_Serial.Open()
|
|
End If
|
|
End If
|
|
|
|
|
|
Catch ex As Exception
|
|
Return False
|
|
End Try
|
|
Return True
|
|
End Function
|
|
|
|
|
|
Public Overrides Sub ClearReadData()
|
|
If IsNothing(m_Serial) Then
|
|
Return
|
|
Else
|
|
If m_Serial.IsOpen Then
|
|
'清空接收缓存
|
|
m_Serial.DiscardInBuffer()
|
|
End If
|
|
End If
|
|
If IsNothing(recvBufferli) OrElse recvBufferli.Count = 0 Then
|
|
Return
|
|
Else
|
|
recvBufferli.Clear()
|
|
End If
|
|
End Sub
|
|
|
|
|
|
'设置串口参数
|
|
|
|
''' 接收数据偏移量
|
|
Private _recvOffset, _recvstar As Integer
|
|
''' <summary>
|
|
''' 接收数据缓存包
|
|
''' </summary>
|
|
Private _recvBuffer(4095) As Byte
|
|
Public recvBufferli As List(Of Byte)
|
|
Public recvBufferliindex As Integer = 0
|
|
'获取 串口数据
|
|
Private Sub DataReceivedHandler(sender As Object, e As SerialDataReceivedEventArgs)
|
|
If isread Then Return
|
|
|
|
isListen = True
|
|
Static bytes As Integer = 0
|
|
Dim sp As SerialPort = DirectCast(sender, SerialPort)
|
|
|
|
Try
|
|
Select Case m_SpecialReceiveFlag
|
|
Case WorkflowType.SearchEquipment
|
|
Do
|
|
bytes = sp.BytesToRead
|
|
If bytes <= 0 Then
|
|
isListen = False
|
|
Exit Sub
|
|
End If
|
|
'If bytes + _recvOffset >= 4096 Then
|
|
|
|
' 'ShowPortReceData(_recvBuffer)
|
|
|
|
' sp.Read(_recvBuffer, _recvOffset, 4096 - _recvOffset)
|
|
|
|
' _recvOffset = 0
|
|
'Else
|
|
' sp.Read(_recvBuffer, _recvOffset, bytes)
|
|
' _recvOffset += bytes
|
|
'End If
|
|
|
|
Dim buf(bytes - 1) As Byte
|
|
sp.Read(buf, 0, bytes)
|
|
recvBufferli.AddRange(buf)
|
|
Thread.Sleep(1)
|
|
Loop While sp.BytesToRead > 0
|
|
If recvBufferli.Count > 0 Then
|
|
'RuningLog.OutputLogsToTheControl(m_Control, New RuningLogConfig($"RX:{DataProcessing.ByteToString2(recvBufferli.ToArray)}", Color.Black), 1)
|
|
Dim item As Cmdconfig
|
|
item = m_ReceiveQueue(0)
|
|
'判断超时
|
|
If item.CmdSendTime.AddMilliseconds(item.CmdReceiveTimeout) < Now Then
|
|
recvBufferli.Clear()
|
|
recvBufferliindex = 0
|
|
Console.WriteLine("超时清空-----------------------------")
|
|
Else
|
|
'截取搜索回复
|
|
|
|
recvBufferliindex = ExtractSearchReply(recvBufferli.ToArray, item)
|
|
|
|
End If
|
|
End If
|
|
Case Else
|
|
Do
|
|
bytes = sp.BytesToRead
|
|
If bytes <= 0 Then
|
|
isListen = False
|
|
Exit Sub
|
|
End If
|
|
'If bytes + _recvOffset >= 4096 Then
|
|
|
|
' 'ShowPortReceData(_recvBuffer)
|
|
|
|
' sp.Read(_recvBuffer, _recvOffset, 4096 - _recvOffset)
|
|
|
|
' _recvOffset = 0
|
|
'Else
|
|
' sp.Read(_recvBuffer, _recvOffset, bytes)
|
|
' _recvOffset += bytes
|
|
'End If
|
|
|
|
Dim buf(bytes - 1) As Byte
|
|
sp.Read(buf, 0, bytes)
|
|
'清空可读缓存
|
|
'sp.DiscardInBuffer()
|
|
|
|
recvBufferli.AddRange(buf)
|
|
|
|
|
|
Thread.Sleep(7)
|
|
Loop While sp.BytesToRead > 0
|
|
|
|
If recvBufferli.Count > 0 Then
|
|
|
|
|
|
|
|
Dim buf(recvBufferli.Count - 1) As Byte
|
|
Array.Copy(recvBufferli.ToArray, 0, buf, 0, buf.Length)
|
|
recvBufferli.Clear()
|
|
' Array.Copy(_recvBuffer, _recvstar, buf, 0, buf.Length)
|
|
'Console.WriteLine(DataProcessing.ByteToString2(buf))
|
|
'_recvstar = _recvOffset
|
|
|
|
'枚举队列
|
|
'获取队列第5个元素
|
|
Dim len As Integer = m_ReceiveQueue.Count
|
|
Dim item As Cmdconfig
|
|
Dim timep As TimeSpan
|
|
' RuningLog.OutputLogsToTheControl(m_Control, New RuningLogConfig($"RX:{DataProcessing.ByteToString2(buf)}", Color.Blue), 1)
|
|
mCommunicationFlowAddQueue(m_Control, New RuningLogConfig($"RX:{DataProcessing.ByteToString2(buf)}", Color.Blue), 1) '
|
|
' RuningLog.OutputLogsToTheControl(m_Control, New RuningLogConfig($"RX:{DataProcessing.ByteToString2(buff)}", Color.Blue), 1)
|
|
'Console.WriteLine($"RX():{len} ")
|
|
For i = 0 To len - 1
|
|
' Console.WriteLine($"RX:{len - 1 - i}< {m_ReceiveQueue.Count }")
|
|
If (len - 1 - i) < m_ReceiveQueue.Count Then
|
|
item = m_ReceiveQueue(len - 1 - i)
|
|
|
|
|
|
'timep = (Now - item.CmdSendTime)
|
|
''判断本节点接收时间是否超时
|
|
'If item.CmdReceiveStatus OrElse timep.TotalSeconds > item.CmdReceiveTimeout Then
|
|
' Console.WriteLine($"item.CmdReceiveStatus:{item.CmdReceiveStatus}, timep.TotalSeconds > item.CmdReceiveTimeout :{ timep.TotalSeconds}>{item.CmdReceiveTimeout}")
|
|
' item.setCmdReceiveStatus(True)
|
|
' Continue For
|
|
'End If
|
|
'按照对应协议解析 并设置到本节点中
|
|
item.Protocol.ParseReceiveData(item, buf)
|
|
End If
|
|
Next
|
|
End If
|
|
End Select
|
|
isListen = False
|
|
Catch ex As Exception
|
|
isListen = False
|
|
'AppendTipText($"串口接收数据失败,原因:{ex.Message}", Color.Red)
|
|
RuningLog.OutputLogsToTheControl(m_Control, New RuningLogConfig($"串口接收数据失败,原因:{ex.Message}", Color.Red), 1)
|
|
End Try
|
|
|
|
|
|
End Sub
|
|
Delegate Sub delmCommunicationFlowAddQueue(c As Control, rl As RuningLogConfig, lev As Integer)
|
|
Public Sub mCommunicationFlowAddQueue(c As Control, rl As RuningLogConfig, Optional lev As Integer = 0)
|
|
If c.InvokeRequired Then
|
|
Dim d As New delmCommunicationFlowAddQueue(AddressOf mCommunicationFlowAddQueue)
|
|
c.Invoke(d, c, rl, lev)
|
|
Else
|
|
RuningLog.OutputLogsToTheControl(c, rl, lev)
|
|
End If
|
|
End Sub
|
|
|
|
|
|
Public Function ExtractSearchReply(bufarry As Byte(), item As Cmdconfig) As Integer
|
|
|
|
If bufarry.Length - recvBufferliindex < 12 Then
|
|
RuningLog.OutputLogsToTheControl(m_Control, New RuningLogConfig($"接收数据长度异常!", Color.Red), 1)
|
|
Return recvBufferliindex
|
|
End If
|
|
Dim len As Integer
|
|
Dim result As Integer = recvBufferliindex
|
|
'Dim buff(44) As Bytei+
|
|
'遍历找到sn\
|
|
' Console.WriteLine($"ExtractSearchReply:{recvBufferliindex} {vbCrLf}RX:{DataProcessing.ByteToString2(bufarry)}")
|
|
AddQueue(m_Control, New RuningLogConfig($"RX1:", Color.Blue), 1)
|
|
For i = recvBufferliindex To bufarry.Length - 1
|
|
If (bufarry(i) And &HF) = (item.CmdSendData(1) And &HF) Then '
|
|
If i + 6 < bufarry.Length Then
|
|
If bufarry(i + 2) = item.CmdSendData(0) AndAlso bufarry(i + 6) = item.CmdSendData(7) Then
|
|
len = bufarry(i + 3) + bufarry(i + 4) * 256
|
|
Dim buff(len - 1) As Byte
|
|
If i > 0 Then
|
|
|
|
If i + len - 2 < bufarry.Length Then
|
|
Try
|
|
Array.Copy(bufarry, i - 1, buff, 0, len)
|
|
i = i + len - 2
|
|
|
|
item.Protocol.ParseReceiveData(item, buff)
|
|
result = i + 1
|
|
AddQueue(m_Control, New RuningLogConfig($"RX2:", Color.Blue), 1) '{DataProcessing.ByteToString2(buff)}
|
|
' RuningLog.OutputLogsToTheControl(m_Control, New RuningLogConfig($"RX:{DataProcessing.ByteToString2(buff)}", Color.Blue), 1)
|
|
Catch ex As Exception
|
|
MsgBox(ex.Message)
|
|
End Try
|
|
|
|
End If
|
|
|
|
Else
|
|
|
|
End If
|
|
End If
|
|
End If
|
|
|
|
End If
|
|
Next
|
|
Console.WriteLine($"ExtractSearchReply------end:{result}")
|
|
Return result
|
|
End Function
|
|
|
|
'设置波特率
|
|
Public Sub AnalyzeData()
|
|
|
|
End Sub
|
|
|
|
'判断串口是否有数据未接收
|
|
Public Function IsSerialData() As Boolean
|
|
' If IsNothing(m_Serial) Then Return False
|
|
Return m_Serial.BytesToRead > 0
|
|
End Function
|
|
|
|
Public Function SetBaudRate(baudRate As Integer, Optional devnumber As Integer = 1) As Boolean
|
|
If IsNothing(m_Serial) Then Return False
|
|
Dim ret As Boolean = m_Serial.IsOpen
|
|
'Dim buff As Byte() = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}
|
|
If m_Serial.IsOpen Then
|
|
'Thread.Sleep(300 * devnumber)
|
|
isread = True
|
|
While isListen
|
|
Application.DoEvents()
|
|
Thread.Sleep(10)
|
|
End While
|
|
Thread.Sleep(10)
|
|
'm_Serial.Write(buff, 0, buff.Length)
|
|
m_Serial.Close()
|
|
|
|
End If
|
|
|
|
m_Serial.BaudRate = baudRate
|
|
|
|
If ret Then
|
|
isread = False
|
|
m_Serial.Open()
|
|
'm_Serial.Write(buff, 0, buff.Length)
|
|
End If
|
|
|
|
Return True
|
|
End Function
|
|
'打开串口
|
|
Public Function OpenSerial() As Boolean
|
|
If IsNothing(m_Serial) Then Return False
|
|
If Not m_Serial.IsOpen Then
|
|
isread = False
|
|
m_Serial.Open()
|
|
End If
|
|
End Function
|
|
'关闭串口连接
|
|
Public Sub CloseSerial()
|
|
If IsNothing(m_Serial) Then Return
|
|
If m_Serial.IsOpen Then
|
|
isread = True
|
|
While isListen
|
|
Application.DoEvents()
|
|
Thread.Sleep(10)
|
|
End While
|
|
Thread.Sleep(10)
|
|
m_Serial.Close()
|
|
|
|
End If
|
|
Timer1.Stop()
|
|
End Sub
|
|
'获取串口接收数据
|
|
Public Overrides Function ReceiveData(g_comfig As Cmdconfig) As Cmdconfig
|
|
|
|
|
|
End Function
|
|
|
|
'发送数据
|
|
Public Overrides Sub SendData(data As Cmdconfig)
|
|
data.CmdSendTime = DateTime.Now
|
|
If IsNothing(m_Serial) OrElse Not m_Serial.IsOpen Then
|
|
RuningLog.OutputLogsToTheControl(m_Control, New RuningLogConfig($"发送器未连接!", Color.Red), 1)
|
|
Return
|
|
End If
|
|
'Dim Rl As New RuningLogConfig($"TX:", Color.DarkGreen)
|
|
'Rl.strdata = data.CmdSendData
|
|
' RuningLog.OutputLogsToTheControl(m_Control, Rl, 1)
|
|
'AddQueue(m_Control, New RuningLogConfig($"TX:", Color.DarkGreen), 1)
|
|
|
|
'清空发送缓存
|
|
'm_Serial.DiscardOutBuffer()
|
|
|
|
Try
|
|
m_Serial.Write(data.CmdSendData, 0, data.CmdSendData.Length)
|
|
'Dim buff As Byte() = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}
|
|
'm_Serial.Write(buff, 0, buff.Length)
|
|
Catch ex As Exception
|
|
Console.WriteLine(ex.Message)
|
|
End Try
|
|
|
|
|
|
End Sub
|
|
|
|
Public Overrides Function OpenTransmitter() As Boolean
|
|
If IsNothing(m_Serial) Then
|
|
Return CreateSerial(m_SerialComfig)
|
|
End If
|
|
If Not m_Serial.IsOpen Then
|
|
Try
|
|
isread = False
|
|
m_Serial.Open()
|
|
Catch ex As Exception
|
|
Return False
|
|
End Try
|
|
|
|
End If
|
|
Return True
|
|
End Function
|
|
Public isread As Boolean = False
|
|
Public isListen As Boolean = False
|
|
Public Overrides Sub CloseTransmitter()
|
|
If IsNothing(m_Serial) OrElse Not m_Serial.IsOpen Then Return
|
|
isread = True
|
|
While isListen
|
|
Application.DoEvents()
|
|
Thread.Sleep(10)
|
|
End While
|
|
|
|
Thread.Sleep(10)
|
|
m_Serial.Close()
|
|
m_Serial = Nothing
|
|
End Sub
|
|
|
|
Public Overrides Function IsTransmitter() As Boolean
|
|
If IsNothing(m_Serial) Then
|
|
Return False
|
|
Else
|
|
Return True
|
|
End If
|
|
End Function
|
|
|
|
Public Overrides Function GetTransmitterStatus() As Boolean
|
|
If IsNothing(m_Serial) Then Return False
|
|
Return m_Serial.IsOpen
|
|
End Function
|
|
|
|
'
|
|
Public Overrides Function SetTransmitterParameter(ParamArray params() As Object) As Boolean
|
|
If IsNothing(m_SerialComfig) Then Return False
|
|
'If m_Serial.IsOpen Then m_Serial.Close()
|
|
If params.Length > 0 Then
|
|
If TypeOf params(0) Is String Then
|
|
m_SerialComfig.PortName = params(0)
|
|
End If
|
|
End If
|
|
If params.Length > 1 Then
|
|
If TypeOf params(1) Is Integer Then
|
|
m_SerialComfig.BaudRate = params(1)
|
|
End If
|
|
End If
|
|
If params.Length > 2 Then
|
|
If TypeOf params(2) Is Integer Then
|
|
m_SerialComfig.DataBits = params(2)
|
|
End If
|
|
End If
|
|
If params.Length > 3 Then
|
|
If TypeOf params(3) Is Parity Then
|
|
m_SerialComfig.Parity = params(3)
|
|
End If
|
|
End If
|
|
If params.Length > 4 Then
|
|
If TypeOf params(4) Is StopBits Then
|
|
m_SerialComfig.StopBits = params(4)
|
|
End If
|
|
End If
|
|
If params.Length > 5 Then
|
|
If TypeOf params(5) Is Handshake Then
|
|
m_SerialComfig.Handshake = params(5)
|
|
End If
|
|
End If
|
|
Return CreateSerial(m_SerialComfig)
|
|
End Function
|
|
|
|
Public Overrides Sub ClearSendData()
|
|
If IsNothing(m_ReceiveQueue) Then Return
|
|
m_ReceiveQueue.Clear()
|
|
End Sub
|
|
|
|
Public Overrides Function SendData(data() As Byte) As Boolean
|
|
'data.CmdSendTime = DateTime.Now
|
|
If IsNothing(m_Serial) OrElse Not m_Serial.IsOpen Then
|
|
RuningLog.OutputLogsToTheControl(m_Control, New RuningLogConfig($"发送器未连接!", Color.Red), 1)
|
|
Return False
|
|
End If
|
|
'Dim Rl As New RuningLogConfig($"TX:", Color.DarkGreen)
|
|
'Rl.strdata = data.CmdSendData
|
|
' RuningLog.OutputLogsToTheControl(m_Control, Rl, 1)
|
|
'AddQueue(m_Control, New RuningLogConfig($"TX:", Color.DarkGreen), 1)
|
|
|
|
'清空发送缓存
|
|
'm_Serial.DiscardOutBuffer()
|
|
|
|
Try
|
|
m_Serial.Write(data, 0, data.Length)
|
|
'Dim buff As Byte() = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}
|
|
'm_Serial.Write(buff, 0, buff.Length)
|
|
Catch ex As Exception
|
|
Console.WriteLine(ex.Message)
|
|
Return False
|
|
End Try
|
|
Return True
|
|
End Function
|
|
|
|
|
|
End Class
|
|
|
|
Public Class SerialComfig
|
|
'串口名称
|
|
Public PortName As String
|
|
'波特率
|
|
Public BaudRate As Integer
|
|
'数据位
|
|
Public DataBits As Integer
|
|
'校验位
|
|
Public Parity As Parity
|
|
'停止位
|
|
Public StopBits As StopBits
|
|
'流控制
|
|
Public Handshake As Handshake
|
|
|
|
'获取 串口名称列表
|
|
Sub New()
|
|
PortName = GetPortNames()(0)
|
|
BaudRate = GetBaudRates()(0)
|
|
DataBits = 8
|
|
Parity = Parity.None
|
|
StopBits = StopBits.One
|
|
Handshake = Handshake.None
|
|
|
|
End Sub
|
|
Public Shared Function GetPortNames() As String()
|
|
Return SerialPort.GetPortNames()
|
|
End Function
|
|
'获取波特率列表
|
|
Public Shared Function GetBaudRates() As Integer()
|
|
Return New Integer() {300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200, 128000, 256000, 512000}
|
|
End Function
|
|
End Class |