2020-01-27 08:26 AM
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);
}
}
2020-01-27 01:12 PM
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.
2020-01-27 01:16 PM
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
2020-01-27 09:38 PM
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 ?
2020-01-27 10:21 PM
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 ....