cancel
Showing results for 
Search instead for 
Did you mean: 

Is the HAL_I2C module functional with the NUCLEO-F446RE?

Mustafa Ismail
Associate
Posted on January 31, 2017 at 04:38

I know HAL should work with all STM32F4xx MCUs but there are no examples for it in the STM32Cube_FW_F4_V1.14.0 folder for the nucleo-f446re, and there is no sign of any connection or success when trying to communicate via I2C to a slave device. I'm having trouble getting data from the ADXL345 accelerometer. It is returning zeros for the data and the return for the IsDeviceReady is always 0x01 even when I disconnect the SDA and SCL lines. Furthermore, the return for the device id (dev_id) should be a fixed value of 0xE5 according to the ADXL345 datasheet but it is always 0x01. I know the hardware is setup is correct because it works with my Arduino but I can't get it working with the stm32 nucleo-f446re. I connected the SDA and SCL lines to the corresponding pins on the nucleo which correspond to I2C1. Here is the code:

  1. &sharpdefine ADXL345_ADDR 0xA6 //write i2c address since i'm grounding SDO pin

  2. &sharpdefine ADXL345_INIT 0x2D //POWER_CTL 

  3. &sharpdefine ADXL345_DATA 0x32

  4. void SystemClock_Config(void);

  5. void Error_Handler(void);

  6. static void MX_GPIO_Init(void);

  7. s

    tatic void MX_I2C1_Init(void);

  8. uint8_t values[6];

  9. int ADXL_STATUS;

  10. struct axes { int x_val; int y_val; int z_val; } axes_vals;

  11. uint8_t dev_id;

  12. int main(void) {

  13.    uint8_t command_data[2];

  14.    uint8_t get_id = 0x00;

  15.     command_data[0] = ADXL345_INIT;

  16.    command_data[1] = 0x00;

  17.    HAL_Init();

  18.    SystemClock_Config();

  19.    MX_GPIO_Init();

  20.    MX_I2C1_Init();

  21.    

  22.    ADXL_STATUS = HAL_I2C_IsDeviceReady(&hi2c1, ADXL345_ADDR, 5, 100);

  23.    

    dev_id = HAL_I2C_Master_Receive(&hi2c1, ADXL345_ADDR | 0x01, &get_id, 1, 50);

    //clear 0x2D

  24.    HAL_I2C_Master_Transmit(&hi2c1, ADXL345_ADDR, command_data, 2, 50);

  25.    command_data[0] = 0x10;

    //write 16 to 0x2D

  26.    HAL_I2C_Master_Transmit(&hi2c1, ADXL345_ADDR, command_data, 1, 50);

  27.    command_data[0] |= 0x08;

    //write 8 to 0x2D

  28.    HAL_I2C_Master_Transmit(&hi2c1, ADXL345_ADDR, command_data, 1, 50);

  29.    while (1) {

  30.       uint8_t request_data = ADXL345_DATA;

    //trigger data request

  31.       HAL_I2C_Master_Transmit(&hi2c1, ADXL345_ADDR, &request_data, 1, 50);

  32.       HAL_I2C_Master_Receive(&hi2c1, ADXL345_ADDR | 0x01, values, 6, 50);

  33.       axes_vals.x_val = ((int)values[1] << 😎 | values[0];

  34.       axes_vals.y_val = ((int)values[3] << 😎 | values[2];

  35.       axes_vals.z_val = ((int)values[5] << 😎 | values[4];

  36.       HAL_Delay(100);

  37.     }

  38. }

I've also tried using the Mem_Read and Mem_Write functions of HAL but to no avail. If the hal_i2c module does indeed work with my board, please tell me what I'm doing wrong. I used Cube to generate the I2C configurations. Thanks a lot.

#i2c #hal-driver #nucleo-f446re #nucleo:
2 REPLIES 2
Rafa? Kasi?ski
Associate
Posted on May 03, 2017 at 19:18

Hello

I have checked similar code to Your on Nucleo 401 RE.

I get data from all axis by this function  HAL_I2C_Mem_Read(&hi2c3,0xA7,0x32,1,values,6,50);

The best way is to use logic to scan ports and see if any feedback is comming or if the Nucleo is working.

john doe
Lead
Posted on May 03, 2017 at 22:19

the HAL i2c driver wants a left justified address. if your device is at 0xA6 and you try to talk to it at 0xA6 it won't work. try using the address (0x53<<1) instead.