UART zwischen STM32F4 und einem Arduino Uno

Ich kann Zeichenfolgen und Zahlen erfolgreich zwischen zwei STM32F407VG Discovery-Boards und zwischen zwei Arduino Uno-Boards senden, aber ich kann es nicht zwischen einem STM32F4 und einem Arduino Uno tun.

Folgendes habe ich getan:

  • Arduino Uno RX -> PA2
  • Arduino Uno TX -> PA3
  • Ein Stift von der STM32F4-Masse zur Arduino-Masse.

Ich verwende die Standardkonfiguration 9600 Baudrate, 8 Bit Datengröße, 1 Stoppbit und keine Parität. Der Ausgabetyp der gpios auf dem stm32f4 ist Push-Pull und sie werden hochgezogen.

Gibt es etwas, das ich vermisse?

Arduino UNOs arbeiten bei 5V. Läuft das Discovery Board mit dem gleichen Spannungspegel? Oder wird die MCU mit 3,3 V betrieben?
Die MCU auf dem F4 Discovery Board läuft mit 3 V.
Ich glaube, das ist eine rhetorische Frage von Lorenzo, sie verwenden nicht das gleiche Lob für Sie.

Antworten (2)

Wahrscheinlich sind die Logikpegel der UARTs der beiden MCUs nicht kompatibel, da sie mit unterschiedlichen Spannungspegeln versorgt werden.

Wie das STM32F405-Datenblatt sagt, hat diese MCU einen Versorgungsspannungsbereich von 1,8 V ... 3,6 V, während das Arduino UNO-Board seine MCU ( ATmega 328P ) mit 5 V versorgt.

Wie Bence Kaulics in seinem Kommentar bestätigt, versorgt Ihr F4 Discovery Board seine MCU mit 3 V, sodass ein logisches High auf seiner TX-Leitung nicht höher als 3 V sein kann, was genau die minimale Eingangsspannung ist, die für ein logisches High für einen ATmega328P mit 5 V erforderlich ist (V IH =0,6Vcc=0,6*5V=3V – siehe Datenblatt auf S.313):

Geben Sie hier die Bildbeschreibung ein

Sie benötigen also einen Pegelumsetzer zwischen den beiden Platinen auf der TX-Leitung Ihres Discovery-Boards und möglicherweise auch auf seiner RX-Leitung (letzteres könnte jedoch nicht erforderlich sein, da die STM32-MCU 5-V-tolerante Eingänge hat).

So etwas wie dieser Level Shifter könnte für Sie funktionieren:

Geben Sie hier die Bildbeschreibung ein

Ein Voltmeter zeigt 2,86 V an, also liegt es sogar unter der minimalen Eingangshochspannung, vielen Dank, Sir.

Manchmal kann es auch an der Einstellung des PULL-UP-Widerstands am STu Rx-Pin liegen.

Sie können Ihre USART-Pins entweder auf Pull-Up/Pull-Down-Konfiguration oder Floating einstellen.
Hier sind Beispielcodes, um den Rx-Pin auf schwebend zu ändern:


void usartSetup (void) {
  // make sure the relevant pins are appropriately set up.
  RCC_APB2ENR |= RCC_APB2ENR_IOPAEN;              // enable clock for GPIOA
  GPIOA_CRH   |= (0x0BUL  < < 4);                  // Tx (PA9) alt. out push-pull
  GPIOA_CRH   |= (0x04UL  << 8);                  // Rx (PA10) in floating
  RCC_APB2ENR |= RCC_APB2ENR_USART1EN;            // enable clock for USART1
  USART1_BRR  = 64000000L/115200L;                // set baudrate
  USART1_CR1 |= (USART1_CR1_RE | USART1_CR1_TE);  // RX, TX enable
  USART1_CR1 |= USART1_CR1_UE;                    // USART enable
  }

int SendChar (int ch)  {
  while (!(USART1_SR & USART1_SR_TXE));
  USART1_DR = (ch & 0xFF);
  return (ch);
}

int GetChar (void)  {
  while (!(USART1_SR & USART1_SR_RXNE));
  return ((int)(USART1_DR & 0xFF));
}

ODER

mit HAL-Bibliothek:


*#include <stm32f4xx_hal.h>
#include <stm32_hal_legacy.h>
#ifdef __cplusplus
extern "C"
#endif
void SysTick_Handler(void)
{
    HAL_IncTick();
    HAL_SYSTICK_IRQHandler();
}
static UART_HandleTypeDef s_UARTHandle = UART_HandleTypeDef();
int main(void)
{
    HAL_Init();
    __USART2_CLK_ENABLE();
    __GPIOA_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.Pin = GPIO_PIN_2;
    GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStructure.Alternate = GPIO_AF7_USART2;
    GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStructure.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.Pin = GPIO_PIN_3;
    GPIO_InitStructure.Mode = GPIO_MODE_AF_OD;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
    s_UARTHandle.Instance        = USART2;
    s_UARTHandle.Init.BaudRate   = 115200;
    s_UARTHandle.Init.WordLength = UART_WORDLENGTH_8B;
    s_UARTHandle.Init.StopBits   = UART_STOPBITS_1;
    s_UARTHandle.Init.Parity     = UART_PARITY_NONE;
    s_UARTHandle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
    s_UARTHandle.Init.Mode       = UART_MODE_TX_RX;

    if (HAL_UART_Init(&s_UARTHandle) != HAL_OK)
        asm("bkpt 255");

    for (;;)
    {
        uint8_t buffer[4];
        HAL_UART_Receive(&s_UARTHandle, buffer, sizeof(buffer), HAL_MAX_DELAY);
        HAL_UART_Transmit(&s_UARTHandle, buffer, sizeof(buffer), HAL_MAX_DELAY);
    }
}*