cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G0B0 USART1 data incorrect

- STM32G0B0 USART1 receiving RS485 data via interrupt driven data collection.

   Our micro is attached to a RS485 interface(38400, 8,N,1) receiving BACnet data. The data taken on the 485 bus is different from what we receive in the USART buffers. We have reviewed the USART config many times over and can not find anything obvious.

485:        55 FF 01 11 0C 00 00 DC

USART:  55 00 7F 7A DE FF EB 00

Notes: All the 485 packets seem to be 8 bytes in length and the micro received packets can be seven or 8 bytes. The scope trace is taken going into the micro after the 485 chip(THVD1410DR). The scope trace seems to show the second byte as all ones.

We have tried different USART1 configs but the received data always seems wrong after the first byte. Any help is appreciated.

Capture.JPG

 

RigolDS0.jpg

 

	LL_USART_InitTypeDef USART_InitStruct = {0};

	USART_InitStruct.PrescalerValue			= LL_USART_PRESCALER_DIV1;
	USART_InitStruct.BaudRate				= 38400;
	USART_InitStruct.DataWidth				= LL_USART_DATAWIDTH_8B;
	USART_InitStruct.StopBits				= LL_USART_STOPBITS_1;
	USART_InitStruct.Parity					= LL_USART_PARITY_NONE;
	USART_InitStruct.HardwareFlowControl	= LL_USART_HWCONTROL_NONE;
	USART_InitStruct.TransferDirection		= LL_USART_DIRECTION_TX_RX;
	USART_InitStruct.OverSampling			= LL_USART_OVERSAMPLING_16;
	LL_USART_Init(USART1, &USART_InitStruct);
	LL_USART_DisableFIFO(USART1);
	LL_USART_ConfigAsyncMode(USART1);
void USART1_IRQHandler(void)
{
	if(LL_USART_IsActiveFlag_RXNE_RXFNE(USART1) != RESET)
	{
		/* Read one byte from the receive data register and log the current time stamp */
		uart1RxBuffer[rxHead][uart1RX[rxHead].rxSize]	= LL_USART_ReceiveData8(USART1);
		uart1RX[rxHead].rxTime[uart1RX[rxHead].rxSize]	= timer3_get_count();
		uart1RX[rxHead].rxSize++;
        }
}

 

Capture.JPG

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

UART is typically idle high. Is yours idle low and if so is RXINV set?

Seems like 0x55 0x00 is plausible for the first 2 bytes to me. Start bits in green, stop bits red.

TDK_0-1692977875983.png

 

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

6 REPLIES 6
TDK
Guru

UART is typically idle high. Is yours idle low and if so is RXINV set?

Seems like 0x55 0x00 is plausible for the first 2 bytes to me. Start bits in green, stop bits red.

TDK_0-1692977875983.png

 

If you feel a post has answered your question, please click "Accept as Solution".

Hmmm, seems like RXINV is off. Not really sure how the RS485 chips takes the twisted pair data and converts it. I'll look at the data sheet. Just seemed weird that the first byte was fine but the second was inverted.

Capture.JPG

 

Capture2.JPG

You may have swapped A and B Unfortunately, there's no standard for this, and in some environments (e.g.Modbus) the marking is opposite to what the IC manufacturers use.

JW

After talking to a few friends over the weekend and your comment about Idle looking inverted, we tried inverting the USART RX line this morning.

LL_USART_SetRXPinLevel(USART1, LL_USART_RXPIN_LEVEL_INVERTED);

The 485 line data and internal RX buffer finally match.

Capture.JPG

Capture2.JPG

So the THVD1410DR chip's output to the micro is inverted from normal serial. My last question would be if we need to invert the TX output? Thanks for all the help to everyone here.

If TX and RX are driving/receiving from the same bus, then they should both be inverted.

 

If you feel a post has answered your question, please click "Accept as Solution".

Set the TX to inverted.

// The RS485 chip inverts the Idle level of the TX/RX pins.
LL_USART_SetRXPinLevel(USART1, LL_USART_RXPIN_LEVEL_INVERTED);
LL_USART_SetTXPinLevel(USART1, LL_USART_TXPIN_LEVEL_INVERTED);

Everything is running correctly. Thanks again for all the help.