cancel
Showing results for 
Search instead for 
Did you mean: 

Usart 2 interrupt problem STM32F303CC

m_
Associate II
Posted on December 08, 2014 at 16:06

Hello

I'm using a STM32F303CC lqfp 48 on a new product. I'm trying to use 3 Usart channels. I succesfully use channel 1 and 3 but channel 2 is acting weird. In configure the three channels all in the same manner. But channel 2 keeps firing interrupts. Below is my code for the initialisation and the interrupt routine:

void Usart2_Init(void)
{
//GPIO Init
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, 7);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, 7);
// USART init
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
//Interrupts for uart 2
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; // we want to configure the USART1 interrupts
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;// this sets the priority group of the USART2 interrupts
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // this sets the subpriority inside the group
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // the USART1 interrupts are globally enabled
NVIC_Init(&NVIC_InitStructure); // the properties are passed to the NVIC_Init function which takes care of the low level stuff
USART_ClearFlag(USART2, USART_IT_RXNE);
USART_ClearFlag(USART2, USART_IT_TXE);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART2, USART_IT_TXE, DISABLE);
// Ringbuffers for transmit and receive
RingBufferInit(&uart2RXRingBuffer);
RingBufferInit(&uart2TXRingBuffer);
}

And this is my interrupt routine:

void USART2_IRQHandler(void)
{
if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) // Characters received
{
USART_ClearFlag(USART2, USART_IT_RXNE);
RingBufferPutChar(&uart2RXRingBuffer, USART_ReceiveData(USART2));
}
else
{
USART_ClearFlag(USART2, USART_IT_TXE);
if (!RingBufferEmpty(&uart2TXRingBuffer)){
USART_SendData(USART2, RingBufferGetChar(&uart2TXRingBuffer));
}
else
{
USART_ITConfig(USART2, USART_IT_TXE, DISABLE);
}
}
}

I would really appreciate help because I'm really stuck. My sincerly. #stm32f303 #usart #interrupt
10 REPLIES 10
Posted on December 08, 2014 at 16:43

Are you sure the ClearFlags takes the _IT_ parameters? Doesn't it take _FLAG_

You shouldn't need to clear the IT flags anyhow, reading the DR, or writing to it should clear the RXNE/TXE states.

Don't have this if/else stuff in the interrupt. Check for RXNE, Check for TXE, they are not mutually exclusive.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
m_
Associate II
Posted on December 08, 2014 at 17:02

Thank you Clive for your reply.

Yes i'm pretty sure the ClearFlag function clears the interrupt. I changed if else construction like you said:

void USART2_IRQHandler(void)
{
if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) // Characters received
{
USART_ClearFlag(USART2, USART_IT_RXNE);
USART_SendData(USART2, USART_ReceiveData(USART2));
RingBufferPutChar(&uart2RXRingBuffer, USART_ReceiveData(USART2));
}
if (USART_GetITStatus(USART2, USART_IT_TXE) != RESET)
{
USART_ClearFlag(USART2, USART_IT_TXE);
if (!RingBufferEmpty(&uart2TXRingBuffer)){
USART_SendData(USART2, RingBufferGetChar(&uart2TXRingBuffer));
}
else
{
USART_ITConfig(USART2, USART_IT_TXE, DISABLE);
}
}
}

This code is a little bit better, but I still have some strange behaviour. If I don't place a breakpoint in the interrupt the code is working fine. But when I place a breakpoint inside the interrupt. The breakpoint will hit. But then the mcu will never leave the interrupt anymore.
Posted on December 08, 2014 at 17:50

