搜索
bottom↓
回复: 27

VB上位机发送数据协议遇到的问题,还是很经典的发送十六进制协议!

[复制链接]

出0入0汤圆

发表于 2009-6-24 16:22:03 | 显示全部楼层 |阅读模式
大家好!我用VB发送AA +AA +AA +FF +01 +TEXT2里保存的Temp值(这个值大于256,所以我把Temp分成buff_out(5)与buff_out(6)),然后把这一组协议以十六进制发送到下位机,但是这样的后果就是程序容易跑飞(这个是昨天请教清华大学计算机系一个老师看了我的程序后说的,可能就是我定义的buff_out()数组来发送这个协议造成后果)。大家看看发送:AA +AA +AA +FF +01 +TEXT2里保存的Temp值,能不能采取其他方法?谢谢了!非常感谢!  
Private Sub Command20_Click()  
    Dim Temp As String  
    Dim buff_out() As Byte  
    ReDim buff_out(6)  
    buff_out(0) = &HAA  
    buff_out(1) = &HAA  
    buff_out(2) = &HAA  
    buff_out(3) = &HFF  
    buff_out(4) = &H1  
    Open App.Path & "\2.txt" For Input As #2  
    Line Input #2, Temp  
    Close #2  
    buff_out(6) = Temp Mod 256  
    buff_out(5) = (Temp - buff_out(6)) / 256  
    MSComm1.Output = buff_out  
  End Sub

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2009-6-24 17:44:32 | 显示全部楼层
Line Input #2, Temp 你前面说过    Dim Temp As String
再看后面
    buff_out(6) = Temp Mod 256   
    buff_out(5) = (Temp - buff_out(6)) / 256
做 mod 运算的能是string吗?!

出0入0汤圆

 楼主| 发表于 2009-6-24 18:55:47 | 显示全部楼层
adcr 老稻有何高见
“Line Input #2, Temp ”只是调用Text2里的数据记为Temp
“Dim Temp As String ”是把它作为 String,我试了,确实发送的数据是AA +AA +AA +FF +01 +TEXT2里保存的Temp值,也能控制下位机的操作,但是有时候就跑飞了,我上位机其他控件还有类似的其他的输出,诸如AA +AA +AA +FF +02;AA +AA +AA +FF +03 +TEXT3里保存的Temp3值;AA +AA +AA +FF +04 +TEXT4里保存的Temp4值+TEXT5里保存的Temp5值等等。

出0入0汤圆

发表于 2009-6-24 19:02:06 | 显示全部楼层
上位机跑飞还是下位机跑飞
如果是下位机的话,你发上位机程序做什么-_-

出0入0汤圆

 楼主| 发表于 2009-6-24 19:10:57 | 显示全部楼层
上位机跑飞 下位机没有问题 那个计算机系的老师说可能就是数组的问题

出0入0汤圆

 楼主| 发表于 2009-6-24 21:13:15 | 显示全部楼层
照adcr 老稻说的 我改成如下了:
Temp定义为String,在计算中用Val函数转换为数值,且它的值必须在65536以下,不然
buff_out(5) = (Temp - buff_out(6)) / 256
会报溢出错误.


全部如下:
Private Sub Command20_Click()
    Dim Temp As String
    Dim buff_out() As Byte
    ReDim buff_out(6)
    buff_out(0) = &HAA
    buff_out(1) = &HAA
    buff_out(2) = &HAA
    buff_out(3) = &HFF
    buff_out(4) = &H1
    Open App.Path & "\2.txt" For Input As #2
        Line Input #2, Temp
    Close #2
    If Val(Temp) < 65536 Then
        buff_out(6) = Temp Mod 256
        buff_out(5) = (Temp - buff_out(6)) / 256
        If MSComm1.PortOpen = False Then
          Label1.Caption = "您的串口现在是关闭状态,请先打开串口"
        Else
            MSComm1.Output = buff_out
            Label1.Caption = ""
        End If
    End If
End Sub

出0入0汤圆

 楼主| 发表于 2009-6-24 21:14:22 | 显示全部楼层
但是我觉得这样还是解决不了问题的关键!还是会在buff_out() 数组上出问题!

出0入0汤圆

 楼主| 发表于 2009-6-24 21:58:42 | 显示全部楼层
有的说是CPU利用率此时会很高!100%
我刚才看了下 只有2% 很低的
不知道我的这个有问题没有(我给单片机发的全是数值):
Private Sub MSComm1_OnComm()
    Dim bytInput() As Byte
    Dim intInputLen As Integer
    Dim n As Integer
    Dim teststring As String
End Sub

