如何将原始数据转换为来自LSM303DLHC传感器的有用温度

时间:2017-05-16 10:04:28

标签: c embedded temperature

我使用STM32F4微控制器和HAL库。我想从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;
}

根据数据表,许多教程温度由此表达式计算:

temp =(int16_t)((data_h&lt;&lt; 8)| data_l);  temp = temp / 8;

我所在的房间大约是20摄氏度。我的函数返回大约128-136的值。

我在哪里弄错了?

提前谢谢你。

3 个答案:

答案 0 :(得分:1)

好吧,在我这边读取20 C房间的临时寄存器时,我得到以下值。

TH=255, TL=224

所以看起来寄存器的0值对应21 C(大约),当温度低于21 C(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

答案 1 :(得分: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。

最好的问候,Stefan

编辑: 小心数据类型!您尝试将字节值移动8.这不起作用。 用int:

定义你的值
int16_t data_h = 0;
int8_t data_l = 0;

然后使用:

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

Tipp:使用MS Windows计算器的编程模式,并使用二进制和十六进制和十进制数字。

答案 2 :(得分:0)

# python

# enable Temperature sensor 
bus.write_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_CRA_REG_M, 0x90)  

...
# read register
tempH = bus.read_byte_data(LSM303_ADDRESS_MAG, 0x31)
tempL = bus.read_byte_data(LSM303_ADDRESS_MAG, 0x32)
temp = (tempH << 8 ) +  tempL
if temp > 32767:  # 2's complement
    temp -= 65536
temperature = float( 20 + ( temp >> 4 )/ 8 )  # 16bit --> 12bit , 8LSB/deg