Skip to main content
er3481
Associate III
January 27, 2020
Question

UART receive data problem

  • January 27, 2020
  • 4 replies
  • 1588 views

Hi,

I am using stm32f103 mcu for UART data transmit and receive. I am using UART interrupt for both receiving and transmitting. Sometimes received data takes a different value than it should be. This occurs when i send some data from stm32 to serial port at the same time. All data can be received normally but sometimes some of 10-byte data is changed to a different value. Any advise ?

Thanks...

void USART1_IRQHandler(void)
{
 if((USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) && (USART_GetITStatus(USART1, USART_IT_TXE) == RESET))
 { 
 USART_ClearITPendingBit(USART1, USART_IT_RXNE); 
 unsigned char data;
 
 data = USART_ReceiveData(USART1);
 uart_buffer[uart_buffer_index] = data;
 uart_buffer_index++; 
 //do some stuff with uart_buffer[] 
 }
 
 if( (USART_GetITStatus(USART1, USART_IT_TXE) != RESET ) && (USART_GetITStatus(USART1, USART_IT_RXNE) == RESET))	// TX buffer not empty
	{
 
		if(byte_counter != 0)//if there is any data in data_buff array
 { 
 USART_SendData(USART1, (uint16_t)*out_pointer);//send buffer data 
 out_pointer++;	//inc pointer for next data in data_buff array
 byte_counter--;
 if(out_pointer >= &data_buff[0] + TX_BUFFER_SIZE)
 { 
 out_pointer = &data_buff[0];
 }
 }
 else
 {
 USART_ClearITPendingBit(USART1, USART_IT_TC);
 USART_ClearITPendingBit(USART1, USART_IT_TXE);
 USART_ITConfig(USART1, USART_IT_TXE, DISABLE);//UC1IE &= ~ UCA1TXIE; // Disable USCI_A1 TX interrupt
 
 }
	}
 
	if(USART_GetFlagStatus(USART1,USART_FLAG_ORE) != RESET)
 { 
 (void)USART_ReceiveData(USART1);
 
 }
}

This topic has been closed for replies.

4 replies

KnarfB
Super User
January 27, 2020

When both interrupt flags are set, none of the if instruction bodies will be executed and possibly a char can be missed.

I would only test for each flag separately

if((USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
 ...
}
 
if( (USART_GetITStatus(USART1, USART_IT_TXE) != RESET ) {
 ...
}

and ideally also for error conditions.

Tesla DeLorean
Guru
January 27, 2020

if((USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) && (USART_GetITStatus(USART1, USART_IT_TXE) == RESET)) // WHY? These bits are independent, DR acts differently for Read vs Write, it is NOT a memory cell, but TWO different holding registers

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
er3481
er3481Author
Associate III
January 28, 2020

Hi, @Community member​ 

when i use the if instructions seperately, the same problem also occurs.

if((USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
 ...
}
 
if( (USART_GetITStatus(USART1, USART_IT_TXE) != RESET ) {
 ...
}

What do you advise ?

vik1970va
Associate II
January 28, 2020

The first is not a match in the code that I saw is if (byte_counter! = 0) and else upon exit from the interrupt flags are not always reset

USART_IT_TC, USART_IT_TXE

I would write like this:

else
 {
 USART_ITConfig(USART1, USART_IT_TXE, DISABLE);//UC1IE &= ~ UCA1TXIE; // Disable USCI_A1 TX interrupt 
 } 
 USART_ClearITPendingBit(USART1, USART_IT_TC);
 USART_ClearITPendingBit(USART1, USART_IT_TXE);
	} //EXIT TX buffer not empty

If you entered // TX buffer not empty, then it is necessary to reset the flags, but they do not always reset ....