Serial format string -HEX

Serial format string -HEX

Introduction

Serial communication relates generally to a process simulation data and a data transmission process, in general, we will send a series of instructions to the next crew

68 05 00 84 01 02 03

This example, we know that we are converted into corresponding character hex character display for indication ascii letters, but in the process we can use the string directly represents a character we want to write, then after receiving serial conversion ASCII code corresponding to the process data,

Here are some common conversion functions

Data Format

In our description
is given first ASCII code tableor reference Wikipedia ACII detailed description
herein, we are using "abc123" as a character string in which each display represented

  1. Refers to a string the string "abc 123" that can be able to play out ascii character representation, since we can not break out portion of the character, or characters are not displayed, only the control commands for flawed string str = " abc123 "
  2. Char string array [] uchar [] refers to a data in the cpp, char storage type or a character uchar, we can use a digital representation -128-127 or 0-255, we do consider that an array of facilitating uchar subsequent processing uchar buffer = {97,98,99,49,50,51}
  3. Char * uchar * string pointer is a pointer type, generally points to the address of the first character string data, because we believe that for many functions in the process 0x00 '\ 0' is ended, the processing time as much as possible the length of the incoming uchar * buffer = buffer
  4. converting the hex string values ​​into an array of strings inside the two hexadecimal values, then use the space division can be easily input commands, e.g. string command = "61 62 63 31 32 33"

Suitable such advantages and disadvantages, for example, we send to the lower machine using such a control command in a conventional Modbus control, typically in the serial input directly, then sent to hex, but if we need to test the corresponding data according to the two segments, filled txt text, each line of data is read, and then be able to convert the data to analog inputs and outputs ascii binary stream

68 13 00 85 11 12 21 22 31 32 00 00 01 00 00 02 00 00 03 88 FF 01 02 03 04 05 0F

Data format conversion

1. uchar data conversion and data byte char

char type data -128-127, uchar 0-255 type data are a byte, char data type of the first sign bit, the following there will be from 127 (01111111) +1 becomes -128 (1000 0000 ) transformation, then there will transform from -1 (1111 1111) to 0 (0000 0000), and can search the detailed char 溢出with 数据补码related content,

Therefore uchar -char interconversion may be considered in two parts
uchar of [0, 127] == char [0,127]
ucahr the [128, 255] == char [ -128, -1]

// uchar 数据转换 char  >127   c1-256
char Utils_String::UChar2Char(uchar c1)
{
    return static_cast<char>(c1 > 127 ? c1 - 256 : c1);
}

// char 类型转换 uchar  <0 -- c1 +256
uchar Utils_String::Char2UChar(char c1)
{
    return static_cast<uchar>((c1 < 0 ? 256 + c1 : c1));
}

2. hex conversion and digital

Hex hex characters generally represented, for convenience since we show, in turn represented by a hexadecimal 16 character is supplied 0-9 af 0-15, here not to consider capital letters, uppercase to lowercase equivalent AF af,

Since the type of data between uchar 0-256, can be expressed exactly two hexadecimal characters to represent, prefix 0x indicates hexadecimal characters, represents octal 0o 0d indicates decimal [0,255] == [0x00, 0xFF,]
we have established a conversion between characters 0-f and 0-15, there are two conversion mode a is mandatory if the conversion is determined, the other is the use of a certain arrangement of the code optimization table deal with

And a hex codes num interconversion
/**
 * @fn  int Utils_String::Hex2Num(const char ch)
 *
 * @brief   根据 各种情况 转换字母  一位字母 大于 48 的 +9  然后取后4位的值
 * *        
 *
 * @author  IRIS_Chen
 * @date    2019/12/16
 *
 * @param   ch  The ch
 *
 * @return  An int
 */
int Utils_String::Hex2Num(const char ch)
{
    //int res = (ch & '@' ? ch + 9 : ch) & 0x0F;
    //LInfo("ch:{},res:{}", ch, res);
    return (ch & '@' ? ch + 9 : ch) & 0x0F;
}

