Skip to main content
Visitor II
July 14, 2021
Question

STM8AF6223A UART 4 RXNE Flag is not set

  • July 14, 2021
  • 2 replies
  • 798 views

I have a STM8AF6223A Processor connected to another processor on Pin 2, UART TX and Pin 3, UART RX.

The oscilloscope verifies that both processors send correctly, 19200 Baud, 8bit Data, no parity, 1 stop bit.

The STM8 processor receives the data in the UART4->DR register mostly correct, but not always correct. How is it possible that the RXNE Flag does not get set?

I am using the stdlib STM8S/A Standard Peripherals Library V2.3.1 26-April-2018. The IDE is ST Visual Develop with the Cosmic Compiler.

This is my example code:

The waitCounter always increases to 1000, the RXNE Flag is never set. At the same time the other processor sends 0x55 constantly, the data is available.0693W00000Bde61QAB.png0693W00000Bde5XQAR.png

/* Includes ------------------------------------------------------------------*/
#include "stm8s.h"
 
/* Private defines -----------------------------------------------------------*/
#define F_CPU 2000000UL
#define _GPIO 1 /* enables the GPIOs */
#define _EXTI 1 /* enables the EXTI */
 
 
 
void SendData(uint16_t min, uint16_t current)
{
 uint8_t main_state = 1;
 uint8_t checksum = 0;
 uint8_t dummy = 0;
 
 // Check and clear uart error flags
 // Read SR then read DR registers
 dummy = UART4->SR;
 if (dummy & (UART4_SR_OR + UART4_SR_FE + UART4_SR_PE))
 {
 dummy = UART4->DR;
 }
 
 while(main_state != 0)
 {
 switch (main_state)
 {
 case 0:
 // end sending
 break;
 
 case 1:
 // Send sync byte
 while (!(UART4->SR & UART4_SR_TXE)) {};
 UART4->DR = 0x9A;
 main_state++;
 break;
 
 case 2:
 // Send sync byte 2
 while (!(UART4->SR & UART4_SR_TXE)) {};
 UART4->DR = 0x9B;
 main_state++;
 break;
 
 case 3:
 // Send first long term byte
 while (!(UART4->SR & UART4_SR_TXE)) {};
 UART4->DR = (uint8_t)(min);
 checksum = (uint8_t)(min);
 main_state++;
 break;
 
 case 4:
 // Send second long term byte
 while (!(UART4->SR & UART4_SR_TXE)) {};
 UART4->DR = (uint16_t)(min >> 8);
 checksum = checksum + (uint16_t)(min >> 8);
 main_state++;
 break;
 
 case 5:
 // Send first current byte
 while (!(UART4->SR & UART4_SR_TXE)) {};
 UART4->DR = (uint8_t)(current);
 checksum = checksum + (uint8_t)(current);
 main_state++;
 break;
 
 case 6:
 // Send second current byte
 while (!(UART4->SR & UART4_SR_TXE)) {};
 UART4->DR = (uint16_t)(current >> 8);
 checksum = checksum + (uint16_t)(current >> 8);
 main_state++;
 break;
 
 case 7:
 // Send checksum byte
 while (!(UART4->SR & UART4_SR_TXE)) {};
 UART4->DR = checksum;
 main_state++;
 break;
 
 case 8:
 // Send termination byte
 while (!(UART4->SR & UART4_SR_TXE)) {};
 UART4->DR = 0xFF;
			while (!(UART4->SR & UART4_SR_TXE)) {};
 main_state = 0;
 break;
 
 default:
 main_state = 0;
 break;
 }
 }
}
 
void main(void)
{
 uint16_t i = 0;
	uint8_t receivedCommand = 0;
	bool waitForData = TRUE;
	FlagStatus receiveRegisterNotEmpty = RESET;
	uint8_t dummy;
	uint16_t waitCounter = 0;
	
	uint8_t receive_byte = 0;
 
 //disableInterrupts();
 
 UART4_DeInit();
 
 UART4_Init((u32)19200, // uint32_t BaudRate
 UART4_WORDLENGTH_8D, // UART_WordLength_TypeDef WordLength
 UART4_STOPBITS_1, // UART_StopBits_TypeDef StopBits
 UART4_PARITY_NO, // UART_Parity_TypeDef Parity
 UART4_SYNCMODE_CLOCK_DISABLE, // UART_SyncMode_TypeDef SyncMode
 UART4_MODE_TXRX_ENABLE // UART_Mode_TypeDef Mode
 );
 
 //UART4_Cmd(DISABLE);
 
 /* Enable general interrupts */
 //enableInterrupts();
 
 /* Infinite loop */
 while (1)
 {
	 // Try to communicate
 UART4_Cmd(ENABLE);
		
 // Wait
 for (i = 0; i < 2000; i++) // 4000us delay
 {
 _asm("nop");
 }
		
		// Check and clear uart error flags
 // Read SR then read DR registers
		dummy = UART4->DR;
 dummy = UART4->SR;
 if (dummy & (UART4_SR_OR + UART4_SR_FE + UART4_SR_PE))
 {
 dummy = UART4->DR;
 }
 
		waitCounter = 0;
		//waitForData = TRUE;
		while((UART4_GetFlagStatus(UART4_FLAG_RXNE) == RESET) 
		 && (waitCounter < 1000))
		{
			// Wait
 for (i = 0; i < 20; i++) // 40us delay
 {
 _asm("nop");
 }
			waitCounter++;
		}
	
	 receivedCommand = UART4_ReceiveData8();
		
		if (receivedCommand == 0x55)
		{
			receivedCommand = 1;
		}
		else
		{
			receivedCommand = 0;
		}
		
		if (1 == receivedCommand)
		{
 SendData(600, 650);
			
			SendData(600, 650);
			
			SendData(600, 650);
		}
		
		UART4_Cmd(DISABLE);
		
 if (0 == receivedCommand) // TI may not have power
 {
 // Do not measure too often, add an additional delay
 for (i = 0; i < 50000; i++) // 100ms delay
 {
 _asm("nop");
 }
 }
 }
}

    This topic has been closed for replies.

    2 replies

    CPack.1Author
    Visitor II
    July 28, 2021

    Further tests found, that the RXNE flag was not set anymore, if errors were cleared before:

     dummy = UART4->SR;
     if (dummy & (UART4_SR_OR + UART4_SR_FE + UART4_SR_PE))
     {
     dummy = UART4->DR;
     }

    The problem is solved by receiving interrupt-based.

    Graduate II
    July 28, 2021

    Take a note that typically bit fields are merged with a bitwise OR ('|') operation, not addition ('+').