出0入0汤圆

 楼主| 发表于 2009-6-24 22:07:26 | 显示全部楼层
觉得是通信协议制定有些问题,因为我好几个通信协议,我的命令数据帧不是固定字节长度,自5-9字节不等,会不会使下位机增加数据帧长度判断难度.不足9个的就用00填充,直到添加到9个字节为止
有的建议通信单独做个窗体,通过全局变量传递数据.这样有个好处,可以定时关闭通信窗体,并瞬间后加载通信窗体,可避免通信出错导致的串口假死. 不知道怎么做?

出0入0汤圆

发表于 2009-6-25 09:46:34 | 显示全部楼层
LZ牛B啊,还能向清华大学的老师请教,真是羡慕!
LZ是不是清华的呀?^_^

出0入0汤圆

 楼主| 发表于 2009-6-25 09:48:47 | 显示全部楼层
呵呵

出0入0汤圆

发表于 2009-6-25 12:40:22 | 显示全部楼层
以下程序测试通过了,问题是如果输入大于65535会被丢弃.这应当是正常的现象,否则……
^

Private Sub Command1_Click()

    Dim Temp As String
    Dim buff_out() As Byte
    ReDim buff_out(6)
    Dim b As Long
   ' 使用 COM2。
   MSComm1.CommPort = 2
   ' 9600 波特,无奇偶校验,8 位数据,一个停止位。
   MSComm1.Settings = "9600,N,8,1"
   ' 当输入占用时,
   ' 告诉控件读入整个缓冲区。
   MSComm1.InputLen = 0
   ' 打开端口。
   MSComm1.PortOpen = True

    buff_out(0) = &HAA
    buff_out(1) = &HAA
    buff_out(2) = &HAA
    buff_out(3) = &HFF
    buff_out(4) = &H1
    Open App.Path & "\2.txt" For Input As #2
    Line Input #2, Temp
    Close #2
    b = Val(Temp)
    If b > 0 And b < 65536 Then
    buff_out(6) = b Mod 256
    buff_out(5) = (b - buff_out(6)) / 256
    MSComm1.Output = buff_out

    End If


   ' 关闭串行端口。
   MSComm1.PortOpen = False

End Sub

出0入0汤圆

发表于 2009-6-25 14:18:28 | 显示全部楼层
跑飞的话,首先应当看跑飞时,vb6的错误提示信息,是溢出、文件不能访问或其它信息,然后找原因。

11楼的代码有几处可以改进,
1.打开文件的Open语句前应当有On Error的处理,如果出现文件不存在,或者文件不能被共享读取,这里就会出错。
2.读入Temp字符串后,不应当立即使用Val做转换,而是应该首先用IsNumeric()进行数字格式判断,
通过后,在b=CLng(Temp)之前也要有On Error的错误处理,以防止转换时溢出。
3.buff_out(5) = (b - buff_out(6)) / 256 可以改写成 buff_out(5) = b \ 256,注意除号方向,后者是只取整数部分结果的。

出0入0汤圆

 楼主| 发表于 2009-6-25 14:49:42 | 显示全部楼层
回复yyccaa :帮11楼解释下你的改进3:这个 buff_out(6) = b Mod 256
                                    buff_out(5) = (b - buff_out(6)) / 256
                              是读大于256数值,把这个大于256数值的数转化为16进制,改写为buff_out(5) = b \ 256,我试了下能达到同样的效果,不过我觉得与程序跑飞(鼠标不能控制)没有多大的关系。
解释下您的改进1:这个open只是打开text保存的值,一般保存的.txt文件都在,所以一般不会有error出现。
yyccaa 您说的1与2的改进能否在11楼基础上帮改进下。谢谢!

出0入0汤圆

 楼主| 发表于 2009-6-28 16:48:45 | 显示全部楼层
Private Sub Command20_Click()
    Dim Temp As String
    Dim buff_out7() As Byte
    ReDim buff_out7(8)
    Dim u As Long
    MSComm1.Settings = "9600,N,8,1"   ' 9600 波特,无奇偶校验,8 位数据,一个停止位。
    MSComm1.InputLen = 0              ' 当输入占用时,告诉控件读入整个缓冲区。
    buff_out7(0) = &HAA
    buff_out7(1) = &HAA
    buff_out7(2) = &HFF
    buff_out7(3) = &H1
    Open App.Path & "\2.txt" For Input As #2
        Line Input #2, Temp
    Close #2
    u = Val(Temp)
    If u > 0 And u < 65536 Then
    buff_out7(5) = u Mod 256
    buff_out7(4) = u \ 256
    buff_out7(6) = &H0
    buff_out7(7) = &H0
    buff_out7(8) = &HFF
        If MSComm1.PortOpen = False Then
          Label1.Caption = "您的串口现在是关闭状态,请先打开串口"
        Else
            MSComm1.Output = buff_out7
            Label1.Caption = ""
        End If
    End If
