+ -
当前位置:首页 → 问答吧 → 串口收到数据后再转换的一个小问题(将十六进制转化为十进制的)

串口收到数据后再转换的一个小问题(将十六进制转化为十进制的)

时间:2007-05-28

来源:互联网

程序如下:
Dim   Data(3)   As   Integer
Dim   buffer   As   Variant
Private   Sub   Form_Load()
  MSComm1.CommPort   =   1
  MSComm1.Settings   =   "9600,n,8,1 "
  MSComm1.InputMode   =   comInputModeBinary  
  MSComm1.RThreshold   =   1
  MSComm1.InputLen   =   2  
  MSComm1.InBufferCount   =   0
  MSComm1.PortOpen   =   True
End   Sub

Private   Sub   MSComm1_OnComm()
buffer   =   MSComm1.Input
For   i   =   LBound(buffer)   To   UBound(buffer)
    Data(i)   =   buffer(i)
Next   i
Text1.Text   =   Data(0)   +   Data(1)   *   16   '这里该怎么写啊?在文本框以十进制显示收到的数据
End   Sub

  根据观察结果   Text1.Text   显示的数据常常到3000多   肯定有问题啊   应该在0--256之间才对啊  
  应该怎么改啊   还是哪块设置有问题啊
另:我以前做项目的时候看到别人的一个程序是这么写的:Text1.Text   =   Data(0)   +   Data(1)   *   16   *   16     为什么要两个*16??


???????

作者: v20052008   发布时间: 2007-05-28

顶起来   怎么没有人回答啊   是不是太弱智了啊   呜呜呜  
可我不清楚啊

作者: v20052008   发布时间: 2007-05-29

Text1.Text   =   Data(0)   +   Data(1)   *   256

作者: bakw   发布时间: 2007-05-29

还是不懂啊   一般来说比如一个十六进制的数B5转化为十进制时为:5+11*16=181  
要是5+11*256那两个结果肯定不一样啊

是vb语言的问题吗?
那我现在要转换的数据是四位十六进制的   就是BBBB   这个在vb里面应该怎么写啊  
不是每个都要加乘一个16吧

作者: v20052008   发布时间: 2007-05-29

length=len(receivedata)
for   i=1   to   length
select   case   i
  case   1  
      t1=16
case   2
    t1=256

………
end   select
data=data+t1*mid(receivedata,(length-i),1)
next   i

作者: dx_cyb   发布时间: 2007-05-29

用&H00-&HFF就可直接转换为0-255的10进制

作者: zdingyun   发布时间: 2007-05-29

dx_cyb(剑)   :
你那个公式有问题吧?data没有赋初值   也就是他的初值为零  
这样的话   比如:收到的数据为ABCD   按你的算法推出来就是:C*16+B*256+A*4096
应该再加上D吧?


zdingyun()   :
我现在串口来的数据是这样处理的,比如数据为:09   89   B2   CB   45   34   ...
我要两个合并   data1=十进制(0989)
                          data2=十进制(B2CB)
                          .......
用你的方法我发现当大于&H7FF时   它返回的就为负数了
这个怎么解决啊   ?

作者: v20052008   发布时间: 2007-05-29

v20052008()  
用你的方法我发现当大于&H7FF时   它返回的就为负数了
这个怎么解决啊   ?
        这是VB中INTEGER数据的值定义所致,你单片机中数据是如何组织的,需根据通信协议定,你要0-255只能每当个16进制来转换。

作者: zdingyun   发布时间: 2007-05-29

如一定要要两个合并,并不出现负值,可将转换后加32768来解决,但是否是你要的结果很难说。

作者: zdingyun   发布时间: 2007-05-29

上述做法不可取.
        一般很多通信协议是按16位(二进制数据),范围为-32768到32767间,小数位数由通信协议指定,不传递.如TEX-200系列仪表V6.0串行通讯接口协议约定为::-2999—+32767为数据,用-32768—-7160之间的数值来表示地址代号,如果数据是温度值,其小数为1位,则数据在
-299.9—+3276.7范围.
        所以你应确认数据通信的协议是如何规定的,再来决定你接收后的数据处理.不然我们在此妄加推测,可能导致错误理解.

作者: zdingyun   发布时间: 2007-05-29

还是不懂啊   一般来说比如一个十六进制的数B5转化为十进制时为:5+11*16=181  
要是5+11*256那两个结果肯定不一样啊
是vb语言的问题吗?
那我现在要转换的数据是四位十六进制的   就是BBBB   这个在vb里面应该怎么写啊  
不是每个都要加乘一个16吧
------------------------
直接比如b5
text1.text=val( "&H "   &   "B5 ")
也就是text1.text=data1(0)   +   data1(1))*&H10
没有错误!

作者: xx22nn   发布时间: 2007-05-30

那我现在要转换的数据是四位十六进制的   就是BBBB   这个在vb里面应该怎么写啊  
不是每个都要加乘一个16吧
text1.text=val( "&H "   &   "BBBB ")