/**
 * @fn  char Utils_String::Num2Hex(int num, bool Up )
 *
 * @brief   将 0-15 转换成 0-F
 *
 * @author  IRIS_Chen
 * @date    2019/12/18
 *
 * @param   num Number of
 * @param   Up  True to up
 *
 * @return  The total number of 2 hexadecimal
 */
char Utils_String::Num2Hex(int num, bool Up /* = true */)
{
    char res;
    if (num >= 10 && num <= 15)
    {
        res = num - 10 + (Up ? 'A' : 'a');
    }
    else
        res = num + '0';
    return res;
}
And a hex codes num interconversion
2 and hex conversion uchar
/**
 * @fn  uchar Utils_String::Hex2Uchar(const std::string & str)
 *
 * @brief   Hexadecimal 2 uchar 将两个 hex 字符 转换成 0-256
 *
 * @author  IRIS_Chen
 * @date    2019/12/18
 *
 * @param   str The string 默认初始两位字符  FF == 255   00 = 0  0D = 14
 *
 * @return  An uchar
 */
uchar Utils_String::Hex2Uchar(const std::string & str)
{
    uchar res = 0;
    for (const auto &s:str)
    {
        res = (res << 4) + Hex2Num(s);
    }
    return res;
}

/**
 * @fn  std::string Utils_String::Num2Hex(uchar num, bool Up)
 *
 * @brief   Number 2 hexadecimal  得到的结果只有 小写
 *
 * @author  IRIS_Chen
 * @date    2019/12/18
 *
 * @param   num Number of
 * @param   Up  True to up
 *
 * @return  The total number of 2 hexadecimal
 */
std::string Utils_String::Num2Hex(uchar num, bool Up)
{
    std::map<int, char> t_base = { 
    { 8,'o' },
    { 10,'d' },
    { 16,'x' } };
    if (!t_base.count(base))
        return "";

    // 使用 sprintf 格式化输出, 将数字 转换成相应的进制值
    std::string format = "%0" + std::to_string(width) + t_base.find(base)->second;
    char *buf = new char[20];
    sprintf(buf, format.c_str(), num);

    std::string res=std::string(buf);

    // 转换大小写
    return Up ? StringUpper(res) : StringLowwer (res);
}

3. given string into an array of strings

Due to the converted character string pointer rotation native
pointer may be used to process a native

/**
 * @fn  const uchar * Utils_String::String2Uchar(const std::string & str)
 *
 * @brief   String 2 uchar
 *
 * @author  IRIS_Chen
 * @date    2019/12/16
 *
 * @param   str The string
 *
 * @return  Null if it fails, else a pointer to a const uchar
 */
const uchar * Utils_String::String2Uchar(const std::string & str)
{
    return (uchar*)str.c_str();
}
/**
 * @fn  std::string Utils_String::Uchar2String(const uchar * buffer)
 *
 * @brief   Uchar 2 string
 *
 * @author  IRIS_Chen
 * @date    2019/12/16
 *
 * @param   buffer  The buffer
 *
 * @return  A std::string
 */
std::string Utils_String::Uchar2String(const uchar * buffer)
{   
    std::string str = (char*)buffer;
    return str;
}

4. hex string conversion array of strings

Sequentially capturing two characters, it is converted to a stored data value to ucahr

Conversion hex string string array
/**
 * @fn  uchar * Utils_String::Hex2CharArr(uchar *&buffer, const std::string & str, bool flg_space)
 *
 * @brief   Hexadecimal 2 character array hex 字符串 转换成 数组
 *
 * @author  IRIS_Chen
 * @date    2019/12/18
 *
 * @param [in,out]  buffer      [in,out] If non-null, the buffer
 * @param           str         The string
 * @param           flg_space   True to flg space hex 是否使用空格分割
 *
 * @return  Null if it fails, else a pointer to an uchar
 */
