2

我正在編程我的Arduino微控制器,並且發現了一些用於接受加速度計傳感器數據供以後使用的代碼。除了下面的代碼我可以理解我想對發生的事情有一些直覺,但畢竟我的搜索和閱讀我無法將自己的頭圍繞在正在發生的事情上,並真正理解。加速度計代碼中的位移操作

我已經參加了C++課程,並且我們在按位操作或位移或任何您想調用的操作方面做得很少。讓我試着解釋我認爲我理解的內容,並且可以在需要的地方糾正我。

所以:

  1. 我認爲我們存儲X的值,其實相當肯定。
  2. 看來數組「buff」(槽號1)中的數據被設置爲整數的數據類型。
  3. 在時隙1的值被移位一位8位到左側。(這是否指向拋光輪時隙0?)

該新值被比較,以拋光輪時隙0,並且如果任一數據位是真的,那麼存儲在x中的數據中的位也將爲真,因此,在最終存儲值中0和1 = 1,0和0 = 0且1和0 = 1。

該代碼對所有三個軸都執行此操作:x,y,z但我不知道爲什麼......我需要幫助。在我進步之前,我想充分理解。

//each axis reading comes in 10 bit resolution, ie 2 bytes. 
// Least Significant Byte first!! 
//thus we are converting both bytes in to one int 
x = (((int)buff[1]) << 8) | buff[0]; 
y = (((int)buff[3]) << 8) | buff[2]; 
z = (((int)buff[5]) << 8) | buff[4]; 

回答

2

此代碼用於將原始加速度計數據(以6字節的數組形式)轉換爲三個10位整數值。正如評論所說,數據首先是LSB。那就是:

buff[0] // least significant 8 bits of x data 
buff[1] // most significant 2 bits of x data 
buff[2] // least significant 8 bits of y data 
buff[3] // most significant 2 bits of y data 
buff[4] // least significant 8 bits of z data 
buff[5] // most significant 2 bits of z data 

它使用位運算符2把兩個部分連成一個單一的變量。 類型轉換是不必要的,(恕我直言)混淆。這種簡化的表達式:

x = (buff[1] << 8) | buff[0]; 

注意到數據在buff[1],並且轉換它留下8位,然後在如此形成的空間把8個比特從buff[0]。讓我們標記10位a通過j例如起見:

buff[0] = cdefghij 
buff[1] = 000000ab 

然後:

buff[1] << 8 = ab00000000 

和:

buff[1] << 8 | buff[0] = abcdefghij 
+0

謝謝!我花了幾天的時間閱讀這些東西,而你和其他社區在不到15分鐘的時間裏爲我帶來了我的尤里卡時刻!你一步一步的解釋使得它更容易理解! – user2701295

+0

輸入數據(buff)也是二進制補碼,看起來Arduino微處理器在將位分配給我的版本中的'x'' y'' z'時會保持符號。這很混亂。 – mrmagooey

+0

@mrmagooey,你爲什麼不想保持這個標誌? –

1

在時隙1中的值被移位一位8位到左側。(這是否指向拋光輪時隙0?)

羅。按位運算符不是指針運算,不要混淆兩者。左邊N的位置(大致)相當於乘以2的N次方(除了C中的某些角落案例,但我們暫不討論這些情況)。

這個新的值正在被比較以拋光輪時隙0中的數據,並且如果任一比特爲真,則在存儲在x中的數據的比特也將是真

|是不邏輯OR運算符(這將是||),但按位或一個。所有代碼都將buff[0]buff[1]中的兩個字節合併爲一個單字節的2字節整數,其中buff[1]表示數字的MSB。

+0

非常感謝!我們能進一步深入嗎?這些位如何組合?如果我們以buff N的值取值並且移動8並且你如何表示,乘以2得到8的冪次,那麼它是如何結合的?如果我猜測......我們從16位或2個字節開始,並將前8位中的數據向左移,並用位移中的數據替換, 0?另外,你會解釋MSB嗎?我知道它代表最重要的字節,但這是我的知識程度。先謝謝你! – user2701295

+0

@ user2701295你的猜測乍一看似乎是正確的。最重要的字節:數字中具有最多「權重」的字節(其貢獻了該值)。 – 2013-08-20 20:49:07

+0

所以如果我們不關心精度,我們可以扔掉LSB?就像我們擁有數千萬的數字一樣,我們真的不會關心數百個地方的數字嗎?這是這個想法嗎? – user2701295

0

的裝置的結果是在6個字節,該字節需要是重新排列爲3個整數(具有最多隻能佔用10位的值)。

所以前兩個字節是這樣的:

00: xxxx xxxx <- binary value 
01: ???? ??xx 

的???部分不是結果的一部分,因爲xxx部分包含10位。我猜硬件是建立在這樣一種方式,???部分全是零位。

爲了將其轉換爲單個整數變量,我們需要全部8個低位加上高位2位,左移8位,以便它們不干擾低位8位。邏輯OR(| - 豎線)將這兩部分結合成一個整數,看起來像這樣:

x: ???? ??xx xxxx xxxx <- binary value of a single 16 bit integer 

其實沒關係的「廉政」有多大(位)的剩餘在這種情況下比特(超過16)將爲零。

0

擴大並澄清卡爾諾魯姆的答覆。

(int)類型轉換是必需的,因爲源是一個字節。在將結果保存到X之前,會對源數據類型執行bitshift。因此,必須將其轉換爲至少16位(int),以便位移8位,並在執行OR操作之前保留所有數據,並且結果保存。

代碼沒有告訴你的是,如果這應該是一個無符號整數或者如果在位數據中有符號。我期望 - 使用加速度計可以獲得數據。