[英]Data conversion from accelerometer
大家好,我正在使用bma220加速度傳感器,其數據表中的數據表示為2的補碼形式,所以我要做的就是將8位數據轉換為任何8位帶符號的char並完成。 bma220具有一個8位寄存器,其中前6位是數據,后兩位是零。
void properdata(int16_t *msgData)
{
printf("\nin proper data\n");
int16_t temp, i;
for(i=0; i<3; i++)
{
temp = *(msgData + i);
printf("temp = %d sense = %d\n", temp, sense);
temp = temp >> 2; // only 6 bits data
temp = temp / sense; //decimal value * .0625 = value in g
printf("temp = %d\n", temp);
}
}
在此程序中,我將數據存儲在無符號變量msgdata中,並對有符號變量進行所有計算。 我只需要知道這是否是轉換數據的正確方法?
經過一些建議,我將代碼更改為此
void properdata(uint16_t *msgData)
{
int arr[3];
arr[0] = msgData[0];
arr[1] = msgData[1];
arr[2] = msgData[2];
arr[0] = arr[0]/4;
arr[1] = arr[1]/4;
arr[2] = arr[2]/4;
printf("x = %d y = %d z = %d\n", arr[0], arr[1], arr[2]);
}
現在處於靜止狀態,我正在獲取61、60和17的數據。如果我認為數據應該在31到-32的范圍內,但是這里超出范圍了?
在此程序中,我將數據存儲在無符號變量msgdata中
不,你不是。 msgdata是一個帶符號的變量。
我只需要知道這是否是轉換數據的正確方法?
在有符號變量上使用按位運算符幾乎總是一個錯誤。 您對有符號變量執行右移,這是實現定義的行為,符號位會發生什么取決於編譯器。
我在您的代碼中看到兩個問題:
1)如Lundin所述,將負值向右移是危險的,因為行為是特定於編譯器的。
2)根據數據表,促進劑的范圍為1.94 ...- 2.00 g。 您嘗試將值存儲為純整數。 至少需要固定點算術(或浮點數)。 否則您的結果將只是1、0,-1或-2。
以下代碼應考慮到以下幾點(未經測試):
int16_t raw; // the 8 bit raw value from the chip
int32_t accel; // acceleration in mg
raw = (int16_t) read_value_from_chip(); // get 8 bits raw value from chip
accel = (int32_t)(raw / 4) * 625; // to avoid to shift to right, use division here
if ( accel >= 0 )
accel = ( accel + 5 ) / 10;
else
accel = ( accel - 5 ) / 10;
printf("%ld\n", accel);
說明:
根據數據表,分辨率為62.5 mg,而最高有效6位保留帶符號的原始值。
為了避免在將位放置到位時顯式處理符號,此處使用除法而不是右移。 使用除以4而不是>>2。這將按需保留符號。
如果負值向右移動時,如果編譯器/ MCU在左側1設置位,則優化的編譯器將通過移位替換該除法。 如果編譯器/ MCU不支持此功能,則將使用除法。
進行* 625以達到所需分辨率1/10 mg的加速度(1位為0.1 mg)。 625是0.0625 * 10000的縮寫。( 更新 )
為了得到毫克,加速度除以10(我在這里這樣做是因為毫克比0.1毫克更方便)。 為了正確四舍五入,必須在除法之前根據符號加/減一半的股息,此處為10/2 = 5。
結果以毫克為單位。
如果要避免除法,則在將有效位放入適當位置時必須顯式處理負/正值。
通常,規格表將包含一個或兩個示例轉換。 它可能顯示值0000 0000(二進制)為零,而0100 0000為47.25 g。 通過代碼運行示例值以進行驗證。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.