uchar * Utils_String::Hex2CharArr(uchar *&buffer, const std::string & str, bool flg_space)
{
    // 出错 只有两个值 默认不符合 操作
    if (str.size() < 3)    return nullptr;
    // 默认够长 判断是否存在空格
    if (str[2] == ' ')   flg_space = true;

    int step = flg_space ? 3 : 2;

    buffer = new uchar[(str.size() + 1) / step +1 ];

    std::string str2 = "";

    for (int i = 0; i < static_cast<int>(str.size());)
    {
        uchar ch = Hex2Uchar(str.substr(static_cast<size_t>(i), 2));
        // 根据是否有空格选择 移动
        *(buffer + i/step) = ch;
        i += step;

        str2 += std::to_string((int)ch) + "-";
    }
    // LInfo("charArr:{}", str2);
    return buffer;
}

/**
 * @fn  std::string Utils_String::CharArr2Hex(uchar * buffer, int length, int flg_space)
 *
 * @brief   Character array 2 hexadecimal  数组 转换成 hex 字符
 *          * 将UCHAR 字符串依次转换成 string 字符串
 *
 * @author  IRIS_Chen
 * @date    2019/12/18
 *
 * @param [in,out]  buffer      If non-null, the buffer
 * @param           length      The length
 * @param           flg_space   The flg space
 *
 * @return  A std::string
 */
std::string Utils_String::CharArr2Hex(uchar * buffer, int length, int flg_space)
{
    std::string str = "";
    // 读取数组中所有字符
    for (int i = 0; i < length; i++)
    {
        str += Num2Hex(*buffer++);
        // 如果开启空格的话  每两个字符 之间加入一个空格 最后一个不加
        if (flg_space && i != length - 1)
            str += " ";
    }
    return str;
}

More

Probably so much common conversion process, there is a separate transfer function string array, you may be used sprintfformatted output, violence or cyclic modulo values to obtain a final result

Digital conversion and string can be a number ary
/**
 * @fn  std::string Utils_String::NumToString(int num, int width, int base)
 *
 * @brief   Number to string 整型数据 前补 0 占位符显示 进制 为 8 10 16 如果超过给出的宽度 原始宽度显示
 *
 * @author  IRIS_Chen
 * @date    2019/12/3
 *
 * @param   num     Number of
 * @param   width   The width
 * @param   base    The base
 *
 * @return  The total number of to string
 */
std::string Utils_String::NumToString(int num, int width, int base)
{
#if 0
    // 保证 存在进制 只考虑 2 8 , 10 16 进制
    static std::map<int, char> t_base = {
        { 2,'0' },
        { 8,'o' },
        { 10,'d' },
        { 16,'x' } };
    if (!t_base.count(base))
        return "";
    // 二进制 特殊处理
    if (base == 2)
    {
        std::string str_8 = NumToString(num, width, 8);
        //  设置8进制 转2进制码表, 转换之后 去除前缀0 即可
        static const std::vector<std::string> table = { "000","001","010","011","100","101","110","111" };

        std::string str_2 = "";
        for (auto s : str_8)
        {
            if(s =='0')
                continue;
            str_2 += table[s - '0'];
        }
        // 去掉前面所有的 0值 从1 开始
        int pos = static_cast<int>(str_2.find_first_of('1'));

        // #TODO(Schen00) 处理, 得到的长度小于width 的情况
        return pos == std::string::npos ?"":str_2.substr (pos);
    }

    std::string format = "%0" + std::to_string(width) + t_base.find(base)->second;

    char *buf = new char[20];
    sprintf(buf, format.c_str(), num);
    return std::string(buf);
#else
    std::string res = "";

    while (num)
    {
        res = base == 16 ? Num2Hex(num % base) : (num % base + '0') + res;
        num /= base;
    }

    // 不足位 补0  足位 不删除
    int cnt = width - res.size();
    while (cnt--)
    {
        res = '0' + res;
    }
    return res;
#endif
}

Guess you like

Origin www.cnblogs.com/hugochen1024/p/12570811.html