End Sub



针对这个用doevents 怎么解决啊 ?有的说用doevents 可以解决

出0入0汤圆

发表于 2009-6-28 21:17:49 | 显示全部楼层
感觉楼主应该到VB专门讨论的论坛去问问。这里好像专门研究VB的坛友不多。

出0入0汤圆

 楼主| 发表于 2009-6-28 22:20:25 | 显示全部楼层
是啊 不是很多 搞仪器的有一点

出0入0汤圆

发表于 2009-6-29 17:39:26 | 显示全部楼层
MSComm1.Output = a
    Do While (MSComm1.OutBufferCount <> 0)
    Loop

出0入0汤圆

 楼主| 发表于 2009-6-29 17:42:40 | 显示全部楼层
MSComm1.Output = a ?不知道什么意思呢?

出0入0汤圆

发表于 2009-6-29 17:54:25 | 显示全部楼层
建议还是用C吧,这样上位机和下位机一个语法,大脑也轻松一些,节省下来的精力就可以用来思考技术了

出0入0汤圆

发表于 2009-6-29 17:56:54 | 显示全部楼层
MSComm1.Output = string

MSCOMM控件有2个工作模式,ascii码模式和二进制模式,上面是ascii的模式用法,用来发送一个以0x00结尾的字符串

出0入0汤圆

发表于 2009-6-29 17:59:13 | 显示全部楼层
10多年没用VB了,你找到这个控件的文档看看,很easy的,比VC的MFC要easy狠了
我当时还做了一个从PC下载hex代码到MCU的东西,用的就是MSCOMM控件的二进制模式

出0入0汤圆

发表于 2009-6-29 18:12:08 | 显示全部楼层
帮你找到出处了:http://msdn.microsoft.com/en-us/library/aa259420(VS.60).aspx
请注意Remark部分关于Text和Binary的叙述部分


Syntax

object.Output [ = value ]

The Output property syntax has these parts:
Part         Description
object         An object expression that evaluates to an object in the Applies To list.
value         A string of characters to write to the transmit buffer.

Remarks

The Output property can transmit text data or binary data. To send text data using the Output property, you must specify a Variant that contains a string. To send binary data, you must pass a Variant which contains a byte array to the Output property.

Normally, if you are sending an ANSI string to an application, you can send it as text data. If you have data that contains embedded control characters, Null characters, etc., then you will want to pass it as binary data.

Data Type

Variant

出0入0汤圆

发表于 2009-6-29 18:39:23 | 显示全部楼层
第一次听到VB程序也有"跑飞"的概念.

出0入0汤圆

 楼主| 发表于 2009-6-29 18:45:25 | 显示全部楼层
这个跑飞还是通信的问题

出0入0汤圆

发表于 2009-6-29 18:49:23 | 显示全部楼层
不太明白你这个"跑飞"指的是单片机的程序重启了, 还是VB程序报错了.

doevents是使用在循环当中的, 把控制权交还操作系统分配. 以免引起假死机.


    buff_out(6) = Temp Mod 256   
    buff_out(5) = (Temp - buff_out(6)) / 256


看了你的程序, 你这两句的意思, 是把一个数值转换为16进制数值, 两个字节的话,  就是0xffff= 65535,  超过这个数值, 你的数组是byte类型, 就保存不了.

换种写法:

    buff_out(6) = Temp Mod 256   '取余
    buff_out(5) = Temp \ 256     '取整

出0入0汤圆

 楼主| 发表于 2009-6-29 20:39:00 | 显示全部楼层
回ls:我指的“跑飞”是指VB界面死掉,鼠标由三角变为2个倒扣的烧杯状,点击控件无效。只能选择右上角的“X”强制性关闭,再次打开就报“串口占用”。我现在已经把doevents加上了,包括 buff_out(5) = (Temp - buff_out(6)) / 256 也改成了 buff_out(5) = Temp \ 256     '取整。好像是没有问题了。不过看做实验的时候还会出现什么问题吧!谢谢gdyaojie 了!

出0入4汤圆

发表于 2009-8-8 11:58:08 | 显示全部楼层
真服了你了,只看了你最上面的程序,连个循环都没有居然让vb down掉
你自己要发什么数据要清楚呀,如果你的数据大于65536,你发出去2个字节有什么意义,如果你一定要发
就先把temp转成int,用cint(),然后用mod,至于除256之前减去余数,真的是六个指头挠痒。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-20 15:46

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表