为什么拆分高低字节而不直接存入数组

发布于:2025-05-09 ⋅ 阅读:(20) ⋅ 点赞:(0)

您的代码片段是在将一个16位值()拆分为高字节和低字节:IR_RF_Signal.length

temp_low = IR_RF_Signal.length & 0xFF;  
temp_high = IR_RF_Signal.length >> 8;  

虽然我在 PX4-Autopilot 仓库中没有找到这段确切的代码,但这是嵌入式系统中的常见做法,特别是在处理通信协议时。这么做的原因主要有以下几点:

1. 通信协议的数据包格式

在大多数低级通信协议中(如UART、SPI、I2C等),数据是按字节一个一个传输的。当需要传输一个多字节的值(如16位的长度值)时,必须将其拆分成单个字节进行传输。拆分成高低字节是标准做法。

2. 字节序(Endianness)考虑

不同的系统可能使用不同的字节序(大端序或小端序)。通过明确地将值拆分为高字节和低字节,可以确保通信双方以相同的方式解释数据,避免字节序差异导致的问题。

3. 内存效率

在资源受限的嵌入式系统中,明确控制每个字节如何存储和传输可以提高内存和带宽效率。

4. 协议兼容性

很多通信协议有特定的数据包格式要求,必须按照固定的格式构造数据包。拆分高低字节是遵循这些格式要求的一种方式。

为什么不直接用数组?

您问为什么不能直接将值存入数组。技术上来说,可以这样做:

uint8_t length_bytes[2];  
length_bytes[0] = IR_RF_Signal.length & 0xFF;  // 低字节  
length_bytes[1] = IR_RF_Signal.length >> 8;    // 高字节  

或者使用联合体(union)或结构体指针转换。但是,明确地拆分为独立变量有几个优势:

  1. 代码可读性更高,明确表示这是长度值的高字节和低字节
  2. 避免可能的内存对齐问题
  3. 在某些情况下可能需要单独处理这些字节,如添加到不同的数据包位置

注意事项

这种拆分方式实际上是在实现小端序(little-endian)的字节序,即低字节在前,高字节在后。如果接收方期望大端序(big-endian),则应该调整存储顺序。

为什么需要将IR_RF_Signal.length拆分成高低字节

在嵌入式系统中,经常需要将多字节数据拆分成单字节进行存储或传输,这段代码就是这样的一个例子。

原因是是一个16位的无符号整数(),而是一个8位字节()的数组:IR_RF_Signal.length uint16_tW25Q64_Bufferuint8_t

volatile uint8_t W25Q64_Buffer[4096] = {0};

在函数中,需要将16位的值存储到这个8位的缓冲区中:Module_IR_RF_Copy_To_Bufferlength

temp_low = IR_RF_Signal.length & 0xFF; temp_high = IR_RF_Signal.length >> 8; W25Q64_Buffer[0] = temp_low; W25Q64_Buffer[1] = temp_high;

这样做的原因是:

  1. W25Q64闪存芯片的接口是基于字节操作的,每次只能读写8位数据
  2. 必须将16位的值分解成两个8位字节才能存储length
  3. 使用获取低8位,使用获取高8位& 0xFF>> 8

同样地,程序也对数组中的每个16位值进行了类似的拆分:duration

for (i = 0; i < IR_RF_Signal.length; i++) {  
    temp_low = IR_RF_Signal.duration[i] & 0xFF;  
    temp_high = IR_RF_Signal.duration[i] >> 8;  
    W25Q64_Buffer[i * 2 + 2] = temp_low;  
    W25Q64_Buffer[i * 2 + 3] = temp_high;  
}

反过来,当从闪存读取数据时,也需要将两个字节重新组合成一个16位值:

temp_low = W25Q64_Buffer[0];  
temp_high = W25Q64_Buffer[1];  
IR_RF_Signal.length = (temp_high << 8) | temp_low;

这种拆分和重组16位值的方法在嵌入式系统和通信协议中非常常见,特别是在处理跨字节边界的多字节数据时。

注意

如果想直接存储在数组中而不拆分,那么需要使用uint16_t类型的缓冲区,但W25Q64闪存的接口是基于字节(8位)作的,所以最终在与硬件交互时仍然需要进行字节拆分。


网站公告

今日签到

点亮在社区的每一天
去签到