Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何解码重复的无符号MSB和LSB 8位字?_C++_C_Embedded - Fatal编程技术网

C++ 如何解码重复的无符号MSB和LSB 8位字?

C++ 如何解码重复的无符号MSB和LSB 8位字?,c++,c,embedded,C++,C,Embedded,我正在编写一个模块,它通过串口接收光谱仪的一些数据,并需要对其进行解码。根据手册,光谱数据在重复的无符号MSB和LSB 8位字中编码为512字节。我将如何在C/C++中对其进行解码 23–534在重复的无符号MSB和LSB 8位字中编码为512字节 [MSB]*256+[LSB] 这是手册中的一个片段 好的,我想在这个问题上加上另一部分。根据下面的评论,这是在大端。现在,我对它感到困惑的是,如果它确实是在big-endian中,那么转换成little-endian不是像反转所有字节的顺序那样简单

我正在编写一个模块,它通过串口接收光谱仪的一些数据,并需要对其进行解码。根据手册,光谱数据在重复的无符号MSB和LSB 8位字中编码为512字节。我将如何在C/C++中对其进行解码

23–534在重复的无符号MSB和LSB 8位字中编码为512字节 [MSB]*256+[LSB]

这是手册中的一个片段

好的,我想在这个问题上加上另一部分。根据下面的评论,这是在大端。现在,我对它感到困惑的是,如果它确实是在big-endian中,那么转换成little-endian不是像反转所有字节的顺序那样简单吗?如果是这样的话,那么它的输出基本上是这样的。。。LSB5、MSB5、LSB4、MSB4、LSB3、MSB3、LSB2、MSB2、LSB1、MSB1等,然后可以将其转换为16位字。我在这里出了什么问题


另外,如果这确实是big-endian,那么是否有任何本机(即使是特定于平台的,如果必要的话,但速度更快)方法来处理转换?

您需要将MSB和LSB存储到单个字中。例如:

uint8_t msb, lsb;
uint16_t word;

word = (msb << 8) | lsb;
uint8_t msb,lsb;
uint16_t单词;

word=(msb我有时是一个过度优化的人,所以尽管Fiddling Bits提供了一个完全合适的解决方案,但它有不必要的除法和不必要的分支。所以我在这里提供一个多余的答案

uint8_t byteArray[512];
uint16_t wordArray[256], word, byteIdx, wordIdx;

for (byteIdx=0, wordIdx=0; byteIdx < 511; )
{
    word = byteArray[byteIdx++] << 8;
    wordArray[wordIdx++] = word | byteArray[byteIdx++]
}
uint8_t byteArray[512];
uint16_t字数组[256],字,字节数,字IDX;
对于(byteIdx=0,wordIdx=0;byteIdx<511;)
{

word=byteArray[byteIdx++]您今天赢得了自己的名字。但是为什么不使用
byte&1
而不是
byte%2
?P.S.
byte
必须大于代码示例中的
uint8\t
。@MarkRansom您确定需要更大的类型吗?OP将数据描述为无符号MSB和LSB 8位字。512要大得多如果大于255,则
for
循环将永远不会终止。@MarkRansom为什么要使用按位和,当他想测试每个第n个字节时?从概念上讲,模运算符更好。您正在使用
byte
作为数组的索引。也许最好选择一个不同的名称。这种格式不正是16位无符号格式吗d big-endian?我不太理解你解释的数据格式。我说的从帧的23字节到534字节有256个16位宽(=2字节)对吗样本?如果是这样,那么每个样本的两个字节只能以两种方式排列。要么LSB在字节流中排在第一位,要么MSB在字节流中排在第一位。前一种情况是little endian,后一种情况是big endian。到目前为止,我已经理解了MSB在第一位,所以这将使样本成为big endian。要在little endian x上解码它们86台计算机,您必须逐个byteswap所有256个样本。至于“本机”函数,如果您在GCC上,您可以使用内置函数
uint16\u t\u builtin\u bswap16(uint16\u t x)
,不需要包含,如果您使用的是Visual Studio,您可以使用
unsigned short\u byteswap\u ushort(unsigned short val)
,只要你
#包含
。对于像字节切换这样简单的事情,任何一个好的编译器都可能检测到BSWAP指令中的移位和/或实现,并进行替换。使用这些内置代码只会让读者和编译器更清楚,从而可以更好地进行优化。Endianness只控制字节的顺序因此,小端16位流类似于
[LSB0][MSB0][LSB1][MSB1][LSB2][MSB2][LSB3][LSB4][MSB4]…
,而大端16位流类似于
[MSB0][LSB0][MSB1 LSB1 2][LSB2 MSB3][LSB3][MSB4][LSB4]…
玩得很好!我一直很欣赏优化。
uint8_t byteArray[512];
uint16_t wordArray[256], word, byteIdx, wordIdx;

for (byteIdx=0, wordIdx=0; byteIdx < 511; )
{
    word = byteArray[byteIdx++] << 8;
    wordArray[wordIdx++] = word | byteArray[byteIdx++]
}