2011-11-21 26 views
1
i2c_receiveData(sDevice *psDevice, byte_t *pbBuffer, uint16_t *puiLen) 
{ 
. 
.  
//extract the packet data length 
unFrameLen = (*(pbBuffer+1) << 8) | *(pbBuffer + 2); 
if(unFrameLen > *puiLen) 
unFrameLen=*puiLen; 
. 
. 
} 

這裏聲明如何找到幀長?左移或

unFrameLen =(*(pbBuffer + 1)< < 8)| *(pbBuffer + 2);

這裏pbBuffer是一個指向unsigned char數組的指針。

調用函數是,

i2c_receiveData(psDevice, prgDataRecv, &unRegLen); 

回答

4

在這種情況下,看起來「幀長度」存儲在偏移量1到傳遞的緩衝區中。

它也看起來是一個16位整數。

爲了得到一個可用的16位整數,你必須從緩衝區中解壓縮。最好是使用htons/ntohs來代替,但我認爲架構是衆所周知的,可移植性不是問題。

有關,比如說,pbBuffer = {0, 1, 2}的輸入端,該結束是:

(1 << 8) | 2; 

...其給出:

(00000001b << 8) | 00000010b 

...換檔1b左8位給出:

100000000b 

...與10b和的OR-ing:

100000010b 

現在你必須從兩個8位整數的16位整數pbBuffer[1..2]

100000010b = 0x102 
+0

+1,特別是對'htons()'引用。 – sarnold

+0

這意味着幀長度是258? – SHRI

+0

對於這些輸入,是的。 –

2

顯然,幀長度被在第二和第三字節的協議發送。該表達式從2個字節構建出16位整數。

*(pbBuffer+x)pbBuffer[x]相同,所以字節#1被左移8,並且字節#2被添加到它。

如果您收到您的pbBuffer,例如, { 0000 0000, 0101 0101, 1100 1100, ...}(二進制),提取的兩個字節將是

*(pbBuffer+1) = 0101 0101 
*(pbBuffer+2) = 1100 1100 

計算將是

*(pbBuffer+1) << 8     = 0101 0101 0000 0000 
(*(pbBuffer+1) << 8) | *(pbBuffer+2) = 0101 0101 1100 1100 

的逐位或(|)是相同的這裏的加成由於低8位(*(pbBuffer+1) << 8)都是0.

請注意,細節取決於平臺上的一點。

+0

謝謝你的詳細解答。以上的列位幫助我很好地理解了 – SHRI

1

除了把語句拆分成更小的碎片:

*(pbBuffer+1)  /* gets the byte_t value one beyond the pbBuffer pointer */ 
(*(pbBuffer+1) << 8) /* shifts that byte eight bits left -- in essence 
         xxxxxxxx00000000 -- where xxx comes from pbBuffer+1 */ 


*(pbBuffer+2)  /* gets the byte_t value two beyond the pbBuffer pointer */ 

(*(pbBuffer+1) << 8) | *(pbBuffer + 2) 
/* xxxxxxxx00000000 | yyyyyyyy */ 
    xxxxxxxxyyyyyyyy */ 

這將指定的兩個字節重建爲單個16位數據類型。這些 類型的操作在處理聯網 代碼時尤爲常見,因爲不同的機器有不同的byte orders。不同的訂單意味着大於一個字節的數字不能在網絡上輕鬆傳遞,而不使用network byte order 作爲中間格式。 (有些電腦工作在網絡字節 本地訂購,而其他人必須始終執行轉換。)