UART entre STM32F4 y un Arduino Uno

Puedo enviar con éxito cadenas y números entre dos placas Discovery STM32F407VG y entre dos placas Arduino Uno, pero no puedo hacerlo entre una STM32F4 y una Arduino Uno.

Aquí esta lo que hice:

  • Arduino Uno RX --> PA2
  • Arduino Uno TX --> PA3
  • Un pin del suelo STM32F4 al suelo arduino.

Utilizo la configuración predeterminada de 9600 baudios, tamaño de datos de 8 bits, 1 bit de parada y sin paridad. El tipo de salida de los gpios en el stm32f4 es push pull y se levantan.

¿Hay algo que este olvidando?

Los Arduino UNO funcionan a 5V. ¿Funciona la placa Discovery con el mismo nivel de voltaje? ¿O la MCU está alimentada a 3.3V?
La MCU en la placa F4 Discovery funciona a 3 V.
Creo que es una pregunta retórica de Lorenzo, no usan el mismo nivel de voltaje que felicitarte.

Respuestas (2)

Probablemente los niveles lógicos de los UART de los dos MCU no sean compatibles, ya que se alimentan con diferentes niveles de voltaje.

Como dice la hoja de datos STM32F405 , esa MCU tiene un rango de voltaje de suministro de 1.8V...3.6V, mientras que la placa Arduino UNO alimenta su MCU ( ATmega 328P ) a 5V.

Como confirma Bence Kaulics en su comentario, su placa de descubrimiento F4 alimenta su MCU a 3 V, por lo que una lógica alta en su línea TX no puede ser superior a 3 V, que es el voltaje de entrada mínimo exacto requerido para una lógica alta para un ATmega328P alimentado a 5 V. (V IH =0.6Vcc=0.6*5V=3V – ver ficha técnica en p.313):

ingrese la descripción de la imagen aquí

Por lo tanto, necesita un cambiador de nivel entre las dos placas en la línea TX de su placa de descubrimiento y, posiblemente, también en su línea RX (pero esta última podría no ser necesaria, porque la MCU STM32 tiene entradas tolerantes a 5V).

Algo como este cambiador de nivel puede funcionar para usted:

ingrese la descripción de la imagen aquí

un voltímetro indica 2,86 v, por lo que está incluso por debajo del alto voltaje de entrada mínimo, muchas gracias, señor.

A veces, también puede deberse a la configuración de la resistencia PULL-UP en el pin STu Rx.

Puede configurar sus pines USART en configuración pull-up/pull-down o flotante.
Aquí hay códigos de muestra para cambiar el pin Rx a flotante:


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

O

con la biblioteca HAL:


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