STM32: Невозможно выйти из обработчика прерывания для прерывания UART - PullRequest
0 голосов
/ 13 сентября 2018

Я реализую простой протокол приема-передачи UART на STM32F103, библиотечный / шаблонный код, который я здесь использую, это LL, а не HAL (так как HAL включает в себя безумное количество служебных данных)

Моя проблема в том, что после успешного ввода обработчика прерываний "USART1_IRQHandler" он продолжает работать бесконечно. Мой код здесь:

    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 */
}

и в main.c у меня есть:

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 */

  }

Команды GPIO_Toggle предназначены только для мигания светодиода, поэтому я знаю, что происходит. Вот что происходит: Когда я включаю MC, он входит в основной цикл и медленно мигает. Когда я посылаю что-то (~ 10 байт) через UART, светодиод начинает быстро мигать, указывая, что он вошел в обработчик прерываний. Проблема в том, что она никогда не останавливается и продолжает вращаться в обработчике прерываний.

Я пытался использовать теперь прокомментированные функции

LL_USART_ClearFlag_RXNE(USART1);
NVIC_ClearPendingIRQ( USART1_IRQn );

по отдельности или в комбинации, но они абсолютно ни на что не влияют. Что я делаю неправильно? Как выйти из обработчика?

Ответы [ 2 ]

0 голосов
/ 24 июня 2019

Системное время, используемое для управления задержками, обновляется периодическим прерыванием sysTick.Если прерывание RXNE имеет более высокий приоритет, чем прерывание sysTick, оно не будет обрабатываться, пока вы находитесь в обработчике IRQ RXNE, поэтому время никогда не будет увеличиваться, а время окончания задержки никогда не будет достигнуто.В зависимости от того, как реализована ваша задержка, он может просто поставить процессор в спин-блокировку, которая никогда не выйдет.

0 голосов
/ 14 сентября 2018

На самом деле все в вашем обработчике прерываний USART неверно.

  1. Вы не проверяете, что вызвало прерывание. Если это флаг RXNE, вы должны просто загрузить значение из регистра DR. Вам не нужно снимать какие-либо флаги. Если это флаг TXE, вы можете сохранить данные в регистр DR. Вы не можете очистить этот флаг любым другим способом. Если у вас нет данных для отправки, вам необходимо отключить прерывание TXE. В противном случае он будет срабатывать непрерывно.

Вы не можете просто читать и записывать регистр данных, когда хотите. Вы должны знать, разрешено ли вам

Вы также должны контролировать статусы ошибок.

  1. Вы не должны использовать какие-либо задержки в процедурах прерывания. Держите его как можно быстрее.
  2. Не прикасайтесь к NVIC, за исключением включения и отключения прерываний, так как на данный момент вы не знаете, для чего оно.
...