cancel
Showing results for 
Search instead for 
Did you mean: 

HTU21D sesnor with Nucleo-L152RE

AP_040
Senior

I am newbie to use Nucleo-L152RE board. I have a HTU21D-Temperature & Humidity sensor which used I2C interface to read the temperature data.

So, with using the STM32CubeMX I have generated code for STM32L152RETx chip with UART2 (debug purpose) and I2C1 (PB6/PB7).

Below is my snippet code.

#define HTU21D_ADDR 0x80

#define Temperature_REG 0xE3

I2C_HandleTypeDef hi2c1;

UART_HandleTypeDef huart2;

int main(void)

{

uint8_t t_data[2];

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

HAL_Init();

 /* Configure the system clock */

SystemClock_Config();

MX_USART2_UART_Init();

MX_I2C1_Init();

HAL_I2C_Master_Transmit(&hi2c1, HTU21D_ADDR, &Temperature_REG, 1, 1000);

HAL_I2C_Master_Receive(&hi2c1, HTU21D_ADDR, t_data, 2, 1000);

printf("Temperature read data %x:%x\r\n",t_data[0],t_data[1]);

}

void MX_I2C1_Init()

{

 hi2c1.Instance       = I2C1;

 hi2c1.Init.ClockSpeed    = I2C_SPEEDCLOCK;

 hi2c1.Init.DutyCycle    = I2C_CCR_DUTY;

 hi2c1.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;

 hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

 hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;

 hi2c1.Init.NoStretchMode  = I2C_NOSTRETCH_DISABLE;

 hi2c1.Init.OwnAddress1   = 0x00;

 hi2c1.Init.OwnAddress2   = 0x00;

}

Every time getting the zero value from the sensor. So, can you please tell me what is the problem here?.

Connection of HTU21D sensor and Nucleo-L152RE board are:

SCK --> PB6

SDA --> PB7

VCC --> 3V3

GND --> GND

Attached snap shot of interface between sensor and Nucleo.

18 REPLIES 18
AP_040
Senior
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  ** This notice applies to any and all portions of this file
  * that are not between comment pairs USER CODE BEGIN and
  * USER CODE END. Other portions of this file, whether 
  * inserted by the user or by software development tools
  * are owned by their respective copyright owners.
  *
  * COPYRIGHT(c) 2018 STMicroelectronics
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32l1xx_hal.h"
 
/* USER CODE BEGIN Includes */
 
/* USER CODE END Includes */
 
/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;
 
UART_HandleTypeDef huart2;
 
static GPIO_InitTypeDef  GPIO_InitStruct;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_USART2_UART_Init(void);
#define LED2_PIN                         GPIO_PIN_5
#define LED2_GPIO_PORT                   GPIOA
#define LED2_GPIO_CLK_ENABLE()           __HAL_RCC_GPIOA_CLK_ENABLE()
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
 
/* USER CODE END PFP */
 
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  *
  * @retval None
  */
#define HTU21D 0x80
 
int main(void)
{
	uint8_t temperature_reg = 0xE3;
	uint8_t buffer[2],status=0;
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration----------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
  LED2_GPIO_CLK_ENABLE();
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_I2C1_Init();
 
  MX_USART2_UART_Init();
  printf("+++++++ Hello\r\n");
  /* USER CODE BEGIN 2 */
  GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull  = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 
  GPIO_InitStruct.Pin = LED2_PIN;
  HAL_GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStruct);
  status = HAL_I2C_Master_Transmit(&hi2c1,HTU21D,&temperature_reg,1,1000);
  printf("tx status %x\r\n",status);
  while (1)
  {
	  HAL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_PIN);
	  status = HAL_I2C_Master_Receive(&hi2c1, HTU21D, buffer, 2, 1000);
	  printf("rx Status %x\r\n",status);
	  printf("Read data %x:%x\r\n",buffer[0],buffer[1]);
	  HAL_Delay(1000);
  /* USER CODE END WHILE */
  }
}
 
