Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: UART прерывания
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Hexart
Привет всем. Разбираюсь с UART и прерываниями. Разбираю код из примера Keil UART с обработкой прерывания. Никак не могу понять зачем там while. В других примерах нету в обработчике while. Если произошло прерывание по UART1 какое либо. Там в регистре U1IIR - есть три бита (3:1) IntId: Iterrupt identification. Но может быть записан идентификатор только одного прерывания, который выбирается в switch. После считывания значений в case'ax, нулевой бит в U1IIR, в котором записан "0", свидетельствующий о прерывании устанавливается в "1". Если во время обработки прерывания, пришло еще одно прерывание, опять по UART1, то в регистр U1IIR опять запишется значение о новом прерывании еще до выхода из обработчика?

Код
void sio_irq (void) __irq {
  volatile char dummy;
  volatile char IIR;
  struct buf_st *p;

  /*------------------------------------------------
Repeat while there is at least one interrupt source.
  ------------------------------------------------*/
  while (((IIR = U1IIR) & 0x01) == 0) {
     switch (IIR & 0x0E) {
       case 0x06: /* Receive Line Status */
         dummy = U1LSR;  /* Just clear the interrupt source */
         break;

       case 0x04: /* Receive Data Available */
       case 0x0C: /* Character Time-Out */
         p = &rbuf;

         if (((p->in - p->out) & ~(RBUF_SIZE-1)) == 0) {
           p->buf [p->in & (RBUF_SIZE-1)] = U1RBR;
           p->in++;
         }
         break;

       case 0x02: /* THRE Interrupt */
         p = &tbuf;

         if (p->in != p->out) {
           U1THR = p->buf [p->out & (TBUF_SIZE-1)];
           p->out++;
           tx_restart = 0;
         }
         else {
           tx_restart = 1;
         }
         break;

       case 0x00: /* Modem Interrupt */
         dummy = U1MSR;  /* Just clear the interrupt source */
         break;

       default:
         break;
     }
  }

  VICVectAddr = 0; /* Acknowledge Interrupt */
}
Сергей Борщ
QUOTE (Hexart @ Oct 23 2011, 17:11) *
Если во время обработки прерывания, пришло еще одно прерывание, опять по UART1, то в регистр U1IIR опять запишется значение о новом прерывании еще до выхода из обработчика?
А вы думали, UART будет ждать пока ядро выйдет из прервывания, чтобы записать значение в свои регистры? А если вы работаете без прерываний? А если второе событие произошло еще до того, как вы вошли в это прерывание? Там ведь не зря у разных источников разные приоритеты. В этом примере сделано довольно грамотно - зачем тратить время на выход из прерывания чтобы тут же попасть в него снова? Проще сразу проверить, что больше обрабатывать нечего.

То, что в этом примере не используются FIFO - уже другой вопрос.
Hexart
Цитата(Сергей Борщ @ Oct 23 2011, 19:56) *
А вы думали, UART будет ждать пока ядро выйдет из прервывания, чтобы записать значение в свои регистры? А если вы работаете без прерываний? А если второе событие произошло еще до того, как вы вошли в это прерывание? Там ведь не зря у разных источников разные приоритеты. В этом примере сделано довольно грамотно - зачем тратить время на выход из прерывания чтобы тут же попасть в него снова? Проще сразу проверить, что больше обрабатывать нечего.

То, что в этом примере не используются FIFO - уже другой вопрос.

Спасибо! понятно. Получается без while тоже можно, но тогда он потом туда вернется, если у него еще есть прерывания от других источников в этот момент.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.