AnsweredAssumed Answered

Problem reading registers with HAL_I2C_Mem_Read(_IT)() and temperature sensor LM75B

Question asked by Dimitris Paraskevopoulos on Sep 17, 2017
Latest reply on Sep 17, 2017 by Dimitris Paraskevopoulos

I have an STM32F401RE-Nucleo board and I have bought the mbed Application Shield to toy with the STM ecosystem.

 

Lately I have been trying to talk to the temperature sensor LM75B and I have achieved some success by being able to read the temperature register which is also the default register by using a call to HAL_I2C_Mem_Read and HAL_I2C_Mem_Read_IT. My problem is that I can't seem to be able to read the configuration register, the hysteresis register and the overtemperature shutdown register.

 

My code is this:

 

main.c

/* Includes ------------------------------------------------------------------*/
#include "main.h"

#define I2C_ADDRESS        0x90

I2C_HandleTypeDef I2cHandle;

/* Buffer used for reception */
uint8_t aRxBuffer[512];
/* Private function prototypes -----------------------------------------------*/
static void SystemClock_Config(void);
static void Error_Handler(void);

int main(void)
{
  volatile float temp = 0.0;     /* Temperature */
  volatile float thyst = 0.0;     /* Hysteresis register default 75deg C */
  volatile float tos = 0.0;     /* Overtemperature shutdown default 80deg C */

  HAL_Init();
 
  /* Configure LED2 */
  BSP_LED_Init(LED2);

  /* Configure the System clock to 84 MHz */
  SystemClock_Config();
 
  /*##-1- Configure the I2C peripheral ######################################*/
  I2cHandle.Instance             = I2Cx;

  I2cHandle.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;
  I2cHandle.Init.ClockSpeed      = 100000;
  I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  I2cHandle.Init.DutyCycle       = I2C_DUTYCYCLE_16_9;
  I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  I2cHandle.Init.NoStretchMode   = I2C_NOSTRETCH_DISABLE;
  I2cHandle.Init.OwnAddress1     = 0;
  I2cHandle.Init.OwnAddress2     = 0xFE;

  if(HAL_I2C_Init(&I2cHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }

  /* Infinite loop */
  while (1)
  {
       /*##-4- Put I2C peripheral in reception process ############################*/
       do
       {
         if(HAL_I2C_Mem_Read_IT(&I2cHandle, (uint16_t)I2C_ADDRESS, 0, I2C_MEMADD_SIZE_8BIT, (uint8_t *)&aRxBuffer[0], 8) != HAL_OK)
         {
           /* Error_Handler() function is called in case of error. */
           Error_Handler();
         }

         /* When Acknowledge failure occurs (Slave don't acknowledge its address)
         Master restarts communication */

       }
       while(HAL_I2C_GetError(&I2cHandle) == HAL_I2C_ERROR_AF);

       while (HAL_I2C_GetState(&I2cHandle) != HAL_I2C_STATE_READY)
       {
       }
          /* Convert register data to temperatures */
       temp = 0.125*(aRxBuffer[0]*8.0+ (aRxBuffer[1]>>5));
       thyst = 0.125*(aRxBuffer[4]*8.0+ (aRxBuffer[5]>>5));
       tos = 0.125*(aRxBuffer[6]*8.0+ (aRxBuffer[7]>>5));

       BSP_LED_Toggle(LED2);
       HAL_Delay(500);

  }
}

main.h

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#include "stm32f4xx_nucleo.h"

/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* User can use this section to tailor I2Cx/I2Cx instance used and associated
   resources */

/* Definition for I2Cx clock resources */
#define I2Cx                             I2C1
#define I2Cx_CLK_ENABLE()                __HAL_RCC_I2C1_CLK_ENABLE()
#define I2Cx_SDA_GPIO_CLK_ENABLE()       __HAL_RCC_GPIOB_CLK_ENABLE()
#define I2Cx_SCL_GPIO_CLK_ENABLE()       __HAL_RCC_GPIOB_CLK_ENABLE()

#define I2Cx_FORCE_RESET()               __HAL_RCC_I2C1_FORCE_RESET()
#define I2Cx_RELEASE_RESET()             __HAL_RCC_I2C1_RELEASE_RESET()

/* Definition for I2Cx Pins */
#define I2Cx_SCL_PIN                    GPIO_PIN_8
#define I2Cx_SCL_GPIO_PORT              GPIOB
#define I2Cx_SCL_AF                     GPIO_AF4_I2C1
#define I2Cx_SDA_PIN                    GPIO_PIN_9
#define I2Cx_SDA_GPIO_PORT              GPIOB
#define I2Cx_SDA_AF                     GPIO_AF4_I2C1

/* Definition for I2Cx's NVIC */
#define I2Cx_EV_IRQn                    I2C1_EV_IRQn
#define I2Cx_EV_IRQHandler              I2C1_EV_IRQHandler
#define I2Cx_ER_IRQn                    I2C1_ER_IRQn
#define I2Cx_ER_IRQHandler              I2C1_ER_IRQHandler
/* Size of Transmission buffer */
#define TXBUFFERSIZE                      (COUNTOF(aTxBuffer) - 1)
/* Size of Reception buffer */
#define RXBUFFERSIZE                      TXBUFFERSIZE
/* Exported macro ------------------------------------------------------------*/
#define COUNTOF(__BUFFER__)   (sizeof(__BUFFER__) / sizeof(*(__BUFFER__)))
/* Exported functions ------------------------------------------------------- */

#endif /* __MAIN_H */

And the files stm32f4xx_hal_msp.c and stm32f4xx_it.c have the default structure.

 

For those of you too lazy to look into the datasheet

temp is in address 00

conf is in address 01

hyst temp in adress 02

and overshoot temp in address 03

So the expected temperatures reported should be room temperature in temp, 75 degrees C in hysteresis temperature and 80 degrees C for shutdown temperature as the last two are the default values of these registers.

 

The output that I get is room temperature (varying in steps of 0.125) for all three of them.

 

Can someone point out why that happens?

Datasheet link

https://www.nxp.com/docs/en/data-sheet/LM75B.pdf 

Juice is in Chapter 7

Outcomes