Skip to main content
User.152
Associate
December 17, 2018
Solved

STM32F072 USART3 interrupt error

  • December 17, 2018
  • 6 replies
  • 1660 views

recently I used the STM32F072 USRT3 to communicate with my peripheral, the configuration of USART3 is follow:

static void USART3_Init( void )

{

 GPIO_InitTypeDef GPIO_InitStructure;

 USART_InitTypeDef USART_InitStructure;

 NVIC_InitTypeDef NVIC_InitStructure;

 /* Enable GPIO clocks */

 RCC_APB1PeriphClockCmd(RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOB, ENABLE);

 /* Enable USART3 clock */

 USER_USART3_APBPERIPHCLOCK(USER_USART3_CLK, ENABLE);

 /**USART3 GPIO Configuration

  PB10   ------> USART3_TX

  PB11   ------> USART3_RX

 */

 /* Configure USART Tx and Rx as alternate function push-pull */

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

 GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_10|GPIO_Pin_11;

 GPIO_Init(GPIOB, &GPIO_InitStructure);

 /* Enable SC_USART IRQ */

 NVIC_InitStructure.NVIC_IRQChannel = USER_USART3_IRQn;

 NVIC_InitStructure.NVIC_IRQChannelPriority = 1;

 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

 NVIC_Init(&NVIC_InitStructure);

 USART_DeInit(USER_USART3);

 /*Configure the initial baudrate*/

 USART_InitStructure.USART_BaudRate = 115200;

 USART_InitStructure.USART_WordLength = USART_WordLength_8b;

 USART_InitStructure.USART_StopBits = USART_StopBits_1;

 USART_InitStructure.USART_Parity = USART_Parity_No;

 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

 USART_Init(USER_USART3, &USART_InitStructure);

 USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);

 USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);

 USART_ReceiveData(USART3); //clear the RXNE pending bit

 USART_ClearITPendingBit(USART3, USART_IT_IDLE);

 /* Enable SC_USART */

 USART_Cmd(USER_USART3, ENABLE);

}

the interrupt function is :

void USART3_4_IRQHandler( void )

{

if(USART_GetITStatus(USER_USART3, USART_IT_RXNE) != RESET)

  {

   /* Disable USER_USART3 RXNE Interrupt */

   USART_ITConfig(USER_USART3, USART_IT_RXNE, DISABLE);

   USART_ReceiveData(USER_USART3);

  }

}

as I start to debug ,the value of: USART_GetITStatus(USART3, USART_FLAG_RXNE) is SET�? but ,I don't send any data to the STM32F072 device, why the interrupt flag is SET?

This topic has been closed for replies.
Best answer by turboscrew

What I mean is that now you first enable interrupts and then clear the possible causes. And if there happens to be bits set in the received data register (that's possible after enabling the USART), the interrupt takes place right after enabling the interrupts and before the read.

Due to the pipeline, it might be a good idea to put DSB (barrier) between clearing the interrupt causes and enabling interrupts. I once had a problem, when in the beginning I first cleared interrupt conditions, then interrupts and then enabled the interrupts. The clearing of the interrupts didn't take effect early enough, so the execution ended up in the interrupt service with interrupt flag cleared. Putting a DSB in between the flag clearing and interrupt enabling fixed it.

6 replies

Tesla DeLorean
Guru
December 17, 2018

Not sure I can unmuddle this.

#defines not provided and used inconsistently

AHB device clocks not enabled via APB1

AF pin sources not muxed properly

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
User.152
User.152Author
Associate
December 17, 2018

the global definition of this as show below:

#define USER_USART3            USART3

#define USER_USART3_CLK          RCC_APB1Periph_USART3

#define USER_USART3_APBPERIPHCLOCK     RCC_APB1PeriphClockCmd

#define USER_USART3_IRQn          USART3_4_IRQn

#define USER_USART3_4_IRQHandler      USART3_4_IRQHandler

if this not work, can you offer a template sample code about STM32F072 USART3 ?

turboscrew
Senior III
December 17, 2018

Not sure. but:

 USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);

 USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);

 USART_ReceiveData(USART3); //clear the RXNE pending bit

 USART_ClearITPendingBit(USART3, USART_IT_IDLE);

Try reordering these - clear interrupts before enabling. Maybe even DSB between.

User.152
User.152Author
Associate
December 17, 2018

the global definition of this as show below:

#define USER_USART3             USART3

#define USER_USART3_CLK           RCC_APB1Periph_USART3

#define USER_USART3_APBPERIPHCLOCK     RCC_APB1PeriphClockCmd

#define USER_USART3_IRQn           USART3_4_IRQn

#define USER_USART3_4_IRQHandler       USART3_4_IRQHandler

turboscrew
turboscrewBest answer
Senior III
December 19, 2018

What I mean is that now you first enable interrupts and then clear the possible causes. And if there happens to be bits set in the received data register (that's possible after enabling the USART), the interrupt takes place right after enabling the interrupts and before the read.

Due to the pipeline, it might be a good idea to put DSB (barrier) between clearing the interrupt causes and enabling interrupts. I once had a problem, when in the beginning I first cleared interrupt conditions, then interrupts and then enabled the interrupts. The clearing of the interrupts didn't take effect early enough, so the execution ended up in the interrupt service with interrupt flag cleared. Putting a DSB in between the flag clearing and interrupt enabling fixed it.

User.152
User.152Author
Associate
December 19, 2018

Thank you very much,the problem had been solved yet