1
\$\begingroup\$

I am able to successfully send strings and numbers between two STM32F407VG Discovery boards and between two Arduino Uno boards but I am unable to do it between an STM32F4 and an Arduino Uno.

Here is what I did:

  • Arduino Uno RX --> PA2
  • Arduino Uno TX --> PA3
  • A pin from the STM32F4 ground to the arduino ground.

I use the default configuration 9600 baudrate, 8 bit data size, 1 stop bit and no parity. Output type of the gpios on the stm32f4 is push pull and they are pulled up.

Is there something I am missing?

Bence Kaulics
6,47312 gold badges35 silver badges61 bronze badges
asked Sep 24, 2016 at 9:04
\$\endgroup\$
4
  • 2
    \$\begingroup\$ Arduino UNOs work at 5V. Do the discovery board run with the same voltage level? Or is the MCU powered at 3.3V? \$\endgroup\$ Commented Sep 24, 2016 at 9:09
  • 1
    \$\begingroup\$ The MCU on the F4 Discovery board runs at 3 V. \$\endgroup\$ Commented Sep 24, 2016 at 9:12
  • \$\begingroup\$ I believe that's a rhetorical question from Lorenzo, they don't use the same voltage level kudos to you. \$\endgroup\$ Commented Sep 24, 2016 at 9:30
  • \$\begingroup\$ related: electronics.stackexchange.com/questions/94155/… \$\endgroup\$ Commented Jan 3, 2019 at 15:54

2 Answers 2

5
\$\begingroup\$

Probably the logic levels of the UARTs of the two MCUs are not compatible, since they are powered with different voltage levels.

As the the STM32F405 datasheet says, that MCU has a supply voltage range of 1.8V...3.6V, whereas the Arduino UNO board powers its MCU (ATmega 328P) at 5V.

As Bence Kaulics confirms in its comment, your F4 discovery board powers its MCU at 3V, so a logic high on its TX line cannot be higher than 3V, which is the exact minimum input voltage required for a logic high for an ATmega328P powered at 5V (VIH=0.6Vcc=0.6*5V=3V – see datasheetat p.313):

enter image description here

So you need a level shifter between the two boards on the TX line of your discovery board and, possibly, also on its RX line (but this latter could be not necessary, because the STM32 MCU has 5V-tolerant inputs).

Something like this level shifter may work for you:

enter image description here

answered Sep 24, 2016 at 9:19
\$\endgroup\$
1
  • \$\begingroup\$ a voltmeter is indicating a 2.86 v so it's even under the minimum input high voltage, thank you very much sir. \$\endgroup\$ Commented Sep 24, 2016 at 10:38
1
\$\begingroup\$

Sometimes it can be due to PULL-UP resistor setting at STu Rx pin too.

You can either set your USART pins to pull-up/pull-down configuration or floating.
Here are sample codes to make the change Rx pin to floating:


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

OR

with HAL library:


*#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);
 }
}*
answered Oct 31, 2018 at 23:01
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.