Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Передача из DMA в UART
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
maug
Суть проблемы вот в чем.
UART работает на передачу без прерывания, но через DMA. Есть функция передачи данных собственно для простоты:
Код
void PUTCH_DMA(void)
{                    
  unsigned char ggg[5]={0x01,0x02,0x03,0x04,0x05};
  
    *AT91C_US1_TPR = (unsigned int)(&ggg[0]);
// можно просто *AT91C_US1_TPR = (unsigned int)ggg;
    *AT91C_US1_TCR = 5;
}


В порту получаю 0.1.2.3.4
если запустить функцию еще раз то получаю 5.1.2.3.4

Т.е получается первым байтом передается то что лежало в буфере UART до активизации DMA.

Как исправить положение, так чтобы передавались только нужные байты?

Вот инициализация UARTa
Код
void init_usart()
{
*AT91C_PIOA_PDR = (1<<21)|(1<<22);
*AT91C_PIOA_ASR = (1<<21)|(1<<22);                  

     PMC_PCER = (0x1<<AT91C_ID_US1);

US1_CR=   AT91C_US_RSTRX |
                  AT91C_US_RSTTX |
                  AT91C_US_RXDIS |
                  AT91C_US_TXDIS;  

  US1_MR = AT91C_US_USMODE_NORMAL |
                  AT91C_US_CLKS_CLOCK    |
                  AT91C_US_CHRL_8_BITS   |
                  AT91C_US_PAR_NONE      |
                  AT91C_US_NBSTOP_1_BIT;

     US1_BRGR = (MCK/16/BAUD_RATE);                    // Baud Rate Divisor


US1_CR = AT91C_US_RXEN  |          // Receiver Enable    
                 AT91C_US_TXEN;           // Transmitter Enable

              
*AT91C_US1_PTCR = AT91C_PDC_RXTEN |
                       AT91C_PDC_TXTEN;

   *AT91C_US1_RTOR = 0x04;  
              
AIC_SMR7 = AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED | USART_INTERRUPT_LEVEL;
AIC_SVR7 = (unsigned int) US1_CIrqHandler;
    
US1_IER = AT91C_US_ENDRX |
      AT91C_US_OVRE | AT91C_US_PARE | AT91C_US_FRAME |  
      AT91C_US_TIMEOUT;

US1_CR = AT91C_US_STTTO;

*AT91C_US1_RPR = (unsigned int)Buf_RX;
*AT91C_US1_RCR = len_Buf_RX;

     AIC_ICCR = (0x1 << AT91C_ID_US1);
     AIC_IECR = (0x1 << AT91C_ID_US1);
     AIC_ISCR = (0x1 << AT91C_ID_US1);
}
maug
Вроде разобрался.
Дело в том что в DMA есть два регистра как для приема так и для передачи.
Для правильной работы записал во второй канал нулевую длину.

*AT91C_US1_TNCR = 0; // регистр 2-го счетчика передачи
maug
Все оказалось гораздо проще (ну или наоборот сложнее).
После некоторой работы, ситуация повторилась и занесение во второй счетчик нуля уже не работало. Чуть с ума не сошел. Потом просто перезагрузил комп. И все стало работать как часы. Без всякой установки нуля во второй счетчик!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.