cancel
Showing results for 
Search instead for 
Did you mean: 

I2C problem with STM32F103

jark
Associate II

This STM32F103 project will have a 4x20 LCD, needs two PWM ouptuts, and I2C interface to a Si5351A and several external interrupts. I started developing the interface to the LCD; no problem,then the two PWM's; again no problem but I cannot get the I2C interface to work. The two lines, SDA and SCL show no activity on an oscilloscope and calls to HAL_I2C_Master_Transmit() just return a HAL_BUSY. Looking at the code generated, I'm surprised to see that the MX_GPIO_Init() routine does not show any configuration of the two I2C lines; PB6 and PB7 although a MX_I2C1_Init() is generated.

static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, D2_Pin|D3_Pin|E_Pin|RS_Pin 
                          |D0_Pin|D1_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pin : LD2_Pin */
  GPIO_InitStruct.Pin = LD2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);
 
  /*Configure GPIO pins : D2_Pin D3_Pin E_Pin RS_Pin 
                           D0_Pin D1_Pin */
  GPIO_InitStruct.Pin = D2_Pin|D3_Pin|E_Pin|RS_Pin 
                          |D0_Pin|D1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
}
static void MX_I2C1_Init(void)
{
 
  /* USER CODE BEGIN I2C1_Init 0 */
 
  /* USER CODE END I2C1_Init 0 */
 
  /* USER CODE BEGIN I2C1_Init 1 */
 
  /* USER CODE END I2C1_Init 1 */
  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_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
 
  /* USER CODE BEGIN I2C1_Init 2 */
 
  /* USER CODE END I2C1_Init 2 */
 
}

5 REPLIES 5
Vijay Krishna
Associate II

Have you tried to use external pull-up resistor in I2C communication lines:

see this configuration: https://rheingoldheavy.com/wp-content/uploads/2015/01/Featured-29.png

let me know if you tried this...

jark
Associate II

Yes, there are pull-up resistors. Both SCL and SDA are sitting at 3.3V.

I2C pins configuration is located in function HAL_I2C_MspInit.

jark
Associate II

Thanks for the info. I see it there ... but, I2C calls still return HAL_Busy. However, when I also put that same code to set up PB6 and PB7 into the MX_GPIO_Init() function in main.c, I no longer get that; instead, I2C apparently is then working correctly. I still haven't completely checked out the function of the I2C peripheral but the fact that it does not return an error is encouraging. But, why is it necessary to do this?

jark
Associate II

To supplement my previous post, I2C seems to be working properly as I was able to control the Si5351A.