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

如何将原始数据转换为来自LSM303DLHC传感器的有用温度,c,embedded,microcontroller,temperature,hal,C,Embedded,Microcontroller,Temperature,Hal,我使用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(

我使用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;
}
LSM303DLHC_状态_t LSM303DLHC_获取_温度(int16_t*temp)
{
uint8_t数据_h=0x00;
uint8数据=0x00;
uint16\u t数据\u tmp=0x00;
uint8温度启用=0x00;
如果(HAL_I2C_Mem_Read(&hi2c1,LSM303_MAGNE_ADDRESS,TEMP_OUT_H_M,1,&data_H,1100)!=HAL_OK)
{
返回LSM303DLHC_错误;
}
如果(HAL_I2C_Mem_Read(&hi2c1,LSM303_MAGNE_ADDRESS,TEMP_OUT_L_M,1,&data_L,1100)!=HAL_OK)
{
返回LSM303DLHC_错误;
}

data_tmp=(int16_t)((data_h您的值是12位的值,但您将其视为16位的值

在LSM303DLHC数据表中,温度寄存器如下所示: 温升(31小时)、温升(32小时)

高位寄存器: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);
*temp=((int16)t)((数据>4);

提示:使用MS Windows计算器的编程模式,玩二进制、十六进制和十进制数字。

好吧,在我这方面,当我在20摄氏度的房间里读取温度寄存器时,我得到以下值

TH=255, TL=224
因此,寄存器中的0值似乎对应于21摄氏度(约),当温度低于21摄氏度时,我可以使用代码获得正确的值(第7位设置为1):

printf(“TH=%d,TL=%d\n”,RegVal[0],RegVal[1]);
int16_t IntTemp=((int16_t)RegVal[0]
#python
#启用温度传感器
总线写入字节数据(LSM303地址、LSM303寄存器、CRA寄存器、0x90)
...
#读寄存器
tempH=总线读取字节数据(LSM303地址MAG,0x31)
tempL=总线。读取字节数据(LSM303地址MAG,0x32)
temp=(tempH 32767:#2的补码)
温度-=65536
温度=浮动(20+(温度>>4)/8)#16位-->12位,8LSB/度

读取值然后启用传感器看起来很奇怪。读数不应该在启用和禁用之间吗?如果启用后传感器需要时间产生读数,可能也会有一些延迟。当切换到符号位时,代码可能会调用未定义的行为。每次测量后,温度传感器必须被启用。我第一次在LSM303DLHC_init_temp()中启用温度传感器,然后在每次测量之后,我也启用了温度传感器。在从寄存器读取之前,我尝试启用温度传感器(HAL_I2C_MEM_read)但是结果是一样的。我已经介绍了你的建议,但在我看来它仍然不能正常工作。现在函数返回的温度大约为50-60摄氏度。在我的房间里大约是20摄氏度。数据的地址是用来读取数据的。更改类型可能会导致问题。相反,
data\u h
应该转换为
uint16\u t
在转换之前。只添加代码回答是可以的,但是如果您添加一条关于此代码如何修复错误的注释,那就太好了!
TH=255, TL=224
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);
# 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