cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f373 interrupt problem

ysmgreen
Associate
Posted on October 27, 2016 at 06:28

Hello

I am using stm32f373 chip to implement SDADC, USART, Timer, etc, and now I have a problem with interrupt.

I tested USART1 interrupt code as below. If I send any character to STM, then it would receive it and send back to my computer. But I couldn't receive anything.

void USART1_IRQHandler(void)

{

    char receive_data;

 

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

    {

        receive_data = USART_ReceiveData(USART1) & 0xFF;

       

        USART_SendData(USART1, receive_data);

        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET );       

       

        USART_ClearITPendingBit(USART1, USART_IT_RXNE); 

    }

   

}

void usart1_test_interrupt(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    USART_InitTypeDef USART_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;

   

    /* AHB Clock enable for USART(GPIOA9, A10) */

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

   

    /* USART1 clock enable */

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

   

    /* USART1 Pins configuration **************************************************/

    GPIO_DeInit(GPIOA);

   

    /* Connect pin to Periph */

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7);   

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7);

   

    /* Configure pins as AF pushpull */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;

    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_NOPULL;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* USARTx configured as follow:

  - BaudRate = 115200 baud 

  - Word Length = 8 Bits

  - Stop Bit = 1 Stop Bit

  - Parity = No Parity

  - Hardware flow control disabled (RTS and CTS signals)

  - Receive and transmit enabled

  */

 

    USART_DeInit(USART1);

    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_HardwareFlowControl = USART_HardwareFlowControl_None;

    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_Init(USART1, &USART_InitStructure);

   

    /* Enable the USART1 */

    USART_Cmd(USART1, ENABLE);

   

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

   

    /* Configure one bit for preemption priority */

    //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

   

    /* Enable the USART1 Interrupt */

    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

  

   

   

    /* Enable the USART1 */

    USART_Cmd(USART1, ENABLE);  

}

Now I tested USART1 polling code as below which implement just same thing but using polling method instead of using interrupt method. Then it works!

void usart1_test_polling(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    USART_InitTypeDef USART_InitStructure;

   

    char receive_data;

    /* AHB Clock enable for USART(GPIOA9, A10) */

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

   

    /* USART1 clock enable */

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);   

   

   

    /* USART1 Pins configuration **************************************************/

    GPIO_DeInit(GPIOA);

   

    /* Connect pin to Periph */

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7);   

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7);

   

    /* Configure pins as AF pushpull */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;

    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_NOPULL;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* USARTx configured as follow:

  - BaudRate = 115200 baud 

  - Word Length = 8 Bits

  - Stop Bit = 1 Stop Bit

  - Parity = No Parity

  - Hardware flow control disabled (RTS and CTS signals)

  - Receive and transmit enabled

  */

 

    USART_DeInit(USART1);

    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_HardwareFlowControl = USART_HardwareFlowControl_None;

    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_Init(USART1, &USART_InitStructure);

    /* Enable the USART1 */

    USART_Cmd(USART1, ENABLE);  

   

    while(1)

    {

   

        while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET );

        receive_data = USART_ReceiveData(USART1) & 0xFF;

       

        USART_SendData(USART1, receive_data);

        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET );

       

        if( receive_data == 'x' )

            break;

    }       

}

So I concluded that I had a problem with interrupt, but I couldn't find the reason. Please help me. Thank you

#interrupt #stm32f373
3 REPLIES 3
thmjpr
Associate II
Posted on October 27, 2016 at 07:16

Why are you enabling the usart twice? that doesn't seem right.

''If I send any character to STM, then it would receive it and send back to my computer. But I couldn't receive anything.''

Can you clarify? So with the interrupt code its not receiving anything. If you put a breakpoint on top if of IRQhandler it never goes there?

ysmgreen
Associate
Posted on October 27, 2016 at 08:06

Dear jpr.thm,

I removed one USART enabling code, but it still did't work.

 ''If I send any character to STM, then it would receive it and send back to my computer. But I couldn't receive anything.''

-> STM is connected with my computer by USB driver, and when I send any character by PC to STM through USART communication, then STM received it, and sent it back to my computer. So if this code works correctly, I can receive a character which I just sent to STM by universalcomm. I could verify it by USART polling method code, but when I used USART interrupt method code, it failed.

Yes, if I put a breakpoint on top if of IRQhandler it never goes there.

Walid FTITI_O
Senior II
Posted on October 27, 2016 at 14:04

Hiyang.seungman,

Try to enable the TX/RX transfer interrupt just after enabling the USART and manage then the Tx and RX transfer sequensetly using interrupt flags . The ''USART_HyperTerminalInterrupt'' example in STM32F3xxstandard library is a helpful example for you. I will give you a brief helpful description that help you to implement correctly you USART transfer code. Like the following: in main.c file: you main function would be like following model:

...
USART_init();
/* Enable USART */
USART_Cmd(USART1, ENABLE);
/* Enable the USART1 Transmoit interrupt: this interrupt is generated when the 
EVAL_COM1 transmit data register is empty */ 
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
/* Wait until USART1 send the TxBuffer */
while(TxCounter < NbrOfDataToTransfer)
{}
/* The software must wait until TC=1. The TC flag remains cleared during all data
transfers and it is set by hardware at the last frame’s end of transmission*/
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
{}
/* Enable the USART1 Receive interrupt: this interrupt is generated when the 
EVAL_COM1 receive data register is not empty */
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
/* Wait until USART1 receive the RxBuffer */
while(RxCounter < NbrOfDataToRead)
{}

with the golobal variable:

extern __IO uint32_t TxCounter; 
extern __IO uint32_t RxCounter;

Then , in STM32F3xx_it.c file you , your USART1_IRQHandler() will be like following:

void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
/* Read one byte from the receive data register */
RxBuffer[RxCounter++] = (USART_ReceiveData(USART1) & 0x7F);
if(RxCounter == NbrOfDataToRead)
{
/* Disable the USART1 Receive interrupt */
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
}
}
if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
{ 
/* Write one byte to the transmit data register */
USART_SendData(USART1, TxBuffer[TxCounter++]);
if(TxCounter == NbrOfDataToTransfer)
{
/* Disable the USART1Transmit interrupt */
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
}
}
}

with defining the following variable in the STM32F3xx_it.c file :

#define TXBUFFERSIZE (countof(TxBuffer) - 1)
#define RXBUFFERSIZE 0x20
/* Private macro -------------------------------------------------------------*/
#define countof(a) (sizeof(a) / sizeof(*(a)))
/* Private variables ---------------------------------------------------------*/
uint8_t TxBuffer[] = ''

USART Hyperterminal Interrupts Example: USART-Hyperterminal\
communication using Interrupt

'';
uint8_t RxBuffer[RXBUFFERSIZE];
uint32_t NbrOfDataToTransfer = TXBUFFERSIZE;
uint32_t NbrOfDataToRead = RXBUFFERSIZE;
__IO uint32_t TxCounter = 0; 
__IO uint32_t RxCounter = 0;

Hope it is clear for you. -Hannibal-