cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with I2C-OLED interfacing

Raahul Jagannathan
Associate II
Posted on June 15, 2018 at 10:09

I am trying to interface an I2C OLED display with an STM32L053C8 board. However, instead of using STM32CubeMX to initialize my different pins, I had to manually assign them, because the example programs which come along with the board, do not open on CubeMX. I think I have made some error in the initialization. When I run the program in the initialization of the oled( i.e SSD1306_Init() ) part, when it checks whether the device is ready, i.e

if (HAL_I2C_IsDeviceReady(&hi2c1, SSD1306_I2C_ADDR, 1, 20000) != HAL_OK)

it goes into this particular function and gets stuck in an infinite while loop. The part which causes it to get stuck is highlighted in the code.

((HAL_GetTick() - tickstart) > Timeout)) never satisfies. 

If someone tells me what I have done wrong, it would be of great help.

HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)

{

uint32_t tickstart = 0U;

__IO uint32_t I2C_Trials = 0U;

if (hi2c->State == HAL_I2C_STATE_READY)

{

if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)

{

return HAL_BUSY;

}

/* Process Locked */

__HAL_LOCK(hi2c);

hi2c->State = HAL_I2C_STATE_BUSY;

hi2c->ErrorCode = HAL_I2C_ERROR_NONE;

do

{

/* Generate Start */

hi2c->Instance->CR2 = I2C_GENERATE_START(hi2c->Init.AddressingMode, DevAddress);

/* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */

/* Wait until STOPF flag is set or a NACK flag is set*/

tickstart = HAL_GetTick();

while ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) && (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == RESET) && (hi2c->State != HAL_I2C_STATE_TIMEOUT))

{

if (Timeout != HAL_MAX_DELAY)

{

if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))

{

/* Device is ready */

hi2c->State = HAL_I2C_STATE_READY;

/* Process Unlocked */

__HAL_UNLOCK(hi2c);

return HAL_TIMEOUT;

}

}

}
6 REPLIES 6
David SIORPAES
ST Employee
Posted on June 15, 2018 at 10:56

What is the value of the SSD1306_I2C_ADDR macro ?

Make sure the I2C address is the 8-bit representation (0x78) and not the 7-bit one (0x3c) as it happens, for example, in the Arduino environment.

Posted on June 15, 2018 at 11:49

The address is 0x78. I manually added the I2C peripheral to my program. I feel like I may have missed something when I did this. Could you please walk me over the process of what exactly I have to do to interface a peripheral without using CubeMX. 

Posted on June 15, 2018 at 12:02

Basically, this is what you need to do:

  • Enable peripheral clock
  • Enable GPIO clock
  • Setup alternate functions
  • If used, configure peripheral's interrupts and NVIC.
  • Configure I2C with proper initialization settings

If you don't want to use CubeMX you can look, as a reference, to the examples provided in the Cube software package. E.g.: in the STM32L0 package I2C polling example can be found in:

Projects\STM32L053R8-Nucleo\Examples\I2C\I2C_TwoBoards_ComPolling

Look, in particular, to the HAL_I2C_MspInit() call.

Peter Allnutt
Associate III
Posted on June 16, 2018 at 10:20

I did something similar recently with a STM32F103 but took the opposite approach. I created a new project in CubeMX and added the code samples to that. You could at least generate the blank project and see how its initialisation differs from yours.

Posted on June 18, 2018 at 06:15

Hey, thank you so much for replying. apologies for the late reply. I was wondering if you could tell me how I am to import the example questions into CubeMX. Whenever I try loading it from Keil, it says that it can not open the xml file.

Posted on June 18, 2018 at 08:13

Sorry I don't use Keil. As I said I just started a new project in CubeMX. Then I did the IO assignments I needed and copy  and pasted the sample code I had in to my project. I'm using Atollic TrueStudio.