PIC*_*ain 3 c embedded hex ascii
我正在为嵌入式设备工作C固件程序.我想通过串口发送一个十六进制字符值数组.有没有一种简单的方法将值转换为ASCII十六进制?
例如,如果数组包含0xFF,我想发送ASCII字符串"FF",或者对于十六进制值0x3B我想发送"3B".
这通常是怎么做的?
我已经有了串行发送功能,所以我可以这样做......
char msg[] = "Send this message";
SendString(msg);
Run Code Online (Sandbox Code Playgroud)
并且SendString函数为传递的数组中的每个元素调用此函数:
// This function sends out a single character over the UART
int SendU( int c)
{
while(U1STAbits.UTXBF);
U1TXREG = c;
return c;
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找一个可以让我这样做的功能......
char HexArray[5] = {0x4D, 0xFF, 0xE3, 0xAA, 0xC4};
SendHexArray(HexArray);
//Output "4D, FF, E3, AA, C4"
Run Code Online (Sandbox Code Playgroud)
Mar*_*iot 17
使用编号将数字写入字符串sprintf
,然后使用现有SendString
函数通过UART发送.当然,您可以一次执行以下操作:
char num_str[3];
sprintf( num_str, "%02X", 0xFF );
SendString(num_str);
Run Code Online (Sandbox Code Playgroud)
%02X
是一个格式字符串的printf
函数系列,它说垫以0的元件直到宽度2和格式化元件作为十六进制数.
该02
部件确保当您想要打印时0x0F
,0F
而不仅仅是F
在输出流中.如果您使用小写字母,x
您将获得小写字符(例如,ff
而不是FF
).
RBe*_*eig 10
汇编语言时代8位微观的经典技巧是将nybble的转换分为两个部分.值为0到9,值为10到15.然后简单算术保存16字节查找表.
void SendDigit(int c) {
c &= 0x0f;
c += (c <= 9) ? '0' : 'A'-10;
SendU(c);
}
void SendArray(const unsigned char *msg, size_t len) {
while (len--) {
unsigned char c = *msg++;
SendDigit(c>>4);
SendDigit(c);
}
}
Run Code Online (Sandbox Code Playgroud)
有几个附注是有序的.首先,这是有效的,因为数字和字母在ASCII中都是连续的跨度.如果你不幸想要EBCDIC,这仍然有效,因为字母'A'到'F'也是连续的(但字母表的其余部分分为三个跨度).
其次,我改变了签名SendArray()
.我的版本小心地使缓冲区无符号,这通常在计划将字节提升为更大的整数类型以进行算术时更安全.如果它们是签名的,那么代码nibble[(*msg)>>4]
可能会尝试在数组中使用负索引,结果将完全无用.
最后,我添加了一个长度参数.对于一般的二进制转储,您可能没有任何有意义的字节值用作结束标记.为此,计数更有效.
编辑:修正了一个错误:对于超过10的数字,算术是c + 'A' - 10
,而不是c + 'A'
.感谢Brooks Moses抓住了这一点.
我将从数组查找开始.
char *asciihex[] = {
"00", "01", "02", ..., "0F",
"10", "11", "12", ..., "1F",
...,
"F0", "F1", "F2", ..., "FF"
};
Run Code Online (Sandbox Code Playgroud)
然后简单地查一下......
SendString(asciihex[val]);
Run Code Online (Sandbox Code Playgroud)
编辑
结合Dysaster的小吃理念:
void SendString(const char *msg) {
static const char nibble[] = {'0', '1', '2', ..., 'F'};
while (*msg) {
/* cast to unsigned char before bit operations (thanks RBerteig) */
SendU(nibble[(((unsigned char)*msg)&0xf0)>>4]); /* mask 4 top bits too, in case CHAR_BIT > 8 */
SendU(nibble[((unsigned char)*msg)&0x0f]);
msg++;
}
}
Run Code Online (Sandbox Code Playgroud)