Public Class BlvBus Private RichTextBox1 As RichTextBox Private g_DevType As DEV_TYPE = DEV_TYPE.NANO_485 Sub New(ByRef RichTextBox As RichTextBox) RichTextBox1 = RichTextBox End Sub Public Enum FMT ADD_FM SEND_TYPE DEV_TYPE ADD_TO LEN CHECK CMD PARAM End Enum Public Enum CMD LOADER_CMD_SEARCH = &HC0 LOADER_CMD_JUMP_TO_BOOT = &HC1 End Enum Public Enum DEV_TYPE NANO_485 PB_485 BLV_C1 End Enum Const LOADER_CMD_OFFSET = &H10 Const LOADER_PKT_LEN = 512 Private COLOR_ERROR As Color = Color.Red Private COLOR_NORMAL As Color = Color.Blue Private COLOR_MESSAGE As Color = Color.Black Private g_SendBuffer(LOADER_PKT_LEN - 1) As Byte Private g_RecvBuffer(LOADER_PKT_LEN - 1) As Byte Private g_RecvLen As UInt16 = 0 Private g_SendSn As Byte = 1 Private g_RichTextBoxLastTick As UInt32 Public Function SearchDeviceCmd(ByVal devType As Byte, ByVal port As System.IO.Ports.SerialPort, ByVal address As Byte, ByRef devId As String, ByRef bootFlag As String, ByRef devModel As String, ByVal groupFlag As Boolean, ByVal val As DEV_TYPE, Optional ByVal maxRetry As Integer = 3, Optional ByVal timeout As Integer = 100) As Boolean g_DevType = val Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) FillSendBuf(devType, g_SendBuffer, CMD.LOADER_CMD_SEARCH, 0, address, groupFlag) If WriteToDevice(devType, port, g_SendBuffer, g_SendBuffer(FMT.LEN), g_RecvBuffer, g_RecvLen, groupFlag, maxRetry, timeout) Then devId = g_RecvBuffer(FMT.PARAM).ToString("X02") & " " & g_RecvBuffer(FMT.PARAM + 1).ToString("X02") & " " & g_RecvBuffer(FMT.PARAM + 2).ToString("X02") & " " & g_RecvBuffer(FMT.PARAM + 3).ToString("X02") bootFlag = "APP" devModel = System.Text.Encoding.ASCII.GetString(g_RecvBuffer, FMT.PARAM + 4, g_RecvLen - FMT.PARAM - 4) Return True End If Return False End Function Public Function JumpBootCmd(ByVal devType As Byte, ByVal port As System.IO.Ports.SerialPort, ByVal address As Byte, ByVal groupFlag As Boolean, ByVal val As DEV_TYPE, ByVal maxRetry As Integer, ByVal timeout As Integer) As Boolean g_DevType = val Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) FillSendBuf(devType, g_SendBuffer, CMD.LOADER_CMD_JUMP_TO_BOOT, 0, address, groupFlag) Return WriteToDevice(devType, port, g_SendBuffer, g_SendBuffer(FMT.LEN), g_RecvBuffer, g_RecvLen, groupFlag, maxRetry, timeout) End Function 'Public Sub GroupJumpBootCmd(ByVal port As System.IO.Ports.SerialPort, ByVal groupFlag As Boolean, ByVal val As DEV_TYPE, Optional ByVal maxRetry As Integer = 3, Optional ByVal timeout As Integer = 100) ' Dim address As Byte ' g_DevType = val ' Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) ' Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) ' FillSendBuf(g_SendBuffer, CMD.LOADER_CMD_JUMP_TO_BOOT, 0, address, groupFlag) ' WriteToDevice(port, g_SendBuffer, g_SendBuffer(FMT.LEN), g_RecvBuffer, g_RecvLen, groupFlag, maxRetry, timeout) 'End Sub Private Function WriteToDevice(ByVal devType As Byte, ByVal port As System.IO.Ports.SerialPort, ByVal sendBuf() As Byte, ByVal sendLen As UInt16, ByRef recvBuf() As Byte, ByRef recvLen As UInt16, ByVal groupFlag As Boolean, Optional ByVal maxRetry As Integer = 3, Optional ByVal timeout As Integer = 100) As Boolean Dim retryCount As Byte = 0 Dim result As Boolean = False Dim retFlag As Boolean = False Dim timeTick As UInt32 Dim rLen As Integer = 0 Dim readIndex As UInt16 = 0 Do RichTextBox_Show("TX", sendBuf, sendLen, COLOR_MESSAGE) retFlag = UartSendBuf(port, sendBuf, sendLen) '发送数据 WaitSendComp(port) '等待发送出去 If g_DevType = DEV_TYPE.PB_485 Then Delay(0.8 * sendLen) End If If retFlag Then If groupFlag = False Then '对于 groupFlag = false 应该要做延时,不能一直不停的发 retFlag = False timeTick = My.Computer.Clock.TickCount Do Try rLen = port.BytesToRead Catch ex As Exception rLen = 0 End Try If rLen > 0 Then '等待接收数据 timeTick = My.Computer.Clock.TickCount port.Read(recvBuf, readIndex, rLen) readIndex += rLen If readIndex > FMT.LEN AndAlso readIndex >= recvBuf(FMT.LEN) Then retFlag = True Exit Do End If End If Loop Until (My.Computer.Clock.TickCount - timeTick) > timeout If retFlag Then RichTextBox_Show("RX", recvBuf, readIndex, COLOR_MESSAGE) If recvBuf(FMT.ADD_FM) = sendBuf(FMT.ADD_TO) AndAlso recvBuf(FMT.ADD_TO) = sendBuf(FMT.ADD_FM) AndAlso recvBuf(FMT.DEV_TYPE) = devType AndAlso recvBuf(FMT.LEN) = readIndex AndAlso CalcCheckSum(recvBuf, readIndex) = 0 AndAlso recvBuf(FMT.CMD) = sendBuf(FMT.CMD) + LOADER_CMD_OFFSET Then recvLen = readIndex result = True End If Else If readIndex > 0 Then RichTextBox_Show("RX", recvBuf, readIndex, COLOR_ERROR) Else RichTextBox_Show("没有接收到数据", COLOR_ERROR) End If End If Else Delay(20) End If End If 'Application.DoEvents() If result = True Then Exit Do retryCount += 1 Loop Until retryCount >= maxRetry Return result End Function Private Sub FillSendBuf(ByVal devType As Byte, ByRef sendBuf() As Byte, cmd As Byte, paramLen As UInt16, ByVal address As Byte, ByVal groupFlag As Boolean) sendBuf(FMT.ADD_FM) = &H0 sendBuf(FMT.SEND_TYPE) = g_SendSn And &HF sendBuf(FMT.DEV_TYPE) = devType If groupFlag Then sendBuf(FMT.SEND_TYPE) = sendBuf(FMT.SEND_TYPE) Or &H80 sendBuf(FMT.ADD_TO) = &H0 '针对所有 Else sendBuf(FMT.ADD_TO) = address End If sendBuf(FMT.LEN) = FMT.PARAM + paramLen sendBuf(FMT.CHECK) = 0 sendBuf(FMT.CMD) = cmd sendBuf(FMT.CHECK) = CalcCheckSum(sendBuf, sendBuf(FMT.LEN)) g_SendSn = g_SendSn + 1 If g_SendSn > &HF Then g_SendSn = 0 End If End Sub Private Sub WaitSendComp(ByVal port As System.IO.Ports.SerialPort) Do Delay(1) Loop Until port.BytesToWrite = 0 End Sub Private Function UartSendBuf(ByVal port As System.IO.Ports.SerialPort, ByVal buf() As Byte, ByVal len As UInt16) As Boolean Try port.DiscardOutBuffer() port.DiscardInBuffer() Catch ex As Exception Return False End Try Try port.Write(buf, 0, len) Catch ex As Exception Return False End Try Return True End Function Private Sub Delay(ByVal time As Integer) Dim timeEnd As Integer = My.Computer.Clock.TickCount + time Do Application.DoEvents() Loop Until My.Computer.Clock.TickCount > timeEnd End Sub Private Function CalcCheckSum(ByVal buf() As Byte, ByVal len As UInt16) As Byte Dim sum As Int16 = 0 Dim i As UInt16 = 0 Dim retByte As Byte For i = 0 To len - 1 sum += buf(i) sum = sum And &HFF Next retByte = (Not sum) And &HFF Return retByte End Function Private Sub RichTextBox_AddTick() Dim str As String = "" str = "[" str += My.Computer.Clock.TickCount.ToString.PadLeft(10, " ") str += "] [" str += (My.Computer.Clock.TickCount - g_RichTextBoxLastTick).ToString.PadLeft(5, " ") str += "]" RichTextBox1.AppendText(str) g_RichTextBoxLastTick = My.Computer.Clock.TickCount End Sub Private Sub RichTextBox_Show(ByVal str As String, ByVal cor As Color) Dim tempSelStart As Integer Dim tempSelLenght As Integer RichTextBox_AddTick() tempSelStart = RichTextBox1.TextLength RichTextBox1.AppendText(str) tempSelLenght = RichTextBox1.TextLength - tempSelStart RichTextBox1.Select(tempSelStart, tempSelLenght) '选中文本 RichTextBox1.SelectionColor = cor '当前选中的文本显示颜色 RichTextBox1.AppendText(vbNewLine) RichTextBox1.ScrollToCaret() '将内容滚动的作用 End Sub Private Sub RichTextBox_Show(ByVal str1 As String, ByVal buf() As Byte, ByVal len As UInt16, ByVal cor As Color) Dim tempSelStart As Integer Dim tempSelLenght As Integer Dim i As UInt16 Dim str As String = "" RichTextBox_AddTick() tempSelStart = RichTextBox1.TextLength RichTextBox1.AppendText(str1) RichTextBox1.AppendText("--") For i = 0 To len - 1 str += Hex(buf(i)).PadLeft(2, "0") str += " " Next RichTextBox1.AppendText(str) tempSelLenght = RichTextBox1.TextLength - tempSelStart RichTextBox1.Select(tempSelStart, tempSelLenght) '选中文本 RichTextBox1.SelectionColor = cor '当前选中的文本显示颜色 RichTextBox1.AppendText(vbNewLine) RichTextBox1.ScrollToCaret() '将内容滚动的作用 End Sub End Class