获取串口数据问题

yueyangyxj 2009-10-29 02:22:11
我想通过串口获取数据,发过来的数据长度是8位,端口数据是一个数字一个数字发过来的,并且是反序的,如发送数据123.5和125.5则是按如下数据发送:5.321000=5.521000=。
程序代码如下:
1、打开串口
If (SerialPort1.IsOpen = True) Then SerialPort1.Close()
SerialPort1.PortName = "com1"
SerialPort1.BaudRate = 1200
SerialPort1.DataBits = 8
SerialPort1.Parity = Parity.None
SerialPort1.StopBits = StopBits.One
SerialPort1.ReadTimeout = 2000
SerialPort1.ReceivedBytesThreshold = 1
SerialPort1.Open()
AddHandler SerialPort1.DataReceived, AddressOf SerialPort1_DataReceived

2、获取数据
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object,
ByVal e As System.IO.Ports.SerialDataReceivedEventArgs)
If e.EventType <> SerialData.Chars Then Exit Sub
isReceiving = True ';//开始读
Dim inData As String = SerialPort1.ReadExisting
DispalyText(inData)
isReceiving = False ';//开始读
End Sub

Delegate Sub SetTextCallback(ByVal InputString As String)

Private Sub DispalyText(ByVal comData As String)
If Me.txtReceive.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf DispalyText)
Me.Invoke(d, New Object() {comData})
Else
If comData.Trim = "=" Then
Me.txtReceive.Text = ""
Else
Dim GetComData As String = comData
If GetComData.Length > 8 Then
Dim weight() As String = GetComData.Split("=")
For i As Integer = 0 To weight.Length - 1
Me.txtReceive.Text = weight(i)
If IsNumeric(StrReverse(txtReceive.Text)) Then
If Convert.ToDouble(StrReverse(txtReceive.Text)) > 0 Then
txtSend.Text = txtReceive.Text
End If
Else
txtSend.Text = 0
End If
Next
Else
Me.txtReceive.Text = GetComData + Me.txtReceive.Text
If txtReceive.Text.Length = 8 Then
txtSend.Text = txtReceive.Text.Substring(3)
End If
End If
End If
End If
End Sub

我的处理方式是把接收到的数据一个一个加起来,判断当前是不是等于8位(想去两个“=”号之间的数据),发现这样处理效率很低,程序很容易出错,不知道是什么原因?调试的时候发现comData数据有时候会有很多,并不是一个数据,不知道是什么原因?
...全文
355 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
贝隆 2009-11-06
  • 打赏
  • 举报
回复
给你一个串口调试器的源码,你借鉴一下吧。
http://download.csdn.net/source/1262066
ckp00001 2009-11-06
  • 打赏
  • 举报
回复
SerialPort1.ReadTimeout = 2000
2秒太长了,300-500毫秒即可。
如果GetComData中是一串8个字符的反序字符串的话并以“=”开头,以下句子供参考:
If GetComData.Length = 8 And GetComData.StartsWith("=") Then
GetComData = Strings.StrReverse(GetedTon.Substring(1))
If IsNumeric(GetComData) Then
GetComData = Format(CDec(GetComData), "#0.00")
Else
GetComData = "0.00"
End If
Else
GetedTon = "0.00"
End If
zdingyun 2009-10-30
  • 打赏
  • 举报
回复
按LZ叙述的通信协议做了个演示代码,在VB.NET2008调试通过:
    Dim strData As String
Dim strDat As String
Dim mRecvByte() As Byte
Dim Hexsj As String
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Dim mSize As Integer = Me.SerialPort1.BytesToRead
ReDim mRecvByte(mSize - 1)
SerialPort1.Read(mRecvByte, 0, mSize)
BeginInvoke(New EventHandler(AddressOf zhuanhuan), SerialPort1.BytesToRead()) '使用委托方式显示接收到的字符串
End Sub
Sub zhuanhuan(ByVal sender As System.Object, ByVal e As System.EventArgs) '委托
strDat = ""
TextBox1.Text = ""
Dim i As Integer
For i = 0 To UBound(mRecvByte) 'mSize - 1
strData = IIf(mRecvByte(i) > 15, Hex(mRecvByte(i)), "0" & Hex(mRecvByte(i))) & strData
Next
Dim sj As Byte
For i = 1 To Len(strData) Step 2 '处理为ASCII字符
sj = Val("&H" & Mid(strData, i, 2))
If sj < 32 Or sj > 128 Then '当接收字节中有Chr(0)时,其后字符被切割
strDat = strDat & "."
Else
strDat = strDat & Chr(sj)
End If
Next
If Mid(strDat, 1, 1) = "=" And Len(strDat) = 9 Then
TextBox1.Text = strDat '显示字符
TextBox2.Text = strData '显示为16进制
TextBox3.Text = Len(strData) / 2
strData = ""
End If
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
SerialPort1.BaudRate = 1200 '波特率设为
SerialPort1.PortName = "com1" '端口为串口COM1
SerialPort1.ReceivedBytesThreshold = 1
SerialPort1.BaudRate = 1200
SerialPort1.DataBits = 8
SerialPort1.Parity = IO.Ports.Parity.None
SerialPort1.StopBits = IO.Ports.StopBits.One
SerialPort1.ReadTimeout = 2000
If SerialPort1.IsOpen = False Then SerialPort1.Open() '打开串口
End Sub

本代码是在我的资源"VB.NET2008的串口工程"工程基础上修改的.
yueyangyxj 2009-10-29
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 sunxinyu 的回复:]
缓冲区的问题,把receivethreshold设置成1,然后判断收到的结束字符标志,然后再往里读。

是不是很称重设备通讯???
[/Quote]

是一个称重的设备,这是厂家提供的资料:
1. 数据格式:所有数据均为ASCⅡ码,每组数据由11位组成,第一位为起始位,中间8位为数据位,第十位为偶校验位,第十一位为停止位;
2. 数据发送格式:本仪表在以连续发送方式时,数据以ASCⅡ方式输出,每帧数据共有9组组成(包括小数点)。数据传送先低位后高位,每帧数据间有一组是分隔符“=”,发送数据为毛重。如当前毛重80.16,连续发送61.08000=61.08000=……

我取数据就是判断是不是收到“=”,如果收到“=”,则默认该组数据称重的接收到,然后再显示,准备接受下一组数据,但是程序这样写好象总是有问题,并且会报错,不知道为何?
sunxinyu 2009-10-29
  • 打赏
  • 举报
回复
缓冲区的问题,把receivethreshold设置成1,然后判断收到的结束字符标志,然后再往里读。

是不是很称重设备通讯???

16,721

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