/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
 
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
 
    /**Configure the main internal regulator output voltage 
    */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  RCC_OscInitStruct.MSICalibrationValue = 0;
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
    /**Configure the Systick interrupt time 
    */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
 
    /**Configure the Systick 
    */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
 
  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
 
/* I2C1 init function */
static void MX_I2C1_Init(void)
{
	hi2c1.Instance = I2C1;
	hi2c1.Init.ClockSpeed = 100000;
	hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
	hi2c1.Init.OwnAddress1 = 0;
	hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
	hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
	hi2c1.Init.OwnAddress2 = 0;
	hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
	hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
	if (HAL_I2C_Init(&hi2c1) != HAL_OK)
	{
		_Error_Handler(__FILE__, __LINE__);
	}
}
 
/* USART2 init function */
static void MX_USART2_UART_Init(void)
{
 
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
}
 
 
/* USER CODE BEGIN 4 */
 
/* USER CODE END 4 */
 
/**
  * @brief  This function is executed in case of error occurrence.
  * @param  file: The file name as string.
  * @param  line: The line in file as a number.
  * @retval None
  */
void _Error_Handler(char *file, int line)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  while(1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}
 
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
 
/**
  * @}
  */
 
/**
  * @}
  */
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

0690X000006CsmqQAC.jpg

Thanks for your exceptional support.

  • Here I attached full interface snapshot of NUCLEO-L152RE with HTU21D sensor and main.c file. In the snap -shot you can find that there is pull-ups present on SDA and SCK line. So, can you please guide me how to solve this issue to read proper temperature data.

Is it reading data consistently now? What's the output look like? Assume I don't have this set up.

Do you need to combine the values and scale to get temperature? Does the Data Sheet described the form and scaling of the data? Have you tried to apply that?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
AP_040
Senior

Yes, data sheet of temperature sensor gives the equation to convert data into degree Celsius. But here the output data is always zero. Once it will give me the output data then I will apply the equation to scale it into the code.

Yes, I want to read data continuous time with some delay for testing purpose.

Moreover, the status return by both HAL transmit/receive API is HAL_BUSY every time.

So, Which one is wrong here?.What should I do?.

It might be SMBUS protocol?

AP_040
Senior

The same sensor is working fine with other controller which I have tested with NXP chip using I2C protocol so no need to SMBUS here. There is some mistake with the ST. So, which things is going to be wrong here. Can you please tell me. Is it some wrong in software code or hardware?. Can somebody help me on this.

AP_040
Senior

I generated I2C code from cubeMX for STM32F413RH and it is working fine. So, what is the wrong with NUCLEO-L152RE kit. Can anybody help me.

Can you remove your "manual" turning on of the pull-up? You are resetting the alternate function settings of the GPIO. The pull-up is already set by Cube's generated code (the HAL_I2C_MspInit function in stm32l1xx_hal_msp.c), the configuration is done in I2C configuration window, GPIO tab, and the pull-up is set by default for the I2C pins.

Can you remove your "manual" turning on of the pull-up?

--> I do not set any thing regarding this in code.

The same set-up is working fine with STM32F413RH. Code is generated with CUBEMX and call HAL_I2C_Master_Transmit/Receive and it will give me the proper Temperature+Humidity data. Both the STM32L1 and STM32F4 is used same HAL driver so why it is not working with STM32L1?.

I also wasn't able to do something regarding I2C on the same board. But you know what, it works if you use CubeMX to initialize it, then with some code borrowed from @Tilen MAJERLE​ , look in this file, it might help you (it helped me for two I2C devices by now: PCF8583 and MAX44009) https://gitlab.com/funlw65/vscode_nucleo_l152re/raw/master/ll_old/ll_library/i2c_master.h

The other file that is included in the file above is https://gitlab.com/funlw65/vscode_nucleo_l152re/raw/master/ll_old/ll_library/typedefs.h

But I think you don't need it...