串口发送数据.......

y103049881 2011-04-01 11:10:17
VB串口发送一组168个字节的数据,其中前6个字节是发送16进制,后面160个字节是发送16进制的ASCII码,第167个字节是全面166个16进制数据的校检和取低位,再转换成16进制的ASCII码,就占了2个字节,全部数据就是168个字节的数据了

这段代码可以实现发送数据了,但是好像稳定性不强,发送的数据可能会经常出错,是不是因为数据长度越大,出错的几率就越大?168个字节的数据发送出错几率大不大呢?

有什么办法可以同样实现以上数据的发送,让发送的数据都正确,或者说可不可以优化一下这段代码呢?

Private Sub clearDksj_Click()

If MSComm1.PortOpen = False Then
MsgBox "请先打开串口!", vbOKOnly + vbExclamation, "提示!"
End If
If MSComm1.PortOpen = False Then Exit Sub

Dim send_buf() As Byte
Dim Abyte(166) As Byte
Dim ss As Single
Dim XX As String

Abyte(0) = &H1F
Abyte(1) = &H6D
Abyte(2) = &H30
Abyte(3) = &H31
Abyte(4) = &H2A
Abyte(5) = &H2B

For I = 6 To 165
Abyte(I) = &H30
Next

For I = 0 To 165
ss1 = ss1 + Val(Abyte(I))
Next

Abyte(166) = ss1 Mod 256

XX = Right("00" & Hex(Abyte(166)), 2)

send_buf = StrConv(Chr(&H1F) & Chr(&H6D) & Chr(&H30) & Chr(&H31) & Chr(&H2A) & Chr(&H2B) & Right(String(160, "0"), 160) & Right("00" & Hex(Abyte(166)), 2), vbFromUnicode)

MSComm1.Output = send_buf

End Sub
...全文
330 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
y103049881 2011-04-02
  • 打赏
  • 举报
回复
单片机应该没问题,是不是我的串口设置有问题呢?发送168个字节的数据应该如何设置串口?
flfq 2011-04-01
  • 打赏
  • 举报
回复
你清楚你最后发送的是什么吗,设置断点看看问题在哪
y103049881 2011-04-01
  • 打赏
  • 举报
回复
前面6个字节发送的是16进制,后面的162个字节要求是16进制的ASCII码
flfq 2011-04-01
  • 打赏
  • 举报
回复

send_buf = StrConv(Chr(&H1F) & Chr(&H6D) & Chr(&H30) & Chr(&H31) & Chr(&H2A) & Chr(&H2B) & Right(String(160, "0"), 160) & Right("00" & Hex(Abyte(166)), 2), vbFromUnicode)

看看chr和hex的,你发的就不是16进制的ascii码,还有strconv的用法,应该这样用:
strconv(abyte,vbUnicode)
y103049881 2011-04-01
  • 打赏
  • 举报
回复
之前我就是用十进制来表示的,现在改成了十六进制表示法,结果还是一样呀
flfq 2011-04-01
  • 打赏
  • 举报
回复
Chr 函数


返回 String,其中包含有与指定的字符代码相关的字符 。

语法

Chr(charcode)

必要的 charcode 参数是一个用来识别某字符的 Long。

说明

0 到 31 之间的数字与标准的非打印 ASCII 代码相同。例如,Chr(10) 可以返回换行字符。charcode 的正常范围为 0 – 255。然而,在 DBCS 系统,charcode 的实际范围为 -32768 到 65535。

注意 ChrB 函数作用于包含在 String 中的字节数据。ChrB 总是返回一个单字节,而不是返回一个字符,一个字符可能是一个或两个字节。ChrW 函数返回包含 Unicode 的 String,若在不支持 Unicode 的平台上,则其功能与 Chr 函数相同。



Hex 函数


返回代表十六进制数值的 String。

语法

Hex(number)

必要的 number 参数为任何有效的数值表达式或字符串表达式。

说明

如果 number 还不是一个整数,那么在执行前会先被四舍五入成最接近的整数。

如果 number 为 所得为
Null Null
Empty 零 (0)
任何其他的数字 最多可到八个十六进制字符。


适当范围内的数字,前缀以 &H,可以直接表示十六进制数字。例如,十六进制表示法的 &H10 代表十进制的 16。
y103049881 2011-04-01
  • 打赏
  • 举报
回复
没有定义ss1,这个有关系吗?
flfq 2011-04-01
  • 打赏
  • 举报
回复

ss1 = ss1 + Val(Abyte(I))

ss1在哪定义的
贝隆 2011-04-01
  • 打赏
  • 举报
回复
研究一下是否你是单片机处理有问题?
y103049881 2011-04-01
  • 打赏
  • 举报
