Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Работа USART при прерывании
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
maug
Попробую кратко объяснить суть проблемы.
US1 настроен на прием пакета по TIMEOUT (по прерыванию)
Код
void init_usart1()
{
    *AT91C_PIOA_PDR = (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);                

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

              
     *AT91C_US1_PTCR = AT91C_PDC_RXTEN;

     *AT91C_US1_RTOR = 0x04;  

                    
      AIC_SMR7 = AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED | USART_INTERRUPT_LEVEL;
      AIC_SVR7 = (unsigned int) US1_CIrqHandler;
    
      US1_IDR = 0xFFFFFFFF;
      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);
        
}


DBGU настроен на передачу пакета (без прерывания)

Код
void init_DBGU()
{
    
*AT91C_PIOA_PDR = (1<<9)|  
           (1<<10);

DBGU_CR=AT91C_US_RSTRX |
                  AT91C_US_RSTTX |
                  AT91C_US_RXDIS |
                  AT91C_US_TXDIS;

DBGU_MR =  AT91C_US_USMODE_NORMAL |  // Normal Mode
                    AT91C_US_CLKS_CLOCK    |  // Clock = MCK
                    AT91C_US_CHRL_8_BITS   |  // 8-bit Data  
                    AT91C_US_PAR_NONE      |  // No Parity  
                    AT91C_US_NBSTOP_1_BIT;    // 1 Stop Bit  

DBGU_BRGR = (MCK/16/BAUD_RATE_DBGU);                    // Baud Rate Divisor

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


При возникновению прерывания по TIMEOUT в теле обработчика вызываю функцию передачи байта по DBGU.
Код
#pragma interrupt_handler US1_CIrqHandler
void US1_CIrqHandler(void)
{
  unsigned int  status;
  status = US1_CSR;

if (( status & AT91C_US_RXRDY)) {
   countTX=US1_RHR;
}

if (( status & AT91C_US_TIMEOUT)) {
  *AT91C_US1_RPR = (unsigned int)Buf_RX;
  *AT91C_US1_RCR = len_Buf_RX;
    US1_CR = AT91C_US_STTTO;
}


if (( status & AT91C_US_ENDRX)) {
    *AT91C_US1_RPR = (unsigned int)Buf_RX;
    *AT91C_US1_RCR = len_Buf_RX;
}

  Write_ByteDBGU(0x77);

   US1_CR = AT91C_US_RSTSTA;
   AIC_EOICR = status;
}


Ну и соответственно функция передачи байта
Код
int Write_ByteDBGU (char byte){
while (!(DBGU_SR & AT91C_US_TXRDY));
return (DBGU_THR = byte);                
}


В результате программа виснет как выяснилось не устанавливается бит TXRDY порта DBGU, т.е. как я понимаю порт просто не передает байт и соответственно не освобождает буфер.
Пробовал вызвать функцию Write_ByteDBGU() из прерывания TIMER0 та же история.
В чем причина понять не могу? Програмирую на ICCARM.
Calculator
Похоже, что не выбрана функция выводов TXD, RXD (регистр PIOA_ASR)
maug
Цитата
Похоже, что не выбрана функция выводов TXD, RXD (регистр PIOA_ASR)


Добавил описание регистра PIOA_ASR, хотя вроде по умолчанию подключается группа А переферии. Одним словом не помогло.
Хочу уточнить, что та же функция Write_ByteDBGU стоит в теле основной программы и прекрасно работает. US1 сам по себе тоже прекрасно работает.
Считывал значение DBGU_SR ->TXRDY=0
Попробовал в тело обработчика прерывания вставить
Код
....
DBGU_CR = AT91C_US_TXEN;           // Transmitter Enable
while (!(DBGU_SR & AT91C_US_TXRDY));
DBGU_THR = 0x75;
....

зависаний нет. Все работает и передается отлично.

Без
DBGU_CR = AT91C_US_TXEN ; // Transmitter Enable
по прежнему не устанавливается DBGU_SR & AT91C_US_TXRDY
Master
Как дела с размером стека?
maug
Спасибо уже разобрался!
Дело было и правда в стеке. ICC по умолчанию поставил число 40. А необходимо было поставить 96 (3*8*4).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.