/**
* @brief Clears the USARTx's pending flags.
* @param USARTx: Select the USART peripheral. This parameter can be one of the
* following values: USART1 or USART2 or USART3 or UART4 or UART5.
* @param USART_FLAG: specifies the flag to clear.
* This parameter can be any combination of the following values:
* @arg USART_FLAG_WUF: Wake up flag.
* @arg USART_FLAG_CMF: Character match flag.
* @arg USART_FLAG_EOBF: End of block flag.
* @arg USART_FLAG_RTOF: Receive time out flag.
* @arg USART_FLAG_CTS: CTS Change flag.
* @arg USART_FLAG_LBD: LIN Break detection flag.
* @arg USART_FLAG_TC: Transmission Complete flag.
* @arg USART_FLAG_IDLE: IDLE line detected flag.
* @arg USART_FLAG_ORE: OverRun Error flag.
* @arg USART_FLAG_NE: Noise Error flag.
* @arg USART_FLAG_FE: Framing Error flag.
* @arg USART_FLAG_PE: Parity Errorflag.
*
* @note
* - RXNE pending bit is cleared by a read to the USART_RDR register
* (USART_ReceiveData()) or by writing 1 to the RXFRQ in the register USART_RQR
* (USART_RequestCmd()).
* - TC flag can be also cleared by software sequence: a read operation to
* USART_SR register (USART_GetFlagStatus()) followed by a write operation
* to USART_TDR register (USART_SendData()).
* - TXE flag is cleared by a write to the USART_TDR register
* (USART_SendData()) or by writing 1 to the TXFRQ in the register USART_RQR
* (USART_RequestCmd()).
* - SBKF flag is cleared by 1 to the SBKRQ in the register USART_RQR
* (USART_RequestCmd()).
* @retval None
*/
void USART_ClearFlag(USART_TypeDef* USARTx, uint32_t USART_FLAG)
{
/* Check the parameters */
assert_param(IS_USART_ALL_PERIPH(USARTx));
assert_param(IS_USART_CLEAR_FLAG(USART_FLAG));
USARTx->ICR = USART_FLAG;
}
/**
* @brief Clears the USARTx's interrupt pending bits.
* @param USARTx: Select the USART peripheral. This parameter can be one of the
* following values: USART1 or USART2 or USART3 or UART4 or UART5.
* @param USART_IT: specifies the interrupt pending bit to clear.
* This parameter can be one of the following values:
* @arg USART_IT_WU: Wake up interrupt.
* @arg USART_IT_CM: Character match interrupt.
* @arg USART_IT_EOB: End of block interrupt.
* @arg USART_IT_RTO: Receive time out interrupt.
* @arg USART_IT_CTS: CTS change interrupt.
* @arg USART_IT_LBD: LIN Break detection interrupt.
* @arg USART_IT_TC: Transmission complete interrupt.
* @arg USART_IT_IDLE: IDLE line detected interrupt.
* @arg USART_IT_ORE: OverRun Error interrupt.
* @arg USART_IT_NE: Noise Error interrupt.
* @arg USART_IT_FE: Framing Error interrupt.
* @arg USART_IT_PE: Parity Error interrupt.
* @note
* - RXNE pending bit is cleared by a read to the USART_RDR register
* (USART_ReceiveData()) or by writing 1 to the RXFRQ in the register USART_RQR
* (USART_RequestCmd()).
* - TC pending bit can be also cleared by software sequence: a read
* operation to USART_SR register (USART_GetITStatus()) followed by a write
* operation to USART_TDR register (USART_SendData()).
* - TXE pending bit is cleared by a write to the USART_TDR register
* (USART_SendData()) or by writing 1 to the TXFRQ in the register USART_RQR
* (USART_RequestCmd()).
* @retval None
*/
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint32_t USART_IT)
{
uint32_t bitpos = 0, itmask = 0;
/* Check the parameters */
assert_param(IS_USART_ALL_PERIPH(USARTx));
assert_param(IS_USART_CLEAR_IT(USART_IT));
bitpos = USART_IT >> 0x10;
itmask = ((uint32_t)0x01 << (uint32_t)bitpos);
USARTx->ICR = (uint32_t)itmask;
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
thaian1112006
Associate II
Posted on July 18, 2016 at 10:52

I have same error with Michel. It keep stuck in interupt imediately apter I enable USART interupt function. Please check my progame. Thank you.

#include ''main.h''
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
void Led_Config(void);
void Delay(uint32_t num);
void USART_Checksum_Config(void);
int main(){
Led_Config();
USART_Checksum_Config();
while(1){ 
GPIO_WriteBit(GPIOA, GPIO_Pin_11, 0);
Delay(500);
GPIO_WriteBit(GPIOA, GPIO_Pin_11, 1);
Delay(500);
}
}
void USART_Checksum_Config(void){ 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_Init(GPIOA, &GPIO_InitStruct); 
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7);
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct);
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
USART_Cmd(USART1, ENABLE);
}
void Delay(uint32_t num){
uint32_t index = 0;
for (index =(12000 * num); index !=0; index--);
}
void Led_Config(void){
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void USART1_IRQHandler(void){
if(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==SET){
GPIO_WriteBit(GPIOA, GPIO_Pin_12, 1);
}
USART_ClearFlag(USART1, USART_FLAG_TXE);
}

It light PA12 Led instead of blink PA

________________

Attachments :

main.c : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0av&d=%2Fa%2F0X0000000bbB%2FthG6xx0bTo.G8._Zt9SYqDg0VXXjGKzhk6PzMscJaQg&asPdf=false
Radosław
Senior
Posted on July 18, 2016 at 11:28

Clearing flag and the end of interrupt is bad idea.

Cheching only TXE flag is not enough, check also if TXE interrupt is enabled.

Delay probably will not work with optimization.

thaian1112006
Associate II
Posted on July 18, 2016 at 11:39 I have changed USART1_IRQHandler as you said but nothing better. I think nothing problem with delay function. You can see it must turn led on before deay in my below programe. Thanks for your reply.

#include ''main.h''
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
void Led_Config(void);
void Delay(uint32_t num);
void USART_Checksum_Config(void);
int main(){
Led_Config();
USART_Checksum_Config();
while(1){ 
GPIO_WriteBit(GPIOA, GPIO_Pin_11, 1);
Delay(500);
GPIO_WriteBit(GPIOA, GPIO_Pin_11, 0);
Delay(500);
}
}
void USART_Checksum_Config(void){ 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
USART_DeInit(USART1);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_Init(GPIOA, &GPIO_InitStruct); 
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7);
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct);
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
USART_Cmd(USART1, ENABLE);
}
void Delay(uint32_t num){
uint32_t index = 0;
for (index =(12000 * num); index !=0; index--);
}
void Led_Config(void){
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void USART1_IRQHandler(void){
if(USART_GetITStatus(USART1, USART_IT_TXE)==SET){
USART_ClearITPendingBit(USART1, USART_IT_TXE);
GPIO_WriteBit(GPIOA, GPIO_Pin_12, 1);
}
}

Posted on July 18, 2016 at 11:40

You will have to supply the USART with data to actually clear the TXE, or disable the interrupt, for it to ever actually leave the background/interrupt state.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
thaian1112006
Associate II
Posted on July 18, 2016 at 12:00

I have test with USART_IT_RXNE too and it have the same problem. Can you give me small function follow your idea? Thanks clive1.

Posted on July 18, 2016 at 15:57

There are examples in this thread.

You can keep RXNE enabled, it will only interrupt when you receive data. But TXE indicates the Transmit Empty, if you DON'T FILL it, then it will remain EMPTY. So USART_SendData(USART1, Something); OR USART_ITConfig(USART1, USART_IT_TXE, DISABLE);

#include ''main.h''
void Led_Config(void);
void Delay(uint32_t num);
void USART_Checksum_Config(void);
int main(){
Led_Config();
USART_Checksum_Config();
while(1){ 
GPIO_WriteBit(GPIOA, GPIO_Pin_11, 1);
Delay(500);
GPIO_WriteBit(GPIOA, GPIO_Pin_11, 0);
Delay(500);
}
}
void USART_Checksum_Config(void){ 
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
USART_DeInit(USART1);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7);
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct);
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
USART_Cmd(USART1, ENABLE);
}
void Delay(uint32_t num){
uint32_t index = 0;
for (index =(12000 * num); index !=0; index--);
}
void Led_Config(void){
GPIO_InitTypeDef GPIO_InitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void USART1_IRQHandler(void){
if(USART_GetITStatus(USART1, USART_IT_TXE)==SET){
USART_SendData(USART1, 0x55);
GPIO_WriteBit(GPIOA, GPIO_Pin_12, 1);
}
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..