2013-12-13 46 views
3

我正在寫一個模塊,它通過串口接收光譜儀的一些數據並需要對其進行解碼。根據手冊重複無符號MSB和LSB 8位字的頻譜數據編碼爲512字節。我將如何在C/C++中解碼這個?如何解碼重複的無符號MSB和LSB 8位字?

23 - 534編碼爲重複無符號MSB 512字節和LSB 8位字 [MSB] * 256 + [LSB]。

這是手冊中的一個片段。

好的,我想在中添加另一部分到這個問題。根據下面的評論,這是在大端。現在,我對此感到困惑的是,如果它確實是大端的,那麼轉換爲小端就像轉換所有字節的順序一樣簡單?如果是這種情況,那麼對此的輸出本質上將是...... LSB5,MSB5,LSB4,MSB4,LSB3,MSB3,LSB2,MSB2,LSB1,MSB1等等,然後可以將其轉換爲16位字。我在這裏錯了什麼?另外,如果這確實是big-endian,那麼是否有任何原生(甚至是平臺特有的,如果有必要,但速度更快)方法來處理轉換?

+0

「重複MSB和LSB單詞」是什麼意思? – 2013-12-13 19:19:04

+0

@ H2CO3這是一個字節流,如下所示:'[MSB1] [LSB1] [MSB2] [LSB2] [MSB3] [LSB3] ...'。兩個字節必須組合成一個單詞:'[WRD1] [WRD2] [WRD3] ...'。 –

+5

難道這種格式正好是16位無符號的big-endian嗎? –

回答

5

我有時會過度優化,所以儘管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++] 
} 

的關鍵概念是移位的MSB字節最多8位(X < < 8等價於x * 256),則或/其添加到LSB,以形成16位字。其餘全部是索引管理。

+0

很好玩!我總是欣賞優化 –

+0

非常感謝! – Siddharth

4

您需要將MSB和LSB存儲爲一個單詞。例如:

uint8_t msb, lsb; 
uint16_t word; 

word = (msb << 8) | lsb; 

的這一個循環會是這個樣子:

uint8_t byteArray[512]; 
uint16_t wordArray[256], byteArrIdx; 

for(byteArrIdx = 0; byteArrIdx < 512; byteArrIdx++) 
{ 
    if((byte % 2) == 0) 
     wordArray[(byteArrIdx/2)] = byteArray[byteArrIdx] << 8; 
    else 
     wordArray[(byteArrIdx/2)] |= byteArray[byteArrIdx]; 
} 

注:

msb << 8msb * 256輸出相同。我更喜歡使用位移,因爲您的意圖對讀者更清楚。

+1

今天你贏得了你的名字。但是,爲什麼不使用'byte&1'而不是'byte%2'?附:你的代碼示例中'byte'需要比'uint8_t'大。 –

+0

@MarkRansom你確定需要更大的類型嗎? OP將數據描述爲*無符號MSB和LSB 8位字*。 –

+1

512遠大於255,'for'循環永遠不會終止。 – Casey