реклама на сайте
подробности

 
 
> UART в SAM7X: Tx+PDC
athlon64
сообщение Mar 29 2011, 12:47
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 156
Регистрация: 10-03-10
Из: Уфа
Пользователь №: 55 882



Здравствуйте
Для отправки в порт фрейма необходимо использовать DMA, используя стандартный пример от атмела удалось добиться вывода с использованием DMA. Только вот неясно как поймать момент окончания отправки чтобы уничтожить временный буфер отправки.
В даташите сказано что для этой цели можно использовать биты TXBUFE и ENDTX в статусном регистре UART, по выставлению которых можно генерировать прерывание. Добавил в обработчик проверку этих битов и в инициализацию портов добавил включение прерывания по US_ENDTX.
Так вот, если прерывание по US_ENDTX или US_TXEMPTY включено то процессор зависает при первой же передаче, как будто забыл сбросить какой то бит в обработчике прерывания от UART.

Код инициализации:
Код
  unsigned int iBaud = 9600;
  PIO_Configure(USART1_pins, PIO_LISTSIZE(USART1_pins));
  PMC_EnablePeripheral(AT91C_ID_US1);                           // Enable the peripheral clock in the PMC
  USART_Configure(AT91C_BASE_US1, mode, iBaud, 48000000);       // Устанавливаем режим и скорость порта
  IRQ_ConfigureIT(AT91C_ID_US1, 5, IRQ_UART1_RX);               // IRQ_UART1_RX - обработчик прерывания по приходу байта // или по таймауту
  IRQ_EnableIT(AT91C_ID_US1);                                   // Разрешаем прерывание от UART1
  USART_SetTransmitterEnabled(AT91C_BASE_US1, 1);               // Включаем передатчик
  USART_SetReceiverEnabled(AT91C_BASE_US1, 1);                  // Включаем приёмник

  AT91C_BASE_US1->US_IER = AT91C_US_RXRDY | AT91C_US_TIMEOUT | AT91C_US_ENDTX;  // Так зависает  
//  AT91C_BASE_US1->US_IER = AT91C_US_RXRDY | AT91C_US_TIMEOUT;  // А так - нет
  AT91C_BASE_US1->US_RTOR=cstTimeCOM;                           // Устанавливаем тайм-аут


Обработчик прерывания:
Код
void IRQ_UART1_RX()
{
  unsigned int status = AT91C_BASE_US1->US_CSR & AT91C_BASE_US1->US_IMR;

  if (status & AT91C_US_ENDTX)     // Передача закончена
  {
// Вот это событие хочу поймать
  }
  
  if (status & AT91C_US_OVRE)     // Буфер был переполнен
    SizeCOM1 = 0;

  if (status & AT91C_US_RXRDY)    // если прерывание произошло по приёму 1 байт буфера
    InBufCOM1[SizeCOM1++] = AT91C_BASE_US1->US_RHR; // Заполнение буфера порта COM1
  
  if (status & AT91C_US_TIMEOUT)  // если прерывание произошло по таймауту, фрейм окончен
  {
    AT91C_BASE_US1->US_CR = AT91C_US_STTTO;                            // Сбрасываем тайм-аут
// Обработка пакета
    }
  }
}


Сообщение отредактировал athlon64 - Mar 29 2011, 12:49


--------------------
Руслан
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 07:23
Рейтинг@Mail.ru


Страница сгенерированна за 0.01355 секунд с 7
ELECTRONIX ©2004-2016