HAL Library 16- I2C for STM32Fxxx devices

Here it is. After some email for I2C library for HAL, I’ve made it. I ported my old for F4 to HAL based libraries for F0/F4/F7 series.

I added method to read single byte, multi bytes, write single byte, write multi bytes, write/read single byte from/to register which has 16-bit address size.


Read more about new HAL libraries


  • Supports up to 4 I2C peripherals
  • Supports different pinouts selectable on initialization
    • Supports custom pin combinations
  • Supports multiple read/write modes
  • Based on HAL drivers for maximal portability between series


  • HAL
  • TM
    • STM32F4xxx HAL
    • defines.h
    • TM GPIO

Library pinouts

I2C1 PB6 PB7 PB8 PB9 PB6 PB9
I2C2 PB10 PB11 PF1 PF0 PH4 PH5
I2C3 PA8 PC9 PH7 PH8
I2C4 PD12 PD13 PF1 PF0 PF14 PF15 PH11 PH12

Functions and enumerations

Example 1

Example 2

Example 3

Project are available on Github, download all libraries below.

TM STM32 Libraries

STM32 libraries based on STM32Fxxx HAL drivers.


Owner of this site. Also electronic enthusiasts, web developer, 3D printer fan, handball player and more. Big fan of STM32F4 devices. In anticipation of the new Discovery board for STM32F7 lines.

You may also like...

Read before commenting!

Before you make a new comment, make sure you agree with things listed below:

  • - Read post to make sure if it is already posted what you are asking for,
  • - Make sure you have the latest version of libraries used in your project,
  • - Make a clean and grammatically correct written message,
  • - Report as many details as possible, including what have you done so far,
  • - Do NOT post any code here. Use Pastebin,
  • - Do NOT post any error codes here. Use Pastebin,
  • - Specify STM32Fxxx family and used Discovery/EVAL/Nucleo or custom made board,
  • - Make sure your clock is set correct for PLL,
  • - If you are using my HAL drivers, please check this post how to start.
Comment will be deleted on breaking these rules without notification!
  • Pingback: All STM32 HAL libraries - STM32F4 Discovery()

  • Jeremy

    Trying to get the I2C working with my F4 Discovery board (stm32407VG) to talk to the CS43L22 DAC and while I have it working with the Standard Peripherial Library, I can’t get any i2c ACK with the HAL version of the library. Right now, I’m just trying to get 1 message to send correctly: Device 0x94, Address: 0x2, value: 0x1. Stepping through the code, it fails for HAL_I2C_ERROR_AF which means ACK Failed. Putting it on the logic analyzer, it does indeed fail after sending the device address 0x94 with a NAK. The waveform looks the exact same for the device address between HAL and Std Periph libraries up to the NAK of course. Both running at 100kHz I2c. Have you tried I2C on the F4 discovery with the latest HAL from CubeMX?

    • I use hal drivers the same as they are on my github, I believe it was cube 1.8.0 version for f4

      • Jeremy

        I backed up and wrote over my HAL files with the ones from github here: https://github.com/MaJerle/stm32fxxx_hal_libraries/tree/master/00-HAL_DRIVERS/STM32F4xx_HAL_Driver

        The i2c files only had a different header and version but the rest was the same. Still didn’t get past the 0x94 device address. No ACK. Still fails for Error_AF on line 522 in the stm32fxx_hal_i2c.c. You have obviously seen this before as you look for any error other than HAL_I2C_ERROR_AF to appear if the MasterTransmit function fails.

        Is there something else I should try? I’m really stuck here and the ST forum isn’t giving any answers here either.

        • Jeremy

          Found out what the problem was. I had the reset logic backwards for the CS43L22. I was holding the DAC in reset mode on the Discovery board. Your i2C lib works fine.

  • Guido

    Do you think to add an I2C Slave HAL library as well?
    Thanks and best regards


    • Right now I dont have this in plan.

      • Guido


        thanks anyway.
        Best regards

  • Marko Pavlin


    I am using this library in one application for controlling PoSTEP60. This is my code for testing: http://pastebin.com/nUH3VKUw

    had problems with the ACK and then I checked the timing with
    oscilloscope. The address I am using in example is 0x4d, but the
    actually transmitted device address is 0x1a. Slave sned the ACK and
    communication works when I set this address in my slave device. What can be wrong? I know it’s STM HAL driver behind your layer, but I couldn’t figure out what am I doing wrong.

    Thanks for any advice.

    • Hi Marko,

      0x4D is not valid I2C address, at least not for this library. You must specify left-aligned 7-bits address. In your case, 0x4D has LSB bit set to 1 which makes invalid I2C address since LSB bit is for controling read/write operations. Try to send 0x4D << 1 and report if this solved a problem.

      Have a nice day.

  • Matthias


    just a comment/bugfix:
    I did have problems when using this lib because the I2C got stuck in a busy state.
    When calling the enable clock (“RCC->APB1ENR |= RCC_APB1ENR_I2C2EN;”) functionality after the enable pins (”
    TM_I2C2_INT_InitPins(pinspack);”) it is working.