回复
MSComm1.Output = Abyte
用这种方法发送数组数据的时候,跟串口调试器测试发现那些数据又完全没有问题,为什么跟单片机传送数据的时候会经常出现数据错误呢,因为数据正确的话,单片机会返回一些指令回来,数据错误单片机则没有反映
是发送数据的问题还是什么问题呢?
y103049881 2011-04-01
  • 打赏
  • 举报
回复
Dim send_buf() As Byte
Dim Abyte(167) As Byte
Dim ss As Single
Dim ss1 As Single
Dim XX As String

Abyte(0) = &H1F
Abyte(1) = &H6D
Abyte(2) = &H30
Abyte(3) = &H31
Abyte(4) = &H2A
Abyte(5) = &H2B

For I = 6 To 165
Abyte(I) = &H30
Next

For I = 0 To 165
ss1 = ss1 + Val(Abyte(I))
Next

ss = ss1 Mod 256

XX = Right("00" & Hex(ss), 2)
Abyte(166) = Asc(Left(XX, 1))
Abyte(167) = Asc(Right(XX, 1))

MSComm1.Output = Abyte
End Sub


现在我改成了这种方式发送,也可以发送数据
我搞不明白的是,楼上的朋友说 以二进制发送,我的命令就是错误的,那为什么我之前的程序也可以发送数据,和单片机连接后可以发送正常的指令呢?
贝隆 2011-04-01
  • 打赏
  • 举报
回复
楼主可以参考一下这个程序,串口调试器代码:
http://download.csdn.net/source/1262066
贝隆 2011-04-01
  • 打赏
  • 举报
回复
如果你是以二进制发送,那么你的命令就是错误的

你要把所有数据都存入数组,然后output=数组名 就可以了
y103049881 2011-04-01
  • 打赏
  • 举报
回复
我的串口设置是这样的:
If cmdSwitchPort.Caption = "打开串口" Then
' Timer1.Enabled = False
MSComm1.InBufferSize = 350 '初始化串口
MSComm1.InBufferCount = 0
MSComm1.InputMode = comInputModeBinary '二进制方式
MSComm1.CommPort = CmbPortName.ListIndex + 1 '1
MSComm1.Settings = "9600,N,8,1"
MSComm1.RThreshold = 1
MSComm1.InputLen = 0 '每次读入缓冲区所有字符
MSComm1.PortOpen = True '打开串口
cmdSwitchPort.Caption = "关闭串口"
Shape1.FillColor = RGB(0, 255, 0)
Else
MSComm1.PortOpen = 0
cmdSwitchPort.Caption = "打开串口"
Shape1.FillColor = RGB(255, 0, 0)

End If
现在已经是二进制方式发送了是吗?
串口这样设置可以吗?
波导终结者 2011-04-01
  • 打赏
  • 举报
回复
send_buf = StrConv(Chr(&H1F) & Chr(&H6D) & Chr(&H30) & Chr(&H31) & Chr(&H2A) & Chr(&H2B) & Right(String(160, "0"), 160) & Right("00" & Hex(Abyte(166)), 2), vbFromUnicode)

MSComm1.Output = send_buf

这样发绝对死翘翘,做那么多字符串操作,谁知道在哪里就不能识别了。不论你发的是什么数据,强烈建议都以二进制方式,存在byte数组里,一个字节一个字节的发。
贝隆 2011-04-01
  • 打赏
  • 举报
回复
我还是固执的认为是你处理字符的问题。
贝隆 2011-04-01
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 y103049881 的回复:]
串口是不是发送的数据越多越容易出错呢?168个字节的数据会不会经常性的出错?
[/Quote]
是不是容易失败,很容易验证,你下载一个串口调试器,把你要发送的这168个数据填写进去,再循环发送一下,看看是否出错。如果不出错,就证明是你的程序有问题。串口调试器你总该要相信吧?
flfq 2011-04-01
  • 打赏
  • 举报
回复
168个字节应该不会的,mscomm默认OutBufferSize是512,你也可以加大
y103049881 2011-04-01
  • 打赏
  • 举报
回复
串口是不是发送的数据越多越容易出错呢?168个字节的数据会不会经常性的出错?
贝隆 2011-04-01
  • 打赏
  • 举报
回复
我认为发送不是问题,只要你的发送缓冲区足够大是没有问题的。问题可能出在你处理字符的问题上。就如楼上所说,ASCII的可表达范围是:&H00~&H7F,如果大于这个数据就不是ASCII码了,你得转换可能需要ChrW来处理了。
加载更多回复(1)

863

社区成员

发帖
与我相关
我的任务
社区描述
VB COM/DCOM/COM+
c++ 技术论坛(原bbs)
社区管理员
  • COM/DCOM/COM+社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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