两个STM32设备之间的I²C通信失败

问题描述 投票:0回答:1

我目前正在使用两个 STM32 设备通过 I²C 进行通信。

目前无法通讯,我不知道为什么。

这是我的主初始化代码,由 STM32CubeMX 生成并稍作修改:

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 */
}

这是我的奴隶代码

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 码根据我的设备而改变

这是我的奴隶接收代码

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
        }
    }
}

这是我的主传输代码

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);
    }

}

当我开始通信时,主机发送地址和写入位,并得到 NACK 作为返回,通信结束

i2c_waveform

我不太确定出了什么问题,谁能帮我解决这个问题?

c stm32 i2c
1个回答
-1
投票

这很可能是外围设备或硬件配置的问题。使用示波器检查时钟频率是否符合您的预期(I2C 的典型频率为 100kHz)。

当您在那里时,检查信号是否也具有良好的快速边缘。忘记添加外部上拉电阻是导致此问题的常见原因。 2k2电阻通常就可以了。

您可能会发现您从电子堆栈交换中得到更多回应。

© www.soinside.com 2019 - 2024. All rights reserved.