|
本帖最后由 topdog 于 2021-6-20 22:31 编辑
在Arduino16进制字符串转ASCII(上)(简称:上文)基础上,举一反三,超越自我,提高难度,有一长串十六进制数字“48454C4C4F20574F524C4421”要求每两位以”0x“样式输出,再翻译成ASCII码整句打印。
输出的效果如下:
涉及的知识点:
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!”翻译成十六进制的字符串呢?开源程序代码,其他就不反反覆覆,重规迭矩。
[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] |
|