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

 
 
> Проблема с UART LPC2214
vesago
сообщение Sep 2 2008, 09:26
Сообщение #1


Тутэйшы
****

Группа: Свой
Сообщений: 708
Регистрация: 30-11-04
Пользователь №: 1 263



К LPC2214 подключена ADM485 у которой приемник постоянно включен. Т.е. при передаче я отключаю прерывание приемника, включаю разрешение пердачи ADM485 и передаю данные. Далее контролирую опустошение передатчика UART и сдвигового регистра и при фиксации сего, чищу фифо и активирую прерывание приемника. Проблема в том, что сразу после передчи и разрешения прерывания приемника, происходит прерывание и принимается переданный байт, не смотря на то, что я почистил фифо. Получается, фифо не всегда чистится или при каких-то условиях прерывание остается взведенным. Если под отладкой выполнять по шагам, такого не происходит. Помогите разобраться с данной ситуацией. Параметры уарта - скорость 38400, глубина фифо - 1 байт, остальное стандартно.

Вот такой у меня иср уарта:
Код
//********************************************************************************
**********
//Обработчик прерывания UART0
//******************************************************************** **********************
void UART0_Handler(void) __irq
{
    u8_t data;
    u8_t tmphead;
    u8_t tmptail;

    switch((data = U0IIR) & INTERRUPT_SOURCE_MASK)
    {
        //Прием
    case SOURCE_RX:
        data = U0RBR;
        if((uart0.flags & (1<<UART0_FLAG_TX_IN_PROGRESS)) == 0)
        {
            tmphead = (uart0.rx_head + 1) & UART0_RX_BUFFER_MASK;
            uart0.rx_head = tmphead;
            if(tmphead == uart0.rx_tail)
            {
                //ERROR! Receive buffer overflow
                uart0.flags |= (1<<UART0_FLAG_ERR);
            }
            uart0.rx_buf[tmphead] = data;
        }

        if(((data == 0x03) || (data == 0x06) || (data == 0x15)) && (avr.counter == 0))
        {
            data = 0x03;//Это для отлавливания ошибочной ситуации
        }
        break;

        //Прередача
    case SOURCE_THRE:
        tmptail = uart0.tx_tail;
        if(uart0.tx_head != tmptail)
        {
            tmptail = (uart0.tx_tail + 1) &    UART0_TX_BUFFER_MASK;
            uart0.tx_tail = tmptail;

            U0THR = uart0.tx_buf[tmptail];
        }
            else
            {
                uart0.flags &= ~(1<<UART0_FLAG_TX_IN_PROGRESS);
                uart0.flags |= (1<<UART0_FLAG_TX_COMPLETE);
            }
            break;

            //Таймаут приема
    case SOURCE_RX_TIMEOUT:
        data = U0LSR;
        data = U0RBR;
        break;

        //Ошибка
    case SOURCE_ERROR:
        data = U0LSR;
        data = U0RBR;
        break;

        //Хрень какая-то
    default:
        data = U0LSR;
        data = U0RBR;
    }

    VICVectAddr = 0;
}


Функции разрешения/запрещения передачи:
Код
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Запрет приема
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void UART0_DisableReciveIRQ(void)
{
    U0IER &= ~(1<<U0IER_RBR_Interrupt_Enable_BIT);
}

//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Разрешение приема
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void UART0_EnableReciveIRQ(void)
{
    u8_t temp;
    
    temp = U0LSR;

    U0FCR = (1<<U0FCR_FIFO_Enable_BIT) | (1<<U0FCR_Tx_FIFO_Reset_BIT) | (1<<U0FCR_Rx_FIFO_Reset_BIT);

    U0IER |= (1<<U0IER_RBR_Interrupt_Enable_BIT);
}

//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Старт передачи
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void UART0_Transmit_On(void)
{
    UART0_DisableReciveIRQ();
    IO0SET |= (1<<GL_BUS_DIR);        //Включим передатчик RS485
}

//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Стоп передачи
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void UART0_Transmit_Off(void)
{
    IO0CLR |= (1<<GL_BUS_DIR);        //Отключим передатчик RS485
    UART0_EnableReciveIRQ();        //Разрешим прием
}


Проверка опустошения сдвигового регистра:
Код
u8_t UART0_Check_Shift_Reg_Emty(void)
{
    if((uart0.flags & (1<<UART0_FLAG_TX_COMPLETE)) != 0)
    {
        if((U0LSR & (1<<U0LSR_TEMT_BIT) != 0) && (U0LSR & (1<<U0LSR_THRE_BIT) != 0))
        {
            uart0.flags &= ~(1<<UART0_FLAG_TX_COMPLETE);
            return 1;
        }
    }
    return 0;
}


Применеие в майне:
Код
    system.state = SYSTEM_STATE_SCPU_BOOT;

   while(1)
   {
        UART0_Transmit_On();
        UART0_Transmit(0x15);

        system.start_timer = TIME;
        do
        {
            if(UART0_Check_Shift_Reg_Emty() != 0)
            {
                UART0_Buf_Clr();
                UART0_Transmit_Off();
            }
        }while(system.start_timer != 0);

    }
Go to the top of the page
 
+Quote Post



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

 


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


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