cancel
Showing results for 
Search instead for 
Did you mean: 

I2C address not sent from STM32F103C8T6 Master to I2C-LCD Slave

AErfu.1
Associate

Hello,

I have troubles using I2C with the STM32F103C8T6 "Blue Pill" board. I set up the code in CubeMX, using LL Libraries.

After initializing the I2C periphery I try to send the address, but the ADDR bit in I2C1_SR1 register remains 0. AF bit remains 0, too. I checked it by debugging and observing the registers. At the moment right before the function call "LL_I2C_TransmitData8(...)", in SR1, everything is 0 except SB, and in SR2 everything is 0 except BUSY and MSL. After this function call, SB becomes 0. After that, ADDR remains 0 and the program stucks in the while loop.

I could not find any solution to this problem neither on the internet, nor in the errata sheets.

I tested the I2C-LCD with an AVR Atmega328PB, works perfectly there. It's a 16x02 LCD with a PCF8574T 8-bit-to-i2c expander.

I am sure everything is connected properly: GND to GND, VCC to 5V, SDA to PB9, SCL to PB8. Also tested the contact with a multimeter.

Unfortunately, I don't have an oscilloscope or logic analyzer.

Here is my setup in CubeMX:

0693W000007CxxTQAS.png0693W000007CxxYQAS.pngHere is the code:

#include "main.h"
 
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
 
void errata_2_14_7_workaround(void)
{
	LL_I2C_Disable(I2C1);
	LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
 
        GPIO_InitStruct.Pin = LL_GPIO_PIN_8|LL_GPIO_PIN_9;   //PIN_8 = SCL, PIN_9 = SDA
        GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
	GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
	GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
	LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
	LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_8);
	LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_9);
	while(!LL_GPIO_IsOutputPinSet(GPIOB, LL_GPIO_PIN_8) || !LL_GPIO_IsOutputPinSet(GPIOB, LL_GPIO_PIN_9)){}
 
	LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_9);
	while(LL_GPIO_IsOutputPinSet(GPIOB, LL_GPIO_PIN_9)){}
 
	LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_8);
	while(LL_GPIO_IsOutputPinSet(GPIOB, LL_GPIO_PIN_8)){}
 
	LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_8);
	while(!LL_GPIO_IsOutputPinSet(GPIOB, LL_GPIO_PIN_8)){}
 
	LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_9);
	while(!LL_GPIO_IsOutputPinSet(GPIOB, LL_GPIO_PIN_9)){}
 
        GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
        GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
        LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
        LL_I2C_EnableReset(I2C1);
        LL_I2C_DisableReset(I2C1);
 
        LL_I2C_Enable(I2C1);
}
 
 
int main(void)
{
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO);
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
  NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
  LL_GPIO_AF_Remap_SWJ_NOJTAG();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_I2C1_Init();
 
  LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_13);   //LED off
 
  errata_2_14_7_workaround();
  LL_I2C_DisableBitPOS(I2C1);
  LL_I2C_AcknowledgeNextData(I2C1, LL_I2C_ACK);
  LL_I2C_GenerateStartCondition(I2C1);
  while(!LL_I2C_IsActiveFlag_SB(I2C1)){};
  (void) I2C1->SR1;
  LL_I2C_TransmitData8(I2C1, (0x27 << 1));      //0x27 is the address of the Slave
  while(!LL_I2C_IsActiveFlag_ADDR(I2C1) && !LL_I2C_IsActiveFlag_AF(I2C1)){};  //the program hangs here
  LL_I2C_ClearFlag_ADDR(I2C1);
  LL_I2C_GenerateStopCondition(I2C1);
 
 
  while (1)
  {
	  LL_mDelay(250);
	  LL_GPIO_TogglePin(GPIOC, LL_GPIO_PIN_13);   //LED blinking
  }
 
}
 
 
void SystemClock_Config(void)
{
  LL_FLASH_SetLatency(LL_FLASH_LATENCY_2);
  while(LL_FLASH_GetLatency()!= LL_FLASH_LATENCY_2)
  {
  }
  LL_RCC_HSE_Enable();
 
   /* Wait till HSE is ready */
  while(LL_RCC_HSE_IsReady() != 1)
  {
 
  }
  LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE_DIV_1, LL_RCC_PLL_MUL_9);
  LL_RCC_PLL_Enable();
 
   /* Wait till PLL is ready */
  while(LL_RCC_PLL_IsReady() != 1)
  {
 
  }
  LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
  LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
  LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
  LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
 
   /* Wait till System clock is ready */
  while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
  {
 
  }
  LL_Init1msTick(72000000);
  LL_SetSystemCoreClock(72000000);
}
 
 
static void MX_I2C1_Init(void)
{
 
  /* USER CODE BEGIN I2C1_Init 0 */
 
  /* USER CODE END I2C1_Init 0 */
 
  LL_I2C_InitTypeDef I2C_InitStruct = {0};
 
  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB);
  /**I2C1 GPIO Configuration
  PB8   ------> I2C1_SCL
  PB9   ------> I2C1_SDA
  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_8|LL_GPIO_PIN_9;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
  LL_GPIO_AF_EnableRemap_I2C1();
 
  /* Peripheral clock enable */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
 
  /* USER CODE BEGIN I2C1_Init 1 */
 
  /* USER CODE END I2C1_Init 1 */
  /** I2C Initialization
  */
  LL_I2C_DisableOwnAddress2(I2C1);
  LL_I2C_DisableGeneralCall(I2C1);
  LL_I2C_EnableClockStretching(I2C1);
  I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
  I2C_InitStruct.ClockSpeed = 100000;
  I2C_InitStruct.DutyCycle = LL_I2C_DUTYCYCLE_2;
  I2C_InitStruct.OwnAddress1 = 0;
  I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
  I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
  LL_I2C_Init(I2C1, &I2C_InitStruct);
  LL_I2C_SetOwnAddress2(I2C1, 0);
  /* USER CODE BEGIN I2C1_Init 2 */
 
  /* USER CODE END I2C1_Init 2 */
 
}
 
 
static void MX_GPIO_Init(void)
{
  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  /* GPIO Ports Clock Enable */
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOC);
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOD);
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA);
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB);
 
  /**/
  LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_13);
 
  /**/
  GPIO_InitStruct.Pin = LL_GPIO_PIN_13;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
}
 
 
void Error_Handler(void)
{
}

0 REPLIES 0