Problem, Board-to-Board-I2C-Kommunikation auf STM32 zum Laufen zu bringen

Ich habe zwei Boards, die an STM32F030R8 bzw. F030C6 arbeiten. Ich habe versucht, die Boards über I2C miteinander kommunizieren zu lassen, aber bisher nicht gut. Eines meiner Boards läuft mit 48 MHz und das andere mit 20 MHz. Ich habe den I2C-Normalmodus mit 100 kHz und 100 ns Anstiegs- und Abfallzeit konfiguriert. Ich habe versucht, sowohl DMA als auch ITs zu verwenden. Bei der Verwendung von DMA versuchte mein Masterboard gleichzeitig zu empfangen und zu senden, sodass meine Codelogik nicht wie erwartet funktionierte. Aber dann wechselte ich zu Interrupts und ich konnte es zum Laufen bringen. Aber das Problem ist, dass es nach dem Einschalten nur Einsen kommuniziert und dann in HAL_I2C_STATE_BUSY übergeht. Dann muss ich das Board ein- und ausschalten, damit es wieder funktioniert. Auch ein Zurücksetzen der MCU erwies sich als zwecklos.

I2C Init-Code für Master:

  hi2c1.Instance = I2C1;
  hi2c1.Init.Timing = I2C_TIMING;//check in .h file
  hi2c1.Init.OwnAddress1 = 0x123;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_10BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0xFF;
  hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }

für Sklave:

  hi2c1.Instance = I2C1;
  hi2c1.Init.Timing = 0x00101D2D;//0x00201D2B;
  hi2c1.Init.OwnAddress1 = I2C_ADDRESS;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_10BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0xFF;
  hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }

Dies ist der Code, der Folgendes überträgt:

if(HAL_I2C_GetState(&hi2c1) == HAL_I2C_STATE_READY) {
    if(HAL_I2C_Slave_Transmit_IT(&hi2c1, (uint8_t*)aTxBuffer, 10)!= HAL_OK) {
    /* Transfer error in reception process */
        Error_Handler();
    }
}

Und das erhält:

do {
   HAL_I2C_Init(&hi2c1);
    if(HAL_I2C_Master_Receive_IT(&hi2c1, (uint16_t)I2C_ADD_CHILLER, aRxBuffer, 14)!= HAL_OK) {
        Error_Handler();
    }
    State = HAL_I2C_GetState(&hi2c1) ;
    Teor=HAL_I2C_GetError(&hi2c1);
    HAL_I2C_DeInit(&hi2c1);
  } while(Teor == HAL_I2C_ERROR_AF);
Wie werden die Platinen miteinander verbunden? I2C ist nicht wirklich dafür ausgelegt, über Kabel zu gehen.
Kabel verwenden. Tatsächlich ist das Kabel etwa 20 cm lang. Ist das ein Problem?
Sehr wahrscheinlich. Diese Kabel fügen den Leitungen eine Menge Kapazität hinzu. Versuchen Sie, ein kurzes Kabel zu verwenden, um zu sehen, ob es einen Unterschied macht.
Gut, danke. Wird das machen.

Antworten (1)

Überprüfen Sie, ob SDA und SCL vernünftige Pull-up-Widerstände haben.

Das Reduzieren des Werts dieser Widerstände kann hilfreich sein, um Kapazität und Rauschen zu überwinden.

Stellen Sie außerdem sicher, dass die 0 V gut zwischen den Platinen verbunden sind.