cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F072 USART3 interrupt error

User.152
Associate II

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?

1 ACCEPTED SOLUTION

Accepted Solutions
turboscrew
Senior III

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.

View solution in original post

6 REPLIES 6

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
Up vote any posts that you find helpful, it shows what's working..
turboscrew
Senior III

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.

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

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

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.

Thank you very much,the problem had been solved yet