2017-05-16 37 views
0

我使用STM32F4微控制器和HAL庫。我想從LSM303DLHC傳感器讀取溫度。以下代碼負責此任務。如何將原始數據轉換爲來自LSM303DLHC傳感器的有用溫度

LSM303DLHC_Status_t LSM303DLHC_get_temp(int16_t *temp) 
{ 
    uint8_t data_h = 0x00; 
    uint8_t data_l = 0x00; 
    uint16_t data_tmp = 0x00; 
    uint8_t temp_enable = 0x00; 

    if (HAL_I2C_Mem_Read(&hi2c1, LSM303_MAGNE_ADDRESS, TEMP_OUT_H_M, 1, &data_h, 1, 100) != HAL_OK) 
    { 
     return LSM303DLHC_ERROR; 
    } 

    if (HAL_I2C_Mem_Read(&hi2c1, LSM303_MAGNE_ADDRESS, TEMP_OUT_L_M, 1, &data_l, 1, 100) != HAL_OK) 
    { 
     return LSM303DLHC_ERROR; 
    } 

    data_tmp = (int16_t)((data_h << 8) | data_l); 

    *temp = data_tmp/8; 

    /*Enable temperature sensor*/ 
    if (HAL_I2C_Mem_Read(&hi2c1, LSM303_MAGNE_ADDRESS, CRA_REG_M, 1, &temp_enable, 1, 100) != HAL_OK) 
    { 
     return LSM303DLHC_ERROR; 
    } 

    temp_enable |= (0x01 << 7); 

    if (HAL_I2C_Mem_Write(&hi2c1, LSM303_MAGNE_ADDRESS, CRA_REG_M, 1, &temp_enable, 1, 100) != HAL_OK) 
    { 
     return LSM303DLHC_ERROR; 
    } 
    /*End enable temperature sensor*/ 

    return LSM303DLHC_OK; 
} 

根據數據片和許多教程溫度由該表達式計算:

溫度=(int16_t)((data_h < < 8)| DATA_L); temp = temp/8;

在我所在的房間裏大約是20攝氏度。我的函數返回大約128-136的值。

我在哪裏犯錯?

謝謝您提前。

+0

讀值和*然後*使傳感器看起來很奇怪。不應該在啓用和禁用之間進行讀取嗎?也許有一些延遲,如果傳感器啓用後需要時間產生讀數。 – unwind

+0

代碼可以在移入符號位時調用未定義的行爲。 – Olaf

+0

必須啓用每個測量溫度傳感器之後。第一次啓用LSM303DLHC_init_temp()中的溫度傳感器,然後在每次測量之後,我還啓用了溫度傳感器。在從寄存器讀取(HAL_I2C_MEM_READ)之前,我嘗試啓用溫度傳感器,但結果相同。 –

回答

0

你的值是一個12位的值,但你把它當作一個16位的值處理。

在LSM303DLHC數據表溫度寄存器被示出這樣的: TEMP_OUT_H_M(31H),TEMP_OUT_L_M(32H)

高寄存器:TEMP11,TEMP10,...,TEMP4 低寄存器:TEMP3,TEMP2, TEMP1,TEMP0, - , - , - , -

前4位(LSB(!))沒有溫度值。

你寫的時候你的臨時值大約是0x130(128-136)。在二進制中,它是 0000 0001 0011 0000. 前四位不相關。所以你必須讀取0000 0001 0011,它是0x13,它是十進制的19。

最好的問候,斯特凡

編輯: 小心數據類型!您嘗試將字節值移位8.這不起作用。 與詮釋定義你的價值觀:

int16_t data_h = 0; 
int8_t data_l = 0; 

然後使用:

*temp = ((int16_t)((data_h << 8) | data_l)>>4); 

蒂普:使用MS Windows計算器的編程模式,並與二進制和十六進制和十進制數字播放。

+0

我已經介紹了您的建議,但它仍然無法正常工作IMO。 現在函數返回溫度約50-60攝氏度。在我的房間裏大約是20攝氏度。 –

0

好了,就在我身邊,我得到了下面的值,當我在20中讀出在一間臨時寄存器C.

TH=255, TL=224 

如此看來,從寄存器中的0值對應於21℃(約。),我可以當溫度下21℃下使用代碼得到正確的值(TH位7設置爲1):

printf("TH=%d, TL=%d\n", RegVal[0], RegVal[1]); 
int16_t IntTemp = ((int16_t)RegVal[0] << 8) + RegVal[1]; 

printf("temp=%0.2f\n", (float)IntTemp/128 + 21); 

溫度= 20.75