作者: xx22nn   发布时间: 2007-05-30

xx22nn(redhill红岭山腰的程序员)
  那我现在要转换的数据是四位十六进制的   就是BBBB   这个在vb里面应该怎么写啊  
不是每个都要加乘一个16吧
text1.text=val( "&H "   &   "BBBB ")

你代码处理方式符合VB的要求。

作者: zdingyun   发布时间: 2007-05-30

你的疑问跟   VB   没什么关系,关键在于你传送进来的数据格式是如何定义的。
你说的   4   位是   2   个字节还是   4   个字节?是大字节序还是小字节序(高字节在前还是低字节在前)?

你把这些说清楚了,一切迎刃而解。

作者: of123   发布时间: 2007-05-30

低字节在前     两个字节一共

作者: v20052008   发布时间: 2007-05-30

xx22nn(redhill红岭山腰的程序员)
text1.text=data1(0)   +   data1(1))*&H10
-------------------------------
  哦   我开始理解错了

作者: v20052008   发布时间: 2007-05-30

zdingyun()  
发上来的是温度的值   因为是16位的   每次发八位   所以我要把两次发的合并再取值

作者: v20052008   发布时间: 2007-05-30

v20052008()  
Val( "&H "   &   "BBBB ")处理16进制方法是VB经典做法。
温度值数据16位,需依据通信协议来决定如何处理,温度有负值。
也有可能按BCD码构成,则直接取4字节16进制字符直接显示,范围为0000-9999
总之需依据通信协议来决定如何处理。

作者: zdingyun   发布时间: 2007-05-30

不论是多少位都可以直接连接字符串然后取值。
只要不超过范围
Val( "&H "   &   "高位 "   &   "低位 "   &   "更低位 "...)

作者: xx22nn   发布时间: 2007-05-30

v20052008()  
串口来的数据   0989B2CB
低字节在前,需将接收到的数据字节换位:
Option   Explicit
        Dim   data   As   String
        Dim   data1   As   String

Private   Sub   Command1_Click()
        data1   =   Mid(data,   3,   2)   &   Mid(data,   1,   2)
        Text2   =   Val( "&H "   &   data1)
End   Sub

Private   Sub   Form_Load()
        data   =   "0989 "
        Text1   =   data
End   Sub

作者: zdingyun   发布时间: 2007-05-30

现在感觉我出的悬赏分太少了   以为是个小问题   没想到会搞这么久  
问题解决了一定增加分  

我现在搞得是   :下位机是一个红外温度传感器测温系统   有led点阵显示温度
                              每个温度值分两个字节发送
                              上位机用vb做个界面   显示温度

我昨天自己鼓捣出来的程序   显示是对的   但是我自己也不知道怎么回事   有些地方不理解   把主要部分贴出来   标出来的地方高手们给解释一下吧

Dim   buffer   As   Variant
Dim   Data(3)   As   Integer
Dim   shi   As   Integer

Private   Sub   Form_Load()
  MSComm1.CommPort   =   1
  MSComm1.Settings   =   "9600,n,8,1 "
  MSComm1.InputMode   =   comInputModeBinary  
  MSComm1.RThreshold   =   1
  MSComm1.InputLen   =   2   '读取缓冲区的两个字符,
  MSComm1.InBufferCount   =   0
  MSComm1.PortOpen   =   True

  End   Sub

Private   Sub   MSComm1_OnComm()

buffer   =   MSComm1.Input
text2.text=buffer           '????text2.text显示的是一堆符号,怎么才能让它显示成现在
                                              缓冲区的数据
For   i   =   LBound(buffer)   To   UBound(buffer)
Data(i)   =   buffer(i)  
shi   =   Data(0)   +   Data(1)   *   16   *   16 ' '?????不懂,看别人的一个小程序是这么写的
Text1.Text   =   shi
next   i
end   sub
' ' '我自己也理解不了,但出来结果是对的。比如他下位机要发一个温度值0x011F他是分两次发的,每次发一个字节,先发1F,再发01,我现在只用上面的程序,也没有进行合并,text1直接显示的就是287,多次测试也是对的。(是MSComm1.InputLen   =   2这个的关系吗??)
' '看懂的人士能给我注释一下吗?
' '谁有mscomm的msdn给我贴出来看看吧
' '唉,郁闷死,要是只做到这里就算了,关键是我还要继续往下进行啊,他要发多路信号,要发3到4个字节,包括一堆其他的信息

作者: v20052008   发布时间: 2007-05-31

原因就是需高低字节换位处理,给你一段调试正确的代码,下位机要发一个温度值   1F01,上位机收到后换位为011F:
Private   Sub   Form_Load()
        '...初始化
        MSComm1.CommPort   =   1
        MSComm1.Settings   =   "9600,n,8,1 "               '...设置通讯参数
        MSComm1.InputLen   =   0
        MSComm1.OutBufferCount   =   0
        MSComm1.RThreshold   =   1
        MSComm1.PortOpen   =   True   '...打开串口
