关于将内存读取字节转为十六进制ASCII字符的技术问询
解决方案:将存储器读取的字节转为十六进制ASCII字符发送
我明白你要做的是:把从EEPROM/FLASH读取的单个字节,转换成它的十六进制表示对应的两个ASCII字符(比如0xA0变成'A'和'0')发送给计算机,而不是发送字节本身的数值。结合你给出的奇偶校验代码片段,我整理了完整的实现方案:
核心:半字节转十六进制ASCII
首先我们需要一个辅助函数,把4位的半字节(nibble)转换成对应的十六进制ASCII字符,这是整个转换的基础:
// 将4位半字节转换为十六进制ASCII字符(0-9→'0'-'9',10-15→'A'-'F') uint8_t nibble_to_ascii(uint8_t nibble) { nibble &= 0x0F; // 确保只保留低4位,避免高位干扰 return nibble <= 9 ? (nibble + '0') : (nibble - 10 + 'A'); }
完整字节转双ASCII字符
有了上面的辅助函数,我们可以把整个字节拆成高4位和低4位,分别转换:
// 将单个字节转换为两个十六进制ASCII字符,高4位对应第一个字符,低4位对应第二个 void byte_to_hex_ascii(uint8_t byte, uint8_t *ascii_high, uint8_t *ascii_low) { *ascii_high = nibble_to_ascii(byte >> 4); // 右移4位取高4位 *ascii_low = nibble_to_ascii(byte); // 直接取低4位(自动截断) }
结合存储器读取与发送流程
假设你已经有读取存储器的函数read_memory和发送字符到计算机的函数send_char,可以这样把整个流程串起来:
// 示例:读取指定地址的字节,转成十六进制ASCII后发送 void process_memory_byte(uint16_t mem_addr) { uint8_t raw_byte = read_memory(mem_addr); uint8_t ascii_high, ascii_low; byte_to_hex_ascii(raw_byte, &ascii_high, &ascii_low); // 先发送高半字节的ASCII,再发送低半字节的 send_char(ascii_high); send_char(ascii_low); }
补全你提到的奇偶校验函数
你给出的unAddParitytoByte代码没写完,我假设你要实现的是给字节添加奇校验位(如果需要偶校验可以调整逻辑),补全后的代码如下:
uint8_t unAddParitytoByte(uint8_t unByte) { uint8_t unNumberofOnes = 0; // 统计字节中1的个数 for(uint8_t unI = 0x80; unI != 0; unI >>= 1) { if (unByte & unI) { unNumberofOnes++; } } // 奇校验:如果1的个数是偶数,最高位置1;否则保持0 if ((unNumberofOnes % 2) == 0) { unByte |= 0x80; } else { unByte &= ~0x80; } return unByte; }
如果需要先做奇偶校验再转换ASCII,只需要修改process_memory_byte即可:
void process_memory_byte_with_parity(uint16_t mem_addr) { uint8_t raw_byte = read_memory(mem_addr); uint8_t parity_byte = unAddParitytoByte(raw_byte); // 先加校验位 uint8_t ascii_high, ascii_low; byte_to_hex_ascii(parity_byte, &ascii_high, &ascii_low); send_char(ascii_high); send_char(ascii_low); }
额外小提示
- 如果需要小写的十六进制字符(比如'a'代替'A'),只需要把
'A'改成'a'就行。 - 确保你的
send_char函数能正确处理ASCII字符发送,比如通过UART串口发送时,要匹配好波特率等参数。 - 批量处理多个字节的话,套个循环调用
process_memory_byte就可以了。
内容的提问来源于stack exchange,提问作者BetaEngineer
相关产品推荐
相关产品推荐

