Arduino16进制字符串转ASCII(下)-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 4782|回复: 0

Arduino16进制字符串转ASCII(下)

[复制链接]
发表于 2021-6-20 00:18 | 显示全部楼层 |阅读模式
本帖最后由 topdog 于 2021-6-20 22:31 编辑

Arduino16进制字符串转ASCII(上)(简称:上文)基础上,举一反三,超越自我,提高难度,有一长串十六进制数字“48454C4C4F20574F524C4421”要求每两位以”0x“样式输出,再翻译成ASCII码整句打印。

输出的效果如下:
toCharArray.jpg

涉及的知识点:
1,String 转化成 char char_array[str_len],在Arduino String组函数中有自带的函数String.toCharArray(char_array, str_len),String函数中计算字符串的长度函数是String.length(),索引开始默认值为0,所以字符串实际长度要加一。
2,十六进制字符串转化成byte值一维数组,把字符串两位截取,程序中提供了两种截取方法,大家可以玩味一下。1 byte = 4 bit ,字符对应出相应的十进制数值,计算机在最后编译时会换算成对应的bit值,在此没有采用上文中计算求值的方法,而是用了十位的左移四位bit值再或个位bit值,这是bit计算方法来实现的。
3,ASCII 十六进制输出显示,在Arduino中数值都是用byte值来储存的,只有在显示时才有所不同。譬如前两位字符串48,通过计算求得十六进制对应的byte值是01001000被存储在芯片里面,如果要求十六进制输出就是:Serial.println(ASCIINumberByte[0], HEX),为了符合书写习惯前面加上”0x“,就是0x48。十进制输出就是:Serial.println(ASCIINumberByte[0],DEC),输出就是72。
4,byte值转化成ASCII对应的char输出,以H为例,char H = char 01001000,遍历第二步求得的byte值一维数组ASCIINumberByte[12],那么就把十六进制数字字符串翻译成ASCII打印来了。结果是:HELLO WORLD!
5,十六进制转化成十进制的第三种方法自定义函数char HexChangeDec(char ch),这个有些繁琐,其他两种参见《串口接收十六进制代码控制点灯》一文。

实现的程序:
[pre]void setup() {
  Serial.begin(115200);
  while (!Serial);

  String inputString = "48454C4C4F20574F524C4421";

  int str_len = inputString.length() + 1;
  char char_array[str_len];

  int ASCIINumber_len = str_len / 2;
  byte ASCIINumberByte[ASCIINumber_len];

  /*
    inputString.toCharArray(char_array, str_len);

    for (char i = 0; i < str_len; i++)
    {
    byte extract;
    char a = char_array[2 * i];
    char b = char_array[2 * i + 1];
    extract = HexChangeDec(a) << 4 | HexChangeDec(b);
    ASCIINumberByte = extract;
    }
  */

  for (char i = 0; i < str_len; i++)
  {
    byte extract;
    char a = inputString.charAt(2 * i);
    char b = inputString.charAt(2 * i + 1);;
    extract = HexChangeDec(a) << 4 | HexChangeDec(b);
    ASCIINumberByte = extract;
  }

  for (int j = 0 ; j < ASCIINumber_len; j++) {
    Serial.print("0x");
    Serial.println(ASCIINumberByte[j], HEX);
  }

  
  for (int k = 0 ; k < ASCIINumber_len; k++) {
    Serial.print(char (ASCIINumberByte[k]));
  }  
  Serial.println("");

  delay(100);
}

void loop() {
  ;
}

char HexChangeDec(char ch)
{
  char returnType;
  switch (ch)
  {
    case '0':
      returnType = 0;
      break;
    case  '1' :
      returnType = 1;
      break;
    case  '2':
      returnType = 2;
      break;
    case  '3':
      returnType = 3;
      break;
    case  '4' :
      returnType = 4;
      break;
    case  '5':
      returnType = 5;
      break;
    case  '6':
      returnType = 6;
      break;
    case  '7':
      returnType = 7;
      break;
    case  '8':
      returnType = 8;
      break;
    case  '9':
      returnType = 9;
      break;
    case  'A':
      returnType = 10;
      break;
    case  'B':
      returnType = 11;
      break;
    case  'C':
      returnType = 12;
      break;
    case  'D':
      returnType = 13;
      break;
    case  'E':
      returnType = 14;
      break;
    case  'F' :
      returnType = 15;
      break;
    default:
      returnType = 0;
      break;
  }
  return returnType;
}[/pre]

写帖子的时间是6月20日,是父亲节,那么把“Happy father's day to all the daddys in the world!”翻译成十六进制的字符串呢?开源程序代码,其他就不反反覆覆,重规迭矩。

toCharArray.jpg


[pre]void setup() {
  Serial.begin(115200);
  while (!Serial);

  String inputString = "Happy father's day to all the daddys in the world!";
  int str_len = inputString.length() + 1;
  char char_array[str_len];
  inputString.toCharArray(char_array, str_len);

  Serial.println(char_array);
  delay(100);

  for (int i = 0 ; i < str_len - 1; i++) {
    Serial.print( char_array, HEX);
  }
  Serial.println();
  delay(100);
}

void loop() {
  ;
}[/pre]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 02:49 , Processed in 0.439786 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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