【发布时间】:2014-05-04 11:40:34
【问题描述】:
我正在编写一个模块,该模块通过串行端口从光谱仪接收一些数据并需要对其进行解码。根据手册,频谱数据在重复无符号 MSB 和 LSB 8 位字中编码为 512 字节。我将如何在 C/C++ 中对此进行解码?
23 – 534 编码为 512 字节,重复无符号 MSB 和 LSB 8 位字 [MSB]*256 + [LSB]。
这是手册中的 sn-p。
好的,我想在这个问题中添加另一部分。根据下面的评论,这是大端的。现在,我对此感到困惑的是,如果它确实是 big-endian,那么转换为 little-endian 不会像反转所有字节的顺序一样简单吗?如果是这种情况,那么输出本质上类似于... LSB5、MSB5、LSB4、MSB4、LSB3、MSB3、LSB2、MSB2、LSB1、MSB1 等等,然后可以转换为 16位的话。我在这里有什么问题?
另外,如果这确实是大端,是否有任何本地(如果需要,甚至是特定于平台,但更快)的方法来处理转换?
【问题讨论】:
-
这种格式不正是 16 位无符号大端序吗?
-
我不太了解您解释的数据格式。我说的对吗?从 frame 的字节 23 到 534 有 256 个 16 位宽(= 2 字节)samples?如果是这样,那么每个样本的两个字节只有两种排列方式。LSB 在字节流中排在第一位,或者 MSB 在位。前一种情况是little-endian,后一种情况是big-endian。到目前为止,我已经理解 MSB 是第一位的,所以这会使样本大端。要在 little-endian x86 机器上解码它们,您必须 单独 对所有 256 个样本进行字节交换。
-
至于“native”函数,如果你使用 GCC,你可以使用内置函数
uint16_t __builtin_bswap16 (uint16_t x),它不需要包含,如果你使用 Visual Studio,你可以使用unsigned short _byteswap_ushort(unsigned short val),前提是你#include <stdlib.h>。 -
对于像字节交换这样简单的事情,任何体面的编译器都可能检测移位和或实现并替换 BSWAP 指令。使用这些内置函数只会让读者和编译器更清楚,因此可能会更好地优化。
-
字节序仅控制 sample 中 bytes 的顺序,而不是 samples 中 samples 的顺序i>帧。因此,小端 16 位流类似于
[LSB0][MSB0] [LSB1][MSB1] [LSB2][MSB2] [LSB3][MSB3] [LSB4][MSB4]...,而大端 16 位流类似于[MSB0][LSB0] [MSB1][LSB1] [MSB2][LSB2] [MSB3][LSB3] [MSB4][LSB4]...