精华内容
下载资源
问答
  • 在计算机中,所有的数据在存储运算时都要使用二进制数表示(因为计算机用高电平低电平分别表示10),例如,像a、b、c、d这样的52个字母(包括大写)、以及0、1等数字还有一些常用的符号(例如*、#、@等)在...

    在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0),例如,像a、b、c、d这样的52个字母(包括大写)、以及0、1等数字还有一些常用的符号(例如*、#、@等)在计算机中存储时也要使用二进制数来表示,而具体用哪些二进制数字表示哪个符号,当然每个人都可以约定自己的一套(这就叫编码),而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则,于是美国有关的标准化组织就出台了所谓的ASCII编码,统一规定了上述常用符号用哪些二进制数来表示.

    A在ascii中定义为01000001,也就是十进制65,有了这个标准后,当我们输入A时,计算机就可以通过ascii码知道输入的字符的二进制编码是01000001。而没有这样的标准,我们就必须自己想办法告诉计算机我们输入了一个A;没有这样的标准,我们在别的机器上就需要重新编码以告诉计算机我们要输入A。ascii码指的不是十进制,是二进制。只是用十进制表示习惯一点罢了,比如在ascii码中,A的二进制编码为01000001,如果用十进制表示是65,用十六进制表示就是41H

    下面摘录自http://www.51hei.com/bbs/dpj-22296-1.html

    在串口调试助手发送选项和接收选项处,还有个“字符格式发送”和“字符格式显示”,这是什么意思呢?
    先抛开我们使用的汉字不谈,那么我们常用的字符就包含了 0~9 的数字、 A~Z/a~z 的字母、还有各种标点符号等。那么在计算机系统里面我们怎么来表示它们呢? ASCII (American Standard Code for Information Interchange 即美国信息互换标准代码)可以完成这个使命:我们知道,在 计算机中一个字节的数据可以有0255256个值,我们取其中的0127128个值赋予了它另外一层涵义,即让它们分别来代表一个常用字符,其具体的对应关系如下表
    11-3 ASCII
    ASCII值
    控制字符
    ASCII值
    字符
    ASCII值
    字符
    ASCII值
    字符
    000
    NUL
    032
    (space)
    064
    @
    096
    001
    SOH
    033
    !
    065
    A
    097
    a
    002
    STX
    034
    "
    066
    B
    098
    b
    003
    ETX
    035
    #
    067
    C
    099
    c
    004
    EOT
    036
    $
    068
    D
    100
    d
    005
    END
    037
    %
    069
    E
    101
    e
    006
    ACK
    038
    &
    070
    F
    102
    f
    007
    BEL
    039
    '
    071
    G
    103
    g
    008
    BS
    040
    (
    072
    H
    104
    h
    009
    HT
    041
    )
    073
    I
    105
    i
    010
    LF
    042
    *
    074
    J
    106
    j
    011
    VT
    043
    +
    075
    K
    107
    k
    012
    FF
    044
    076
    L
    108
    l
    013
    CR
    045
    -
    077
    M
    109
    m
    014
    SO
    046
    078
    N
    110
    n
    015
    SI
    047
    /
    079
    O
    111
    o
    016
    DLE
    048
    0
    080
    P
    112
    p
    017
    DC1
    049
    1
    081
    Q
    113
    q
    018
    DC2
    050
    2
    082
    R
    114
    r
    019
    DC3
    051
    3
    083
    S
    115
    s
    020
    DC4
    052
    4
    084
    T
    116
    t
    021
    NAK
    053
    5
    085
    U
    117
    u
    022
    SYN
    054
    6
    086
    V
    118
    v
    023
    ETB
    055
    7
    087
    W
    119
    w
    024
    CAN
    056
    8
    088
    X
    120
    x
    025
    EM
    057
    9
    089
    Y
    121
    y
    026
    SUB
    058
    :
    090
    Z
    122
    z
    027
    ESC
    059
    ;
    091
    [
    123
    {
    028
    FS
    060
    <
    092
    \
    124
    |
    029
    GS
    061
    =
    093
     
    125
    }
    030
    RS
    062
    >
    094
    ^
    126
    ~
    031
    US
    063
    ?
    095
    _
    127
    DEL
    这样我们就在常用字符和字节数据之间建立了一一对应的关系,字节是数据存储的最小单位,存储一个字符是以字节为单位进行的(也即是8位二进制),那么现在一个字节就既可以代表一个整数又可以代表一个字符了,但它本质上只是一个字节的数据,而我们赋予了它不同的涵义,什么时候赋予它哪种涵义就看编程者的意图了。
     
      通过上述可以知道串口通信的本质是发送对应字符的以二进制表示的ASCII码:
    比如:
     
      用字符格式发送一个小写的 a,a的ASCII码是二进制 0110 0001 ,十六进制的0x61,十进制是97,就是通过串口把0110 0001按位发送出去
      用字符格式发送一个数字1,   1的ASCII码是二进制 0011 0001 ,十六进制的0x31,十进制是49,就是通过串口把0011 0001按位发送出去;
          用字符格式发送  a12b,  a12b的ASCII码是二进制 0110 0001 0011 0001 0011 0010 0110 0010,十六进制 61 31 32 62 ,就是通过串口按位发送出去,而每发送八位数据(一个字节)就有一个停止位,然后发送接下来的一个字符(8位),这样就依次发送了字符a-1-2-b 的ASCII码。
         用十六进制发送的本质就是发送对应字符的ASCII码的十六进制表示,发送框里写入十六进制,实际发送的时候仍然是十六进制转换为二进制,然后按位发送出去。 


    串口发送一帧数据时,两个字节的间隔时间是多少?

    波特率:发送二进制数据位的速率,习惯上用 baud 表示,即我们发送一位二进制数据的持续时间=1/baud。

    如果波特率为9600,发送一个位需要的时间为1/9600s=0.0001042s=0.1042ms,这里按数据位为8位,停止位为2位, 
    加起来就是10位,10个位发送所需的时间为:0.1042*10ms = 1.042ms,如果我要发送10个字节的数据,那发送这10个字节数据给接收方需要 的时间为:10*1.042ms = 10.42ms,这是算实际的发送10个字节的数据所需要的时间。我们在接收方接收数据时可以 
    把时间再加宽一些,让它有一点余量。让接收方能稳定的把数据从发送方接手过来,可以加个5ms,或更宽一点10ms, 
    加上发送10个字节所花的时间,就是15ms或20ms。



    展开全文
  • C#串口通信源代码,可以实现串口通信,实现字符和16进制发送以及接受
  • 经过单步调试,发现单片机发送的数据帧是字符串,并不是16进制数,而在线解包程序直接是对16进制数进行处理的,这就导致的比如16进制的数0xAA(170),下位机发送的是“AA"(字符串),上位机处理的16进制数是41 41...

         在调试一个stm32串口通信时,下位机设置好的发送方式采用串口助手接收后已经可以正常离线解包。但是由于需要实时解包并存储,因此写了一个实时解包存储的上位机,通信正常后接收的数据一直有误。经过单步调试,发现单片机发送的数据帧是字符串,并不是16进制数,而在线解包程序直接是对16进制数进行处理的,这就导致的比如16进制的数0xAA(170),下位机发送的是“AA"(字符串),上位机处理的16进制数是41 41(10进制为65*100+65)。查询‘A’的ASCII码可知,‘A’的ASCII码对应的10进制数为65,16进制数为41,也就是说上位机把接收到的16进制字符串当16进制数处理了,所以出错。

       解决方法两个,一个是修改下位机发送方式,将其改为发送“16进制数”,而不是“16进制字符串“;另一个是修改上位机接收方式,收到后将”16进制字符串“先转换为”16进制数“。多次尝试后发现还是修改下位机发送方式较为简单,且比较实用,因为大部分下位机串口发送协议发送的是16进制数。

    关于发送”16进制数“和”16进制字符“这两种数据发送方式原理的不同之处可见这篇文章http://blog.csdn.net/yibu_refresh/article/details/22695063

      

    下面是在stm32中进行两种数据发送的具体方法:

    一、发送16进制字符

    例如我们要发送一个32位的数:uint32_t  temp_send;
    发送方式如下,将32位的16进制数转换为8个对应的字符分别输出,例如:0xF0123456,将发送“F0123456”字符串:

    uint32_t  temp_send;
    //主函数
    int main(void)
    {
      while(1)
      {
       UART4_Putc_Hex(0xAA);//帧头
       UART4_Putdw_Hex(temp_send);	
      }
    }
    //子函数
    /**************************实现函数********************************************
    *函数原型:  void UART4_Putdw_Hex(uint32_t dw)
    *功  能:  RS232以十六进制ASCII码的方式发送32位的数据.
      	  如:0xF0123456 将发送 " F0123456 "
    *输入参数:uint32_t dw   要发送的32位数据值
    *输出参数:没有 
    *******************************************************************************/
    void UART4_Putdw_Hex(uint32_t dw)
    {
        UART4_Putw_Hex((uint16_t) (dw >> 16));
        UART4_Putw_Hex((uint16_t) (dw & 0xffff));
    }
    /**************************实现函数********************************************
    *函数原型:  void UART4_Putw_Hex(uint16_t w)
    *功  能:  RS232以十六进制ASCII码的方式发送一个字的数据.就是发送一个int
        		如:0x3456 将发送 " 3456 "
    *输入参数:uint16_t w   要发送的字
    *输出参数:没有 
    *******************************************************************************/
    void UART4_Putw_Hex(uint16_t w)
    {
     //发送高八位数据,当成一个字节发送
        UART4_Putc_Hex((uint8_t) (w >> 8));
     //发送低八位数据,当成一个字节发送
        UART4_Putc_Hex((uint8_t) (w & 0xff));
    }
    /**************************实现函数********************************************
    *函数原型:  void UART4_Putc_Hex(uint8_t b)
    *功  能:  RS232以十六进制ASCII码的方式发送一个字节数据
       	   先将目标字节数据高4位转成ASCCII ,发送,再将低4位转成ASCII发送
       	  	 如:0xF2 将发送 " F2 "
    *输入参数:  uint8_t b   要发送的字节
    *输出参数:  没有 
    *******************************************************************************/
    void UART4_Putc_Hex(uint8_t b)
    {
          /* 判断目标字节的高4位是否小于10 */
        if((b >> 4) < 0x0a)
            UART4_Put_Char((b >> 4) + '0'); //小于10  ,则相应发送0-9的ASCII
        else
            UART4_Put_Char((b >> 4) - 0x0a + 'A'); //大于等于10 则相应发送 A-F
    
        /* 判断目标字节的低4位 是否小于10*/
        if((b & 0x0f) < 0x0a)
            UART4_Put_Char((b & 0x0f) + '0');//小于10  ,则相应发送0-9的ASCII
        else
            UART4_Put_Char((b & 0x0f) - 0x0a + 'A');//大于等于10 则相应发送 A-F
    //   UART4_Put_Char(' '); //发送一个空格,以区分开两个字节
    }
    /**************************实现函数********************************************
    *函数原型:	void UART4_Put_Char(unsigned char DataToSend)
    *功  能:		RS232发送一个字节
    *输入参数:unsigned char DataToSend   要发送的字节数据
    *输出参数:没有	
    *******************************************************************************/
    void UART4_Put_Char(unsigned char DataToSend)
    {
      TxBuffer[count++] = DataToSend;  
      USART_ITConfig(UART4, USART_IT_TXE, ENABLE);  
    }
    

    二、发送16进制数

    发送方式如下,需要先将32位的数移位分割为4个字节(1个字节8位)的8位数分别发送, 例如:0xF0123456,将发送F0 12 34 56(4个16进制数)

    uint32_t  temp_send;
    char ByteSend[5]={0};//发送的字节
    uint i;
    //主函数
    int main(void)
    {
      while(1)
      {
    	ByteSend[0] = 0xAA;//帧头,ByteSend的类型为uchar或char均可		
    	ByteSend[1] = (temp_send>>24) & 0xFF;//
    	ByteSend[2] = (temp_send>>16) & 0xFF;
    	ByteSend[3] = (temp_send>>8) & 0xFF;
    	ByteSend[4] = temp_send & 0xFF;	
    	for(i=0;i<5;i++)
       	{ 
        	  UART4_Put_Char(ByteSend[i]);
      	}		
      }
    
    }
    //子函数
    /**************************实现函数********************************************
    *函数原型:  void UART4_Put_Char(unsigned char DataToSend)
    *功  能:  RS232发送一个字节
    输入参数:
      unsigned char DataToSend   要发送的字节数据
    输出参数:没有 
    *******************************************************************************/
    void UART4_Put_Char(unsigned char DataToSend)
    {
      TxBuffer[count++] = DataToSend;  
      USART_ITConfig(UART4, USART_IT_TXE, ENABLE);  
    }
    
    
    展开全文
  • Python3 串口接收与发送16进制数据包,及字符

    万次阅读 多人点赞 2018-08-09 14:27:00
    Python3 串口接收与发送16进制数据包,及字符串 将最简化的程序做到功能完善。 注意: #sleep() 与 inWaiting() 最好配对使用,不然 返回的num可能等于0 time.sleep(1)  num=t.inWaiting() #如果不使用 此行...

    Python3 串口接收与发送16进制数据包,及字符串

    将最简化的程序做到功能完善。

    注意:  #sleep() 与 inWaiting() 最好配对使用,不然 返回的num可能等于0

    time.sleep(1)    

    num=t.inWaiting() #如果不使用 此行函数返回读取的字节数,则只返回一个字符

    import binascii
    import serial  
    import time
    def hexShow(argv):        #十六进制显示 方法1
        try:
            result = ''  
            hLen = len(argv)  
            for i in range(hLen):  
             hvol = argv[i]
             hhex = '%02x'%hvol  
             result += hhex+' '  
            print('hexShow:',result)
        except:
            pass
    while True:  #循环重新启动串口
        t = serial.Serial('com7',9600)  
        print(t.portstr)  
        strInput = input('enter some words:') 
        try:    #如果输入不是十六进制数据-- 
            n =t.write(bytes.fromhex(strInput))
        except: #--则将其作为字符串输出
            n =t.write(bytes(strInput,encoding='utf-8'))
        
        print(n)  
        time.sleep(1)     #sleep() 与 inWaiting() 最好配对使用
        num=t.inWaiting()
        
        if num: 
            try:   #如果读取的不是十六进制数据--
                data= str(binascii.b2a_hex(t.read(num)))[2:-1] #十六进制显示方法2
                print(data)
            except: #--则将其作为字符串读取
                str = t.read(num)  
    #print(str)  
                hexShow(str)  
        serial.Serial.close(t)

     

    展开全文
  • 字符和16进制之间的转换

    万次阅读 2019-06-21 15:45:55
    串口传递数据的时候数据格式是16进制的,但是...在实现转换之前,先看一个16进制和字符的对应关系,如下所述。 用16进制打开一个文件如下图: 文件的大小是5个字节 为啥文件里面以01作为一个字节呢,其实是...

    在串口传递数据的时候数据格式是16进制的,但是存下来的数据为了方便查看,用字符串存储下来了。例如串口传递的数据是0xAA 0xBB 0xCC,存储下来的文件为AABBCC,这样存储带来的问题就是无法直接通过串口再发送出去,所以需要转换一下。在实现转换之前,先看一个16进制和字符的对应关系,如下所述。

    用16进制打开一个文件如下图:
    CSDN
    文件的大小是5个字节
    CSDN
    为啥文件里面以01作为一个字节呢。原因是01是两个16进制的字符,一个16进制字符是4位,8位是一个字节,所以01表示一个字节。基于上面的结论,转换函数实现如下:

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAX_DATA_SIZE 1024
    
    static int convert_string2hex(unsigned char *in_data, int in_data_len, unsigned char *out_data, int *out_data_len)
    {
        int i;
        int loop_count;
        int convert_point = 0;
        int mem_point = 0;
        unsigned char convert_result;
        unsigned char temp[3] = {0}; /* 为啥是3呢? */
    	
    	/* 检查参数有效性 */
        if (in_data == NULL || in_data_len <= 0 || out_data == NULL || out_data_len == NULL || (in_data_len % 2) != 0) {
            printf("invalid parameters\n");
            return -1;
        }
    
    	/* 判断是否超过16进制范围 0 ~ F */
        for (i = 0; i < in_data_len; i++) {
            if ((in_data[i] < '0') || (in_data[i] > 'f') || ((in_data[i] > '9') &&(in_data[i] < 'A'))) {
                printf("out of range\n");
                return -1;
            }
        }
    
        loop_count = in_data_len / 2;
        memset(out_data, 0x00, *out_data_len);
        *out_data_len = 0;
    
        for (i = 0; i < loop_count; i++) {
            memset(temp, 0x00, sizeof(temp));
            memcpy(temp, in_data + convert_point, 2);
            convert_point += 2;
    
            convert_result = strtoul(temp, NULL, 16);
    
            memcpy(out_data + mem_point, &convert_result, sizeof(unsigned char));
            mem_point += sizeof(unsigned char);
            *out_data_len += sizeof(unsigned char);
        }
    
        return 0;
    }
    

    测试转换功能的代码如下:

    int main(int argc, char const *argv[])
    {
        unsigned char in_data[MAX_DATA_SIZE] = {0};
        int in_data_len = MAX_DATA_SIZE;
        unsigned char out_data[MAX_DATA_SIZE] = {0};
        int out_data_len = MAX_DATA_SIZE;
        int i;
    
        scanf("%s", in_data);
    
        in_data_len = strlen(in_data);
    
        convert_string2hex(in_data, in_data_len, out_data, &out_data_len);
    
        for (i = 0; i < out_data_len; i++) {
            printf("0x%02x ", out_data[i]);
        }
        printf("\n");
    
        return 0;
    }
    

    输入AABBCC转换后的结果是0xAA 0xBB 0xCC。

    注意点
    convert_string2hex()函数中用来承接数据的temp必须要是3个字节,原因是strtoul函数的功能导致,strtoul()函数的定义如下:

    unsigned long int strtoul(const char *nptr, char **endptr, int base);
    

    strtoul()会扫描参数nptr字符串,跳过前面的空白字符(例如空格,tab缩进等),直到遇上数字或正负符号才开始做转换,再遇到非数字或字符串结束时(’\0’)结束转换,如果申请的temp是2个字节,那么其后面的一个字节如果不是0,转换就会出错,所以多申请一个字节来防止出现这种错误

    展开全文
  • 我们在工控软件中,会经常使用到网口和串口,去接受和发送数据。通常我们发送数据的模式有两种,一种16进制,一种是ASCII码。16进制的的经常会用来仪器PLC等设备通讯。ACSII码是一种文本模式。 1、当我们不点选16...
  • 51单片机串口程序,字符串/16进制发送与接收

    万次阅读 多人点赞 2014-03-31 21:50:51
    进制发送与接收,十六进制发送与接收。 字符串发送与十六进制发送,参考:http://blog.csdn.net/wityy/article/details/8234739 程序皆由PC串口工具发送,由单片机接收,并返回接收值给PC机。
  • Unity实现串口通信发送16进制字符

    千次阅读 热门讨论 2020-06-20 15:33:57
    Unity实现串口通信发送16进制字符 前言 Unity在与硬件设备进行串口通信的时候,硬件那边只接收字符串有时候是不行的,还需要接收16进制的数据,在这里简单介绍下使用Unity发送16进制串口信号。 步骤 一、首先开发...
  • 使用说明在程序内,此程序为C语言,有解释,已测试不需改可直接在keil内使用,注意波特率
  • 今天小编就为大家分享一篇Python3 串口接收与发送16进制数据包的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 用qt实现的界面程序,实现串口和UDP的字符和16进制的收发以及qt界面美化的方法。 更详细的介绍及界面展示,请参考笔者博客,在CSDN上搜索“QT学习过程及简单串口和UDP通信demo开发过程及代码分享”。
  • 字符串转16进制数值

    2011-12-20 09:12:14
    该程序是用labview编写的串口发送字符转,如何将字符串转换为16进制数值进行发送,可以为绝大部分朋友解决串口发送字符转换带来的一些麻烦,这是源代码
  • CVI串口字符16进制转换
  • 查找系统里存在着的串口资源并发送和接收16进制数字
  • Labview字符串转16进制

    2021-05-22 13:12:11
    在数据通信的时候经常会用到16进制来相互传输数据,下面是我在学习用Labview编写串口助手的时候,因为要用到16进制发送,探索到的用Labview实现字符串转换成16进制的方法之一。 用到的模块都很简单,有点基础的就能...
  • 51单片机串口程序,字符16进制发送与接收.docx
  • 串口发送字符十六进制源码

    千次阅读 2018-11-09 09:14:58
    /**  * @brief USART GPIO 配置,工作参数配置  * @param 无  * @retval 无  */ void USART_Config(void) {  GPIO_InitTypeDef GPIO_InitStructure;  USART_InitTypeDef USART_... // 打开串口GPIO的时...
  • 本文实例为大家分享了MFC串口通信发送16进制数据的具体代码,供大家参考,具体内容如下 MFC串口通信会使用m_mscomm控件。 发送数据一般是在edit control 里输入自己想发送的内容,然后点击send button。 如果直接...
  • 串口调试,更方便发送字符16进制数据,可以自动定时发送接收数据。可以选择多个串口.
  • 字符串转16进制 function strToHexCharCode(str) { if(str === "") return ""; var hexCharCode = []; hexCharCode.push("0x"); for(var i = 0; i < str.length; i++) { hexCharCode.push((str...
  • 串行通信--字符发送和十六进制发送串行通信--字符发送和十六进制发送### ASCII码在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0)#### 例如像a、b、c、d这样...
  • 在使用串口发送数据时可以选择字符串发送或者十六进制发送,通常情况下我们习惯选用字符串发送数据。关于两者的区别,需要从计算机存储数据的格式说起。  在计算机中,数据是以二进制的形式存储的,例如十进制 1...
  • 在软硬件开发中,常常会遇到将字符串转16进制的需求,因为设备的中控码常见的就是Hex编码格式,也就是16进制,下面就来看下如何字符串如何转化16进制吧 二、字符串转16进制 /// <summary> /// 字符串转16进制...
  • char ConvertHexChar(char ch) { if((ch >= '0') && (ch )) return ch-0x30;...if((hexdata == 16) || (lowhexdata == 16)) ...hexdata = hexdata*16+lowhexdata;...返回的QBtyeArray 可直接用串口对像发送
  • C++字符串转16进制

    2020-12-20 00:50:14
    串口通讯中,时常涉及到16进制字符发送,需要将字符串转为16进制。 Example:string str = "07 0a 02 10 03 00 00 00 00 00" #include <stdio.h> #include <stdlib.h> #include <string.h> ...
  • 在使用串口发送数据时可以选择字符串发送或者十六进制发送,通常情况下我们习惯选用字符串发送数据。关于两者的区别,需要从计算机存储数据的格式说起。  在计算机中,数据是以二进制的形式存储的,例如十进制 1...
  • 想要发送如下指令,并且不能当做字符串,必须要作为16进制发送 指令格式举例:01 10 00 00 00 02 04 00 01 00 00 a2 6f 这种需求其实是要 1,将16进制数字转为byte数组, 2,用OutStream讲byte数组写进...
  • VB写一个串口发送16进制数,如何将文本中的字符串转化成16进制数据发送

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 27,311
精华内容 10,924
关键字:

串口字符发送和16进制发送