2

I'm implementing a simple UART receive-transmit protocol on STM32F103, the library/boilerplate code I'm using here is LL, not HAL (as HAL includes insane amounts of overhead)

My problem is that after successfully entering the interrupt handler "USART1_IRQHandler" it keeps cycling on forever. My code is here:

    void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
    int ii = 0;
    for(ii=0; ii<4;  ii++){
        LL_mDelay(40);
        LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_5);
        LL_mDelay(40);
        LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_5);

    }
    uint8_t cc = LL_USART_ReceiveData8(USART1);
    LL_USART_TransmitData8(USART1, cc);
    LL_mDelay(130);

    //LL_USART_ClearFlag_RXNE(USART1);
    //NVIC_ClearPendingIRQ( USART1_IRQn );

  /* USER CODE END USART1_IRQn 0 */
  /* USER CODE BEGIN USART1_IRQn 1 */
  /* USER CODE END USART1_IRQn 1 */
}

and in main.c I have:

LL_USART_EnableIT_RXNE(USART1);
  while (1)
  {

        LL_mDelay(300);
        LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_5);
        LL_mDelay(300);
        LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_5);

        //LL_USART_EnableIT_TC(USART1);

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }

The GPIO_Toggle commands are just there to blink an led so I know what's going on. Here's waht happens: When I power the MC up, it enters the main loop and blinks slowly. When I send something (~10 bytes) through UART, the led starts blinking fast, indicating that it has entered the interrupt handler. PProblem is that it never stops and keeps spinning around in the interrupt handler.

I've tried using the now commented functions

LL_USART_ClearFlag_RXNE(USART1);
NVIC_ClearPendingIRQ( USART1_IRQn );

either alone or in combination but they have absolutely no effect on anything. What am I doing wrong? How can I exit the handler?

15
  • 6
    There is too much going on inside your interrupt handler. These should be as short as possible. And surely no delays. Commented Sep 13, 2018 at 18:28
  • 2
    Are you sure it's stuck in your interrupt handler and not repeatedly called again because you're not clearing a bit in the UART. Commented Sep 13, 2018 at 18:32
  • It is indeed being called repeatedly again and again. This can be seen in the led blink. Commented Sep 13, 2018 at 18:34
  • A delay LL_mDelay(130); in an interrupt handler? Hmm, questionable approach. Delays add up to 450. If that is 450 ms, that would only keep up with a very slow baud. Commented Sep 13, 2018 at 18:36
  • user2666497, If you remove all LL_mDelay(), does the code still "never stops and keeps spinning around in the interrupt handler"? Commented Sep 13, 2018 at 18:41

2 Answers 2

4

Actually everything in your USART interrupt handler is wrong.

  1. You do not check what has caused the interrupt. If it is RXNE flag you should just load the value from the DR register. You do not need to clear any flags. If it is TXE flag you can store the data to the DR register. You cant clear this flag any other way. If you do not have any data to send you need to disable the TXE interrupt. Otherwise it will trigger continuously.

You can't just read and write the data register when you want to. You need to know if you are allowed to

You should also control the error statuses.

  1. You must not use any delays in the interrupt routines. Keep it as fast as possible.
  2. Do not touch NVIC exept for enabling and disabling the interrupts, as for now you do not know what it is for.
Sign up to request clarification or add additional context in comments.

Comments

1

The system time utilised for controlling delays is updated by a periodic sysTick interrupt. If the RXNE interrupt has a higher priority than the sysTick interrupt it won't be handled while you're inside your RXNE IRQ handler, so the time will never increment and your delay end time will never be reached. Depending on how your delay is implemented, it may just put the CPU in a spinlock that can never exit.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.