Skip to main content
AP_040
Senior
December 18, 2018
Question

HTU21D sesnor with Nucleo-L152RE

  • December 18, 2018
  • 18 replies
  • 5305 views

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.

    This topic has been closed for replies.

    18 replies

    After Forever
    Senior III
    December 18, 2018

    You should check what are returning the HAL_I2C_Master_Transmit and HAL_I2C_Master_Receive functions. Maybe they are failing and you can find more information from their return code.

    AP_040
    AP_040Author
    Senior
    December 18, 2018

    Yes, I have checked the return status of transmit and receive. It has given me status =2 (HAL_BUSY). So, what I have to do here?.

    AP_040
    AP_040Author
    Senior
    December 19, 2018

    Has anyone give me the solution for the i2c busy flag error?. Is there any pull-up/down setting required?. What is wrong here?. @Community members, can you please help me to resolved this issue.

    After Forever
    Senior III
    December 19, 2018

    I2C requires open-drain and pull-ups on both data and clock pins, if you don't have the pull-ups on PCB level you must activate them on MCU level.

    As for the busy flag, can you debug step-by-step into the HAL calls and see where exactly it returns the busy code?

    AP_040
    AP_040Author
    Senior
    December 19, 2018

    Thanks for your quick support.

    As far pull-ups, it is present on SDA and SCK line on PCB. And after debug, I have found that in HAL_I2C_Master_Transmit() "I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart)" this is returning the HAL_TIMEOUT error so HAL_I2C_Master_Transmit() gives the status HAL_BUSY. Now, what is the next step to do?. Can you please guide me.

    After Forever
    Senior III
    December 19, 2018

    Did you generate the initialization code using STM32CubeMX? Can you share the IOC file? I don't see any calls to HAL_I2C_Init.

    AP_040
    AP_040Author
    Senior
    December 19, 2018

    Here is the IOC file. HAL_I2C_Init() is called in MX_I2C1_Init(), it is already present in code but unfortunate I forgot in snippet code.

    Also attched HTU21D interfcae which is already present pull-ups on I2C lines.0690X000006CsHnQAK.png

    After Forever
    Senior III
    December 19, 2018

    > I forgot in snippet code.

    Aha, so that was not the whole code, OK.

    I don't see any issues with your IOC, I generated init. code using it, getting somewhat different code than your snippet, but maybe it's because my Cube and firmware packages are updated to the latest versions.

    Anyhow, returning to your step-by-step debugging, there are several calls to I2C_WaitOnFlagUntilTimeout inside the HAL_I2C_Master_Transmit function, so which one exactly is timing out for you? If it's the first one, then it's strange, I2C peripheral's busy flag shouldn't be set just after enabling it, before any usage.

    AP_040
    AP_040Author
    Senior
    December 19, 2018

    Yes, it is the first one. Its a full code just only HAL_init() function to forgot in snippet. Now, what should I do?

    AP_040
    AP_040Author
    Senior
    December 20, 2018
    /**
     ******************************************************************************
     * @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.

    Tesla DeLorean
    Guru
    December 20, 2018

    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 (See Profile) Up vote any posts that you find helpful, it shows what's working..