简体   繁体   中英

i2c communication between 2 stm32 devices fail

i'm currently using 2 stm32 devices to communicate via i2c.

communication is not working at the moment and i have no idea why.

this is my master initialize code, generated from stm32cubemx and modified a little

static void MX_I2C2_Init(void)
{

  hi2c2.Instance = I2C2;
  hi2c2.Init.Timing = 0x00303D5B;
  hi2c2.Init.OwnAddress1 = 0;
  hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c2.Init.OwnAddress2 = 0;
  hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  HAL_I2C_Init(&hi2c2);
  if (HAL_I2C_Init(&hi2c2) != HAL_OK)
    {
      Error_Handler();
    }

    /** Configure Analogue filter
    */
    if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
    {
      Error_Handler();
    }

    /** Configure Digital filter
    */
    if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK)
    {
      Error_Handler();
    }
}

static void MX_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_I2C2_CLK_ENABLE();

  /*Configure GPIO pins : PB7 PB6 */
  GPIO_InitStruct.Pin = GPIO_PIN_11;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF6_I2C2;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PA2 PA3 */
  GPIO_InitStruct.Pin = GPIO_PIN_12;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF6_I2C2;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  if (HAL_I2C_Init(&hi2c2) != HAL_OK) {     cpu_ErrHandler();   }
    /** Configure Analogue filter
     */
    if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE)
            != HAL_OK) {
        cpu_ErrHandler();
    }
    /** Configure Digital filter
     */
    if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK) {
        cpu_ErrHandler();
    }
  //HAL_I2C_Slave_Receive_IT(&hi2c2,  ( uint8_t * ) &i2c_data,1);
}
void cpu_ErrHandler(void)
{
  /* USER CODE BEGIN cpu_ErrHandler_Debug */
  /* User can add his own implementation to report the HAL error return state */

  /* USER CODE END cpu_ErrHandler_Debug */
}
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

and this is my slave code

static void MX_I2C2_Init(void)
{

  /* USER CODE BEGIN I2C2_Init 0 */

  /* USER CODE END I2C2_Init 0 */

  /* USER CODE BEGIN I2C2_Init 1 */

  /* USER CODE END I2C2_Init 1 */
  hi2c2.Instance = I2C2;
  hi2c2.Init.Timing = 0x00303D5B;
  hi2c2.Init.OwnAddress1 = 96;
  hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c2.Init.OwnAddress2 = 0;
  hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  HAL_I2C_Init(&hi2c2);
  if (HAL_I2C_Init(&hi2c2) != HAL_OK)
      {
        Error_Handler();
      }

      /** Configure Analogue filter
      */
      if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
      {
        Error_Handler();
      }

      /** Configure Digital filter
      */
      if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK)
      {
        Error_Handler();
      }
}
/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  //__HAL_RCC_I2C2_CLK_ENABLE();

  /*Configure GPIO pins : PB7 PB6 */
  GPIO_InitStruct.Pin = GPIO_PIN_11;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF6_I2C2;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PA2 PA3 */
  GPIO_InitStruct.Pin = GPIO_PIN_12;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF6_I2C2;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  if (HAL_I2C_Init(&hi2c2) != HAL_OK) {     cpu_ErrHandler();   }
    /** Configure Analogue filter
     */
    if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE)
            != HAL_OK) {
        cpu_ErrHandler();
    }
    /** Configure Digital filter
     */
    if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK) {
        cpu_ErrHandler();
    }
  //HAL_I2C_Slave_Receive_IT(&hi2c2,  ( uint8_t * ) &i2c_data,1);
}
void cpu_ErrHandler(void)
{
  /* USER CODE BEGIN cpu_ErrHandler_Debug */
  /* User can add his own implementation to report the HAL error return state */

  /* USER CODE END cpu_ErrHandler_Debug */
}
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

pin number changed according to my device

this is my slave receive code

void user_main(void)
{
    HAL_StatusTypeDef ret;
    ret = HAL_I2C_Slave_Receive(&hi2c2,  ( uint8_t * ) UartRxMemory01, sizeof(UartRxMemory01), 100);
    cpu_delay_ms(100);
    if(ret != HAL_OK){
        char i2c_fail[]="fail";
        DCPU_TX_EN(); // get sensor value
        #if 1
            if(HAL_UART_Transmit(&rcpu_huart2,( uint8_t * ) i2c_fail,strlen( i2c_fail ),100 ) == HAL_OK) {
                DCPU_RX_EN();
                HAL_UART_Receive(&rcpu_huart2, ( uint8_t * ) RxIntBuffer,sizeof(RxIntBuffer),100 );
            }
        #endif
    }
    else {
        if(strstr((const char*)UartRxMemory01, "OK") != NULL){
            char i2c[]="i2c succeed";
            DCPU_TX_EN(); // get sensor value
            #if 1
                if(HAL_UART_Transmit(&rcpu_huart2,( uint8_t * ) i2c,strlen( i2c ),100 ) == HAL_OK) {
                    DCPU_RX_EN();
                    HAL_UART_Receive(&rcpu_huart2, ( uint8_t * ) RxIntBuffer,sizeof(RxIntBuffer),100 );
                }
            #endif
        } else {
            char got_smth[]="received something";
            DCPU_TX_EN(); // get sensor value
            #if 1
                if(HAL_UART_Transmit(&rcpu_huart2,( uint8_t * ) got_smth,strlen( got_smth ),100 ) == HAL_OK) {
                    DCPU_RX_EN();
                    HAL_UART_Receive(&rcpu_huart2, ( uint8_t * ) RxIntBuffer,sizeof(RxIntBuffer),100 );
                }
            #endif
        }
    }
}

and this is my master transmit code

void user_main(void)
{
    char i2c_ok[5];
    i2c_ok[0]=0x0a;
    strcat(i2c_ok, "OK");
    i2c_ok[4] = 0x0d;
    HAL_StatusTypeDef ret;
    ret = HAL_I2C_Master_Transmit(&hi2c2, 0x20 << 1, (uint8_t*)i2c_ok, sizeof(i2c_ok),100);

    if(ret != HAL_OK){
        cpu_delay_ms(100);
    }
    else{
        cpu_delay_ms(1000);
    }

}

when i start the communication the master sends address and write bit, and gets NACK as return and the communication is over

i2c_waveform

i'm not really sure which or what went wrong, can anyone help me with this?

This is most likely an issue with the configuration of the peripheral or the hardware. Check that the clock frequency is what you expect (100kHz is typical for I2C) using an oscilloscope.

While you are there, check that the signal has nice fast edges too. Forgetting to add external pull-up resistors is a common cause of this problem. 2k2 resistors are usually fine.

You may find you get more response from the electronics stack exchange.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM