我这两天使用通讯协议分析软件(我多年前用qbasic编写的)分析了一下日本fanuc plc eprom读写器 fa-writer。发现它在读、写eprom时,将读出的eprom中的一个字节,按照高4位、低四位转换成两个相应的ascii码,从串口发送或接收。
例如:  (hex)           (ascii)
 eprom内容           发送的内容    0A                30 41     14                B1 B4              '做了 parity 处理、补偶了。补偶前应为 31  34。vb 能够将一个字节的内容转换成两个对应的ascii 吗?任何方式的帮助,都将非常感谢!

解决方案 »

  1.   

    分析一下,都加了30
    0        0+30         30       
    A       11+30         411        1+30         31       B1
    4        4+30         34       B4
      

  2.   

    看数据的规律不是ascii码
          ascii
    0      48
    A      65
    1      49
    4      52而是16进制转10进制,但都加了30是先转化后加 +30
      

  3.   

    不补偶的:
    dim n as byte, n1 as byte, n2 as byte
    n = &H0An1 = (n \ &H10) + &H30
    n2 = (n mod &H10) + &H30
    debug.print hex(n1), hex(n2)补偶是什么规则?
      

  4.   

    Public Function HexToAsc(bytHex As Byte) As String
        Dim i As Long
        i = bytHex \ 16
        If i > 9 Then
            HexToAsc = Chr(i - 10 + &H41)
        Else
            HexToAsc = Chr(i + &H30)
        End If
        i = bytHex Mod 16
        If i > 9 Then
            HexToAsc = HexToAsc & Chr(i - 10 + &H41)
        Else
            HexToAsc = HexToAsc & Chr(i + &H30)
        End If
    End FunctionPublic Function HexToAsc2(bytHex As Byte) As Byte()
        Dim i As Long
        Dim bytAsc(0 To 1) As Byte
        i = bytHex \ 16
        If i > 9 Then
            bytAsc(0) = i - 10 + &H41
        Else
            bytAsc(0) = i + &H30
        End If
        i = bytHex Mod 16
        If i > 9 Then
            bytAsc(1) = i - 10 + &H41
        Else
            bytAsc(1) = i + &H30
        End If
        HexToAsc2 = bytAsc
    End FunctionPrivate Sub Command1_Click()
        Dim byt() As Byte
        byt = HexToAsc2(&HD)
        Print Chr(byt(0)); Chr(byt(1))
    End SubPrivate Sub Command2_Click()
        Print HexToAsc(&HD)
    End Sub补偶不知道怎么算的
      

  5.   

    首先感谢各位这么给面子!补偶的意思是当一个字节的数据中有单数个1的时侯,在这个字节的最高bit补1.
    这是一种在数控机床上常用的数据纠错、检查的方式。
    例如:
      hex      binary        parity even(补偶)   parity odd(补奇)
      31       00110001       10110001               00110001
      41       01000001       01000001               11000001也就是串口通讯中常用的协议 parity=even ,data=7, stop bit=1
    我先试一下各位的指教。
    其实,在vb的程序中。我的这个例子不用考虑补偶。因为最后我要通过串口将数据发送出去。
    发送的时候采用偶校验(even)自动就将补偶的问题解决了。
    多谢各位!
    多谢!
      

  6.   

    tiger-zhao 的程序我试了一下,很好用,简单易懂。yachong 的程序我试了只输出 0D ,没太明白。不过如此认真回答我的问题,还是让我感激不尽。
      

  7.   

    大家注意一下:十六进制 A = 10 ,而不是 11。楼主试一下这段代码:
    Private Function ByteToHexStr(Num As Byte) As String    Dim i%, strBH$
        
        i = Num \ 16 + 48
        If (i > 57) Then i = i + 7
        strBH = Chr$(i)
        i = (Num And 15) + 48
        If (i > 57) Then i = i + 7
        ByteToHexStr = strBH & Chr$(i)
        
    End Function
    Private Sub Command1_Click()    Debug.Print ByteToHexStr(&H1A)
        Debug.Print ByteToHexStr(&H35)
        Debug.Print ByteToHexStr(&HEF)End Sub
    '输出:
    ' 1A
    ' 35
    ' EF
      

  8.   

    我刚才又试了一下tiger_zhao的程序,发现在0-9的区间是正确的。在A-F的区间有问题。
    结果如下:
       HEX     输出结果    应该输出的是
       FF       3F  3F       46 46
       AA       3A  3A       41 41多谢各位!   
      

  9.   

    Dim n As Byte, n1 As Byte, n2 As Byte
    n = &HFFn1 = Asc(Hex(n \ &H10))
    n2 = Asc(Hex(n Mod &H10))
    Debug.Print Hex(n1), Hex(n2)
      

  10.   

    我试了chen8013的程序。可能我的问题没有问清楚?!应该是如下内容,就满足需要了.0-9 用 31,32,33,....39表示  A-F 用 41,42,43,44,45,46来表示 (在这里先不考虑补偶处理)  hex         output code
      1A             31 41
      35             33 35
      EF             45 46多谢各位!
      

  11.   

    不补偶的将10进制数转换为16进制字符串,按字符发送:
        MSComm1.Output = Right("0" & Hex(Val(Text1)), 2)
      

  12.   

    Dim n As Byte, n1 As Byte, n2 As Byte
    n = &HFFn1 = Asc(Hex(n \ &H10))
    n2 = Asc(Hex(n Mod &H10))
    Debug.Print Hex(n1), Hex(n2)
    TIGER-ZHAO的这个程序试了一把,我觉得对了。真是高手啊!多谢!
      

  13.   

    我写的HexToAsc2这个函数返回一个byte数组,假设传入的参数是&h1A
    返回的数组就分别保存了&h31、&h41
    还是用tiger-zhao给出的Hex函数简单
    俺还没从C里面转出来,忘了VB内置的这个函数了
      

  14.   

    要这样输出,就用这个代码吧:
    Private Function ByteToHexStr(Num As Byte) As String    Dim i&, strOut$
        strOut = Space(5)    '高、低四位用空格分开
        'strOut = Space(4)    '高、低四中间无空格
        i = Num \ 16 + 48
        If (i > 57) Then i = i + 7
        Mid$(strOut, 1, 2) = Hex$(i)
        i = (Num And 15) + 48
        If (i > 57) Then i = i + 7
        Mid$(strOut, 4, 2) = Hex$(i)    '中间有空格用这句'
        'Mid$(strOut, 3, 2) = Hex$(i)    '中间无空格用这句'
        ByteToHexStr = strOutEnd FunctionPrivate Sub Command1_Click()
    ' 测试代码
        Cls
        Print ByteToHexStr(&H0)
        Print ByteToHexStr(&H34)
        Print ByteToHexStr(&HEF)End Sub
      

  15.   

    当然能
    例如:format(Hex(Asc("1")),"00"),这个可以将1的Asc码的16进制数转换出来:31
      

  16.   

    eprom 里的内容肯定是没有空格的。eprom就相当于bios芯片,里面装的是机器码。thanks for any help
      

  17.   

    VB boolean operators in order of precedence:Operator -- Operation:   1. Not -- negation
       2. And -- conjunction
       3. Or -- disjunction
       4. Xor -- exclusive disjunction
       5. Eqv -- equivalent
       6. Imp -- implies The boolean operators are lower in precedence than the arithmetic operators and the comparison operators. The boolean constants True and False may also be considered operators with 0 operands.Truth Tables:
    A  B A And B A Or B A Xor B A Eqv B A Imp BT  T    T    T    F    T    T
    T  F    F    T    T    F    F
    F  T    F    T    T    F    T
    F  F    F    F    F    T    T又从网上挡了一篇,自己复习一下吧。
    谢谢chen8013的认真态度。ascii码部分是从串口发送出去的。空格是我为了便于识别,这是我的错误,没有做说明。高手都是认真的!
      

  18.   

    其实很简单。它是把一个字节的内容当作字符来处理的:0A: Asc("0") = &H30, Asc("A") = &H41因此,不需要楼上的复杂函数,只要Dim a() As Byte
    a = StrConv(Right("0" & Hex(b), 2), vbFromUnicode)
    试试:
    Dim a() As Byte
    Dim b As Byteb = &HA
    a = StrConv(Right("0" & Hex(b), 2), vbFromUnicode)Debug.Print Hex(a(0))
    Debug.Print Hex(a(1))
      

  19.   

    of123 多谢!我试了你的程序,又开了眼了。存入我的档案喽!我把你的程序改成如下,step了一遍。
    Private Sub Form_Load()
    Dim a() As Byte
    Dim b As Byteb = &H31
    'a = StrConv(Right("0" & Hex(b), 2), vbFromUnicode)
    a = Right("0" & Hex(b), 2)
    Debug.Print Hex(a(0))
    Debug.Print Hex(a(1))a = StrConv(a, vbFromUnicode)
    Debug.Print Hex(a(0))
    Debug.Print Hex(a(1))End Sub33
    0
    33
    31
    为什莫通过strconv转换一下,33,0 传换成 33,31 有空讲一下吗?thanks for any help
      

  20.   


    C里面
    char s[]="12";
    则s[0]==0x31,ss[1]==0x32strconv函数可以实现同样效果
    dim byt() as byte
    byt=strconv("12",vbfromunicode)
    byt(0) --> &H31
    byt(1) --> &H32
      

  21.   


    改成
    Dim a() As Byte
    Dim b As Byteb = &H31
    'a = StrConv(Right("0" & Hex(b), 2), vbFromUnicode)
    a = Right("0" & Hex(b), 2)
    Debug.Print Hex(a(0))
    Debug.Print Hex(a(1))
    Debug.Print Hex(a(2))
    Debug.Print Hex(a(3))
    就可以发现问题在哪里了
    数据结果:
    33
    0
    31
    0
    多了两个0
    直接把字符串复制给byte数组,单字节的字符会补0
    所以要用strconv函数
      

  22.   

    yachong:"直接把字符串复制给byte数组,单字节的字符会补0
             所以要用strconv函数 " 说得好,我明白了。多谢!下面的问题是:
    b = &H31
    a = Right("0" & Hex(b), 2)
     
    关于“0” & hex(b),2 看不懂 
    是等于 &h30 and &h31 再取它的最右端的两个字节吗?
    那位给展开了讲一下,多谢!
      

  23.   

    Right("0" & Hex(b), 2) 是为了保证十六进制有 2 个字符。因为 Hex() 是自动去除前导 0 的:
    Hex(&HA) 得到的是 "A" 而不是 "0A"。
      

  24.   

      谢谢 of123! 你说的&hA去掉前导0我能够明白. 我还要继续请教一下。例如:
    问题1:
    上面我的例子里是&h31
    在vb里摆放形式是 00 31
    通过hex( ) 去掉00,只剩下 31了,对吗?
      或者是:
           &h0A  00001010  这种情况要去掉高四位的0000
           &h31  00110001  这样就没得去了问题2:
    Right("0" & Hex(b), 2)这个2是什莫意思,取最右端的两个字节?&h31只是一个字节吧!?
    针对&h31 这个2到底得到了是什莫内容呢?下面是vb msdn说明,连个例子都没有,举例就是"hello world".
     RightB 函数作用于包含在字符串中的字节数据。所以 length 指定的是字节数,而不是指定返回的字符数。抱歉!我有点笨。 thanks for any help!
      

  25.   

    Hex函数的返回值是一个字符串
    Hex(&h31) 返回“31”
    Hex(&H0a) 返回“A”
    字符串自动去掉了前导0
      

  26.   

    谢谢 蚜虫!刚写完一个数控机床改造的合同,还是回来把vb写明白点吧!我基本上使用basic的概念来学vb的。记得在basic语言里
    如果#1定义的是rs232的话。
    print #1,chr$(&h0a);那么输出的就是一个字节的数据 00001010.那位能用二进制给描述一下 &H0A 和 hex(&H0A)
    1. &H0A= binary code(                    )
    2. hex(&H0A)=binary code (                  )多谢!
     
      

  27.   

    那位能用二进制给描述一下 &H0A 和 hex(&H0A) 
    1. &HA = 10 
    binary code( 0000 1010 ) 
    2. Hex(&H0A) = "A"
    binary code ( 0100 0001 ) 
      

  28.   

    谢谢!
    那位能用二进制给描述一下 &H0A 和 hex(&H0A)
    1. &HA = 10
    binary code( 0000 1010 )
    2. Hex(&H0A) = "A"
    binary code ( 0100 0001 ) 那所谓的前导零在哪里呢?
      

  29.   

    lz:你用VB做下试验
    在CODE编辑窗口
    Private Sub Command1_Click()
        Dim a As Byte
        a = &HA  '书写按a = &H0A,换行后变为a = &HA
        Debug.Print a
        Debug.Print 
    End Sub立即窗口执行Command1_Click
    可以看到:
      10
     A
    前导零不显示.但内存的BYTE中必然是(0000 1010)
      

  30.   

    修正:Private Sub Command1_Click() 
            Dim a As Byte 
            a = &HA     '书写按a = &H0A,换行后变为a = &HA 
            Debug.Print  a 
            Debug.Print  Hex(a) 
    End   Sub 立即窗口执行Command1_Click 
    可以看到: 
       10 
      A 
    前导零不显示.但&HA在内存的BYTE中必然是(0000 1010)
      

  31.   

    谢谢!zdingyunDim a As Byte 
            a = &HA     '书写按a = &H0A,换行后变为a = &HA 
            Debug.Print  a 
            Debug.Print  Hex(a) 
    你写的这段,我明白了,和basic语言是一样的。而且‘书写按a = &H0A,换行后变为a = &HA ,在实际编程时我也经常见到。我也不相信cpu的内存里会有半个字节的数据存在。如果是将半个字节的数据输出到外部是可行的。在单片机和plc里会常用到,可以通过左移四位或右移四位来实现。我又仔细理解了一下of123的下述话:
    Right("0" & Hex(b), 2) 是为了保证十六进制有 2 个字符。因为 Hex() 是自动去除前导 0 的:
    Hex(&HA) 得到的是 "A" 而不是 "0A"。
    谢谢关照,祝晚安!