End   Sub

Private   Sub   mscomm1_OnComm()
        Dim   card   As   String
        Dim   indata()   As   Byte
        Dim   BytesReceived()   As   Byte
        Dim   ReceiveLen   As   Byte
        Dim   i   As   Integer
        Dim   t   As   String
        Select   Case   MSComm1.CommEvent
                Case   comEvReceive
                MSComm1.InputMode   =   comInputModeBinary
                Lblshow.Caption   =   "正在接收数据 "
                MSComm1.InputLen   =   0
                ReceiveLen   =   MSComm1.InBufferCount   '以二进制方式接收
                ReDim   indata(ReceiveLen   -   1)   As   Byte
                indata   =   MSComm1.Input
                BytesReceived()   =   indata                                 '将数据转入BYTE中
                For   i   =   0   To   UBound(BytesReceived)             '显示结果以十六进制显示
                        If   Len(Hex(BytesReceived(i)))   =   1   Then
                                card   =   card   &   "0 "   &   Hex(BytesReceived(i))
                        Else
                                card   =   card   &   Hex(BytesReceived(i))
                        End   If
                Next
                If   Len(card)   =   4   Then   '接收7字节数据判断
                        card   =   Mid(card,   3,   2)   &   Mid(card,   1,   2)   '高底字节换位
                        Text1.Text   =   Val( "&H "   &   card)
                        MSComm1.InBufferCount   =   0               '清除接收缓冲区
                End   If
        End   Select
End   Sub

作者: zdingyun   发布时间: 2007-05-31

MSDN解释:
InputLen   属性
设置并返回   Input   属性从接收缓冲区读取的字符数。
语法
object.InputLen   [   =   value]
InputLen   属性语法包括下列部分:
部分   描述  
object   对象表达式,其值是“应用于”列表中的对象。  
value   整型表达式,说明   Input   属性从接收缓冲区中读取的字符数。  
说明
InputLen   属性的缺省值是   0。设置   InputLen   为   0   时,使用   Input   将使   MSComm   控件读取接收缓冲区中全部的内容。
若接收缓冲区中   InputLen   字符无效,Input   属性返回一个零长度字符串   ( " ")。在使用   Input   前,用户可以选择检查   InBufferCount   属性来确定缓冲区中是否已有需要数目的字符。
该属性在从输出格式为定长数据的机器读取数据时非常有用。
数据类型
Integer
InputLen   属性示例
该例子说明如何读取   10   个数据字符:

Private   Command1_Click()
Dim   CommData   as   String
'   确定一个10个字符的数据块。
MSComm1.InputLen   =   10
'   读数据。
CommData   =   MSComm1.Input
End   Sub

作者: zdingyun   发布时间: 2007-05-31

api   copymemory应该可以

作者: kkkk17100   发布时间: 2007-05-31

我做过这个,是用的copymemory函数,我是将收到的数据放在数组里,然后转换的,我是4个字节的转换成浮点数,要将2个字节的转换成整数,就不用copymemory了

作者: hanxiao6904   发布时间: 2007-06-01

定义一个byte型数组从串口收数
那样直接从串口中收到的就是十进制啊

作者: bitzl210   发布时间: 2007-06-01

Public   ReceiveQb()   As   Byte   '从串口收数
然后收数时
ReceiveQb   =   MSCsend.Input
直接收进来的就是10进制啊

作者: bitzl210   发布时间: 2007-06-01

谢谢各位   在实验室已经调试通过了  

下周去现场     不知道他们还会提什么意见   希望能通过   若有问题   还得请大家伙帮帮忙


作者: v20052008   发布时间: 2007-06-02

引用 13 楼 of123 的回复:
你的疑问跟 VB 没什么关系,关键在于你传送进来的数据格式是如何定义的。
你说的 4 位是 2 个字节还是 4 个字节?是大字节序还是小字节序(高字节在前还是低字节在前)?

你把这些说清楚了,一切迎刃而解。

一样的看法

作者: AloneZHANG   发布时间: 2008-05-08

VB code

buffer   =   MSComm1.Input 
text2.text=buffer           '????text2.text显示的是一堆符号,怎么才能让它显示成现在 
                                              缓冲区的数据 
For   i   =   LBound(buffer)   To   UBound(buffer) 
Data(i)   =   buffer(i)   
shi   =   Data(0)   +   Data(1)   *   16   *   16 ' '?????不懂,看别人的一个小程序是这么写的 
Text1.Text   =   shi 
next   i 
end   sub 


这个都不懂怎么处理字节数据,一个字节8位最大是256=16*16有什么不可理解的
Data(0)中的数几就是几 Data(1)中的数1代表256

作者: xx22nn   发布时间: 2008-06-04

膜拜一下,一年的贴子还不结

作者: alifriend   发布时间: 2008-06-04

是把第二个字符左移两位!!然后求和的。。。

作者: aini13141413   发布时间: 2011-10-05

热门下载

更多