Hardware BUG in STM32 serial port, pay attention!

Publisher:星光曲折Latest update time:2016-06-13 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
When debugging the serial port, it was found that the serial port would frequently interrupt, resulting in the inability to execute the main loop!

Debugging revealed that it was a hardware bug of the serial port interrupt:

1. USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); The receive interrupt is enabled, and the ORE interrupt is also enabled at the same time.

        2. The ORE interrupt can only be read using USART_GetFlagStatus(USART1, USART_FLAG_ORE) (when USART_IT_ERR interrupt is not enabled)
Solution:

       1. Enable interrupts during initialization

USART_ITConfig(USART1, USART_IT_PE, ENABLE); //Enable PE error reception interrupt Bit 8PEIE: PE interrupt enable
  //CR2 enables ERR interrupt
  USART_ITConfig(USART1, USART_IT_ERR, ENABLE);

 

       2. Add USART_IT_ORE and other exception interrupt processing to the STM32 interrupt function!

       

//Enable EIE of CR3, bit0: Error interrupt enable, handle USART_IT_ERR, USART_IT_ORE_ER, USART_IT_NE, USART_IT_FE error
if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)
{//Same as @arg USART_IT_ORE_ER: OverRun Error interrupt if the EIE bit is set  
ushTemp = USART_ReceiveData(USART1); //Take out and throw away
USART_ClearFlag(USART1, USART_FLAG_ORE);
}

if(USART_GetFlagStatus(USART1, USART_FLAG_NE) != RESET)
{//Same as @arg USART_IT_NE: Noise Error interrupt
USART_ClearFlag(USART1, USART_FLAG_NE );
}


if(USART_GetFlagStatus(USART1, USART_FLAG_FE) != RESET)
{//Same as @arg USART_IT_FE: Framing Error interrupt
USART_ClearFlag(USART1, USART_FLAG_FE);
}

if(USART_GetFlagStatus(USART1, USART_FLAG_PE) != RESET)
{//Same as @arg USART_IT_PE: Parity Error interrupt
USART_ClearFlag(USART1, USART_FLAG_PE);
}

 

 

 

 

 

There is also an article on the Internet that explains it in more detail, please take a look!

http://bbs.21ic.com/viewthread.php?tid=160999&highlight=USART

 

Today, I encountered some problems when using the USART module and solved them, so I posted them to share.

Problem description:
When using USART for serial communication, I only turned on the receive interrupt and set the preemption priority to the lowest level. The previous priority of the receive interrupt handles more things, which may take up 2ms. When I use 9600 baud rate to send data to the lower computer, the speed is very fast, just keep pressing enter to send! The problem comes out. In less than 1 minute, the communication is unresponsive. The USART configuration code is as follows:
void uart_config(void)
{
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = UART_GetBaud(BaudRate);
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_Init Structure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;     USART_InitStructure.USART_Mode
    = USART_Mode_Rx | USART_Mode_Tx; OL     = USART_CPOL_Low;     USART_InitStructure.USART_CPHA = USART_CPHA_2Edge;     USART_InitStructure.USART_LastBit = USART_LastBit_Enable;     /* Configure USART1 */     USART_Init(USART1, &USART_InitStructure);     /* Enable USART1 receive interrupt */     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);     /* Enable the USART1 */     USART_Cmd(USART1, ENABLE); } Analysis of the problem: 1. Why is there no communication? Through the emulator simulation, it is found that the program has been entering the receive interrupt. Since I did not use the interrupt to send, the program died in the receive interrupt, and no data was sent to the computer. The receive interrupt code is as follows: void UART_Receive(void) {    //Processing the previous communication, do not process the received data     if(bRecieveOK)     {         if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)             USART_ClearITPendingBit(USART1, USART_IT_RXNE);         return;//processing receive data,don't receive again     }     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)     {         if(MoudBusExpir == 0)         {             ucRcePtr = 0;             MoudBusExpir = 20;//50ms         }         else             MoudBusExpir = 20;         /* Read one byte from the receive data register */         ucRS485Buff[ucRcePtr++] = USART_ReceiveData(USART1);         /* Clear the USART1 Receive interrupt */         USART_ClearITPendingBit(USART1, USART_IT_RXNE);     } } 2. Why does it keep running to the receive interrupt? After the breakpoint, I found that (USART_GetITStatus(USART1, USART_IT_RXNE)==RESET, which means that the interrupt was entered even though no data was received, and I only turned on the receive interrupt in the USART configuration! It should be impossible to enter the interrupt without data sent! 3. What interrupt was responded to? I wanted to read all the interrupt status through the function (USART_GetITStatus(), but failed. All interrupt status of USART_IT_XXX are RESET! That is to say, it entered this interrupt service routine even without an interrupt! ? 4. Looking for information STM32F10x Microcontroller Reference Manual (10th Edition, December 2009) P541 found the following description: That is to say, as long as the receive interrupt is turned on, that is, RXNEIE is set to 1, then the ORE interrupt is automatically turned on.

















































Hardware BUG in STM32 serial port, pay attention!
 

But USART_GetITStatus(USART1, USART_IT_ORE )== RESET!!!!
Found the USART_GetITStatus(USART1, USART_IT_RXNE) function and found that the ORE interrupt can only be read when the USART_IT_ERR interrupt is enabled.
Here I want to point out this BUG: the ORE interrupt is generated, but the USART_GetITStatus() function cannot read that the interrupt is SET!

5. Clear the ORE interrupt flag bit
Since we have found what interrupt it is, it should be OK to clear the corresponding interrupt flag bit, right?
USART_ClearITPendingBit(USART1, USART_IT_ORE);
However, the result is that there is no effect! After clearing, read the ORE interrupt status immediately, USART_GetITStatus(USART1, USART_IT_ORE)==RESET. The program still runs dead on the receiving interrupt. Use another function USART_GetFlagStatus(USART1,USART_FLAG_ORE) = SET, it turns out that the ORE flag bit has not been cleared.

6. Problem Solved
Why can't it be cleared? I was troubled, so I looked for more information and found that on page P523, as shown below: The receive interrupt program is changed to: void UART_Receive(void) {     if (USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET) // Note! Cannot use if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) to judge     {         USART_ReceiveData(USART1);     }    //Processing the previous communication, do not process the received data     if(bRecieveOK)     {         if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)             USART_ClearITPendingBit(USART1, USART_IT_RXNE);         return;//processing receive data,don't receive again     }     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)     {         if(MoudBusExpir == 0)         {             ucRcePtr = 0;             MoudBusExpir = 20;//50ms         }         else             MoudBusExpir = 20;         /* Read one byte from the receive data register */         ucRS485Buff[ucRcePtr++] = USART_ReceiveData(USART1);         /* Clear the USART1 Receive interrupt */         USART_ClearITPendingBit(USART1, USART_IT_RXNE);     } } Summary: Note: 1. USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); enables the receive interrupt, so the ORE interrupt is also enabled.                2. The ORE interrupt can only be read using USART_GetFlagStatus(USART1, USART_FLAG_ORE) (when the USART_IT_ERR interrupt is not enabled) BUG suggestion: 1. In the STM32 library, can the USART_GetITStatus() function be modified to handle the USART_IT_ORE interrupt? In other words, as long as I turn on the receive interrupt, I can also use USART_GetITStatus(USART1,USART_IT_ORE) to read it when there is an ORE interrupt.
Hardware BUG in STM32 serial port, pay attention!
 

































Keywords:STM32 Reference address:Hardware BUG in STM32 serial port, pay attention!

Previous article:STM32 USART library function USART_SendData bug
Next article:Regular garbled characters encountered in STM32 serial communication

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号