0
\$\begingroup\$

I thought to create a simple test to send and receive a buffer via UART. I succeeded in sending bytes from my PC to the nucleo bord and receiving them in blocking and non-blocking mode. But for some reason I can't succeed to send data from UART3 and receive the bytes on UART2.

I have a nucleo-f103rb and have the following pins setup:

  • UART2: tx=PA2;rx=PA3
  • UART3: tx=PB10;rx=PB11

And then the following code:

  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
    if (HAL_UART_Transmit(&huart3, send, 2, 1000) == HAL_OK)
    {
        if (HAL_UART_Receive(&huart2, receive, 2, 1000) == HAL_OK)
        {
            HAL_GPIO_TogglePin(GPIOA, LD2_Pin);
        }
    }
  }

All the boiler plate is generated using cube mx. So the UART 2 and 3 are all default, same for the button pins.

  • I connected the transmit pin of uart3 to the receiving pin of uart2
  • I connected the receive pin of uart3 to the transmitting pin of uart2 (while not used in this trivial example though)

What am I missing here?

Update

As comments and answers suggested, I shouldn't be using the blocking mode approach. So I rewrote it slightly to rely more on interrupts.

I attached a callback to the nucleo blue button

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == B1_Pin)
    {
        HAL_UART_Transmit_IT(&huart3, (uint8_t *)send, 2);
    }
}

And I added a callback for receiving stuff over uart

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_UART_RxCpltCallback can be implemented in the user file
   */

     // Toggle the pin to see some proof that I received something
     HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);

     // Resubscribe uart2
     HAL_UART_Receive_IT(&huart2, (uint8_t *)receive, 2);
}

In the main function I call the interrupt so that the callback is active.

while (HAL_UART_Receive_IT(&huart2, receive, 2) != HAL_OK);

__NOP();
while (1)
{
}

Again, when debugging through I do end up in the button released callback, but the callback on the uart receive isn't triggered. When I send stuff from the PC, it does. So it seems that sending stuff via uart3 isn't working. So I guess that must be the wiring.

enter image description here

But I really can't see what I am missing here, the pins are clearly defined in the pinout here: https://os.mbed.com/platforms/ST-Nucleo-F103RB/.

I hope the photo is clear enough, but this is how I connected them.

enter image description here

\$\endgroup\$
  • \$\begingroup\$ what is the observed result? \$\endgroup\$ – jsotola Sep 22 '19 at 18:15
  • \$\begingroup\$ Did you succeed with both UART2 and UART3 talking to your PC? If not, check you I/O pin config. Get each working with your PC first, then connect them to each other. \$\endgroup\$ – DKNguyen Sep 22 '19 at 18:15
  • \$\begingroup\$ @jsotola when i step through the code sending is successful, but receiving isn't. \$\endgroup\$ – bas Sep 22 '19 at 18:18
  • 1
    \$\begingroup\$ Make sure you aren't using blocking methods for this! If you use both a blocking transmit and a blocking receive, you won't receive until the transmit is done, so you'd at most catch one byte and an overrun error. ST's design of the HAL UART stuff is rather illogical, most people ignore those and write their own ISR buffering routine against the hardware. Blocking transmit can work though. \$\endgroup\$ – Chris Stratton Sep 22 '19 at 18:22
  • 2
    \$\begingroup\$ You are not using interrupts correctly, since you are still blocking while waiting for them.. As I said before, the STM32 UART HAL stuff is really goofy, most people do not use it beyond configuring the UART, but write their transmit routine and receive ISR. That's not to say that you might not also have a wiring problem, but your code is wrong. You need to enable the interrupt before you start transmitting, and have it collect the results in a buffer. \$\endgroup\$ – Chris Stratton Sep 22 '19 at 19:11
1
\$\begingroup\$

It works just as expected from that code that controls the uarts - first there is transmission out on UART3, and after that is fully complete there is reception from UART2. So UART2 does not see any reception as at that time there is no transmission going on UART3.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.