cancel
Showing results for 
Search instead for 
Did you mean: 

UART2 on Virtual COM works but UART1 does not

L4CAJS
Associate II

Hi everyone,

Figured I banged my head against a wall long enough, so might as well ask even if it is a really simple fix.

So far I have only used USART2 to write data to the Virtual COM port from my nucleo board, now I have need to write other data out through a different USART channel (USART1).

I generated the template for the initialization for both of the USART ports using CubeMX and I double/triple checked the initialization are the exact same minus the Ports and Pins the TX/RX are mapped to.

I am using the HAL_UART_Transmit() (not the DMA or IT) function, and it works flawlessly on USART2 but nothing happens when writing to USART1. I have stepped through the function and everything is the same, it is successfully writing it but I am not receiving anything on the transmit line (Serial console on PC). I have also tried receiving with USART1 and I still am receiving nothing on the nucleo board end.

I have debugged this from many different ways and I feel like I am missing a specific step to get the USART1 to work, I am thinking that since USART2 is a Virtual COM port it might have a slightly different initialization or a different way to transmit/receive information.

My simple test was:

for (;;)
	{
		uint8_t buffer[4];
		HAL_UART_Receive(&huart1, buffer, sizeof(buffer), 0xFFFF);
		HAL_UART_Transmit(&huart2, buffer, sizeof(buffer), 0xFFFF);
	}

I tried receiving and writing to both USART2 and it worked, and then I tried both USART1 and received nothing. When trying to use the code above, I am seeing a successful transmit VIA my USB to UART adaptor (VIA the transmit LED), but nothing seems to be reaching the nucleo board.

I have checked:

  • Initialization for both USART1/2 are the exact same
  • Checked that the ports they are assigned to VIA cube MX are correct
  • That the wiring between ports defined on nucleo are properly wired to be USB-UART adapter
  • There is valid connectivity between the wires
  • The USB-UART adapter is working VIA loopback check

The one thing I haven't tried yet is assigning USART1 to different PINS and trying it in case one of my pins are messed up, but my logic was that highly unlikely both transmit and receive are dead.

Please let me know if you need any more information.

EDIT: I am using STM32G071RB, specifically the NUCLEO-G071RB.

I created a fresh project and only touched the USART1, init code below

static void MX_USART1_UART_Init(void)
{
 
  /* USER CODE BEGIN USART1_Init 0 */
 
  /* USER CODE END USART1_Init 0 */
 
  /* USER CODE BEGIN USART1_Init 1 */
 
  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */
 
  /* USER CODE END USART1_Init 2 */
 
}
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(huart->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspInit 0 */
 
  /* USER CODE END USART1_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();
  
    __HAL_RCC_GPIOC_CLK_ENABLE();
    /**USART1 GPIO Configuration    
    PC4     ------> USART1_TX
    PC5     ------> USART1_RX 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF1_USART1;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
  /* USER CODE BEGIN USART1_MspInit 1 */
 
  /* USER CODE END USART1_MspInit 1 */
  }
 
}

To test the transmit I used the following function.

while (1)
  {
	  debugPrint(&huart1, "Test Message");       // print
	  debugPrint(&huart1, "New Line\r\n");            // manual new line
 
  }
 
void debugPrint(UART_HandleTypeDef *huart, char _out[]){
	HAL_UART_Transmit(huart, (uint8_t *) _out, strlen(_out), 10);
}

 I also tried switching the ports, I made PA10 Rx and PA9 as Tx, hooked it up and wired same way and still don't seem to be reading anything either. Not sure what I am doing wrong, I don't seem to have this issue with USART2.

1 ACCEPTED SOLUTION

Accepted Solutions
L4CAJS
Associate II

So turns out the issue that I had was with my UART to USB device. I was able to do a simple loopback on it but sending any sort of Rx/Tx transmission from an external source didn't work, not sure why.

I ended up doing UART (Rx on STM -> Tx on Rs485 & Tx on STM -> Rx on RS485) to RS485 to USB and I was successfully able to transmit information which leads me to believe that everything in terms of STM code and initialization was all fine, but the issue was in the device I was using to recieve the information.

Thank you very much!

View solution in original post

9 REPLIES 9

These Receiver/Transmit routines will block.

Not seeing init code so hard to comment. Dump the USART register, if all zero, check clocks initialized.

Check PA9/PA10 not getting roped into USB initialization. VBUS/ID

Not sure what "STM32" you're using. F1 has some peripheral level issues with mapping of pins to different units.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Do one thing at a time - strip down the code to bare minimum to test the USART, omitting USB etc.

As Clive Avogadro said, read out and check/compare/post the USART and relevant GPIO registers' content.

Check the Rx/Tx pins physical connection by setting them up as GPIO output and "wiggling" from the mcu. This can be easily done in the debugger alone, you don't need to click in another code.

As Clive Avogadro said, our crystal cubes won't penetrate into what you've clicked in, and won't tell us what STM32 are you using on what hardware/board.

And change your username to a normal nick.

I don't Cube/CubeMX.

JW

1) Changed the code around so that it was only transmitting same message over and over, still same issue.

2) I posted the init code on a fresh project, sorry for not posting that originally.

3) PA9/PA10 aren't be initialized, but specifically PC4 and PC5 are my TxRx pins

4) Posted in above edit, but STM32G071RB on the Nucleo-G071RB

Thank you for the help!

1) I stripped my code to the bare minimum, only have UART1 initialized, no other UART or GPIO pins.

2) Any pointers on how to check/compare/post the USART and relevant GPIO register content? I have the register values as I step through the code but i don't necessarily know which ones correspond to which part of the HAL_UART_ functions.

3) I checked the physical connections of PC4 and PC5 but configuring them as GPIO pins and setting them high/low.

4) Sorry, forgot to post source and model, source is in the edit above and it is a STM32G071RB.

Will change my username.

Spent most of the day debugging, to respond to the USART and GPIO Registers:

  • Both USART1(Not working) and USART2(Working) Registers have very simlar inits. They have the same nonzero values of BRR, TDR, the only nonzero value that differentiates is the ISR value, but in this case both the UARTs use polling not Interupts (so i didn't think this made a difference.
  • I checked both of the GPIO registers for USART1 and USART2, both are initialized the exact same way.0690X00000As6QIQAZ.png

ISR for USART1 indicates Framing Error, which might indicate that the receiver does work, but the incoming characters are of incorrect form - baudrate, polarity, or simply there's only some noise on the respective Rx pin.

Check in RCC registers, if both USARTs are clocked in the same way. The G0 appears to have an USART clock switch in RCC_CCIPR.

JW

Thank you for the replies JW, much appreciated for the help you are giving trying to fix this!

I double checked the baudrate as well as the wired connections and ensured it is all hooked up correctly, but my main concern here is the ability to transmit information off the board. The application it is being used for is to just transmit UART messages, which i still can't get to work unfortunately. Any ideas in regard to that specific part?

Tx should be simpler - just set up the USART Tx pin in GPIO and the USART itself, and then write to the data register e.g. in the debugger, and observe the pin using an oscilloscope or logic analyzer.

JW

L4CAJS
Associate II

So turns out the issue that I had was with my UART to USB device. I was able to do a simple loopback on it but sending any sort of Rx/Tx transmission from an external source didn't work, not sure why.

I ended up doing UART (Rx on STM -> Tx on Rs485 & Tx on STM -> Rx on RS485) to RS485 to USB and I was successfully able to transmit information which leads me to believe that everything in terms of STM code and initialization was all fine, but the issue was in the device I was using to recieve the information.

Thank you very much!