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

 
 
> LPC2366 Глюк’с UART2,3 ?
Andrei_S
сообщение Aug 6 2007, 08:54
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535



07.gif Господа, интересная фишка с UARTами 2 и 3 получается. В проекте используются UART0,2,3 (2400-19200, n, 8, 1, FIFO-1байт).
Задача: от ПК приходит запрос по Modbus. МК обрабатывает запрос и пересылает в ответ массив данных.
Реализация: после первого принятого по UART байта начинается отсчет времени тишины в линии (задействован, например, Timer2). Как только время тишины > времени передачи 4.5 символов, прерывания UARTа блокируются, выполняется обработка запроса и посылается ответ. После отправки последнего байта - прерывания UARTа возобновляются.
Так вот, при использовании UART0 – все пучком, нареканий никаких нет, при работе с UART2,UART3 флаги прерываний IER_THRE, IER_RLS, IER_RBR не работают, хотя в отладчике (Peripherals->UART2,3) флаги снимаются/устанавливаются. Что получается: запрещаю все прерывания UART2,3, отправляю n байт, восстанавливаю прерывания, разрешаю прием очередного пакета, и тут начинают сыпаться прерывания по приему байта, причем данные не что иное, а эхо отсылаемых перед этим данных.
Как лечил: после отправки n байт тупо выжидал время, необходимое для их отправки, а затем разрешал THRE, RLS, RBR и прием очередной посылки. Если и были какие то прерывания по приему, то они проигнорированы программно.
Какие у кого есть комменты????
Глюк ли это, или я что-то не так сделал.… Хотя при использовании UART0 – все в порядке.

Более подробно разбираться – времени нет. Попочка уже горит…

p.s. Надо бы еще проверить передачу байт в прерывании какого-нибудь таймера, а не в main. Не будет ли конфликта. А с аппаратной отправкой массива байт по флагу THRE, наверное, полный облом… (то есть отправляем первый байт откуда угодно, а при срабатывании прерывания THRE загоняем очередной байт и так до окончания массива).





Код
//Keil uVision 3.53 (mdk3.11+crk), отладчик ULINK2.
//#######################################################
int main (void)
{

PINSEL0 = 0x00500050;    // UART0 – P0.2,P0.3,   UART2 – P0.10,P0.11
PINSEL1 = 0x15400022;

PINSEL8 = 0x00;        // UART3 – P4.28,P4.29
PINSEL9 = 0x0F000000;    

//#########################################################
//        Timer 0
//#########################################################
T0MR0 = 14999;    // Interval
T0MCR = 3;        // Interrupt and Reset on MR0
T0TCR = 1;        // Enable Timer0
VICIntEnClr = 1 << 4;    // Disable Interrupt
VICVectAddr4 = (unsigned long)Timer0Handler;    // TC0 Interrupt -> Vector 4
VICVectCntl4 = 0x06;                              // TC0 Interrupt -> Priority 6
VICIntEnable = 1 << 4;                            // Enable TC0 Interrupt
//#######################################################
//#######################################################
//        Timer 1
//#######################################################
T1MR0 = 5000;    // Interval
T1MCR = 3;        // Interrupt and Reset on MR1
T1TCR = 1;        // Enable Timer1
VICIntEnClr = 1 << 5;    // Disable Interrupt
VICVectAddr5 = (unsigned long)Timer1Handler;    // TC1 Interrupt -> Vector 5
VICVectCntl5 = 0x03;                              // TC1 Interrupt -> Priority 3
VICIntEnable = 1 << 5;                            // Enable TC1 Interrupt
//#######################################################

PCONP  |= (1 << 22);  // Включаем питание Timer2
//#######################################################
//        Timer 2
//#######################################################
T2MR0 = 5000;    // Interval
T2MCR = 3;        // Interrupt and Reset on MR2
T2TCR = 1;        // Enable Timer2
VICIntEnClr = 1 << 26;    // Disable Interrupt
VICVectAddr26 = (unsigned long)Timer2Handler;   // TC2 Interrupt -> Vector 26
VICVectCntl26 = 0x04;                              // TC2 Interrupt -> Priority 4
VICIntEnable = 1 << 26;                            // Enable TC1 Interrupt
//#######################################################


  


PCONP  |= (1 << 24);  // Включаем питание UART2 и UART3
PCONP  |= (1 << 25);

//########################################################    
//        UART 0
//########################################################    
U0LCR = 0x83;        // 8 bits, no Parity, 1 Stop bit
U0DLL = 0xC2;        // 4800
U0LCR = 0x03;        // DLAB = 0
U0FCR = 0x07;        // Enable and reset TX and RX FIFO.
VICVectAddr6 = (unsigned long)UART0Handler;        // UART0 Interrupt -> Vector 6
VICVectCntl6 = 0x05;                              // UART0 Interrupt -> Priority 5
VICIntEnable = 1 << 6;                            // Enable UART0 Interrupt
U0IER = IER_RBR | IER_THRE | IER_RLS;    // Enable UART0 interrupt


//########################################################    
//        UART 2
//########################################################    
U2LCR = 0x83;        // 8 bits, no Parity, 1 Stop bit
U2DLL = 0xC2;        // 4800
U2LCR = 0x03;        // DLAB = 0
U2FCR = 0x07;        // Enable and reset TX and RX FIFO.
VICVectAddr28 = (unsigned long)UART2Handler;    // UART2 Interrupt -> Vector 28
VICVectCntl28 = 0x02;                              // UART2 Interrupt -> Priority 2
VICIntEnable = 1 << 28;                            // Enable UART2 Interrupt
U2IER = IER_RBR | IER_THRE | IER_RLS;    // Enable UART2 interrupt


//########################################################    
//        UART 3
//########################################################    
U3LCR = 0x83;        // 8 bits, no Parity, 1 Stop bit
U3DLL = 0xC2;        // 4800
U3LCR = 0x03;        // DLAB = 0
U3FCR = 0x07;        // Enable and reset TX and RX FIFO.
VICVectAddr29 = (unsigned long)UART3Handler;    // UART3 Interrupt -> Vector 29
VICVectCntl29 = 0x01;                              // UART3 Interrupt -> Priority 1
VICIntEnable = 1 << 29;                            // Enable UART3 Interrupt
U3IER = IER_RBR | IER_THRE | IER_RLS;    // Enable UART3 interrupt





// Таймер оттикал положенное количество времени, и дал добро на обработку принятого пакета и передачи ответа
// Пришла пора отправлять ответ – из main()
    U2IER = 0;     // Запрещаю прерывания
    Bit_Priem = 1;    // Запрещаю прием посылок
    // Здесь типа обработали пакет и подготовили ответ
    // Отправляю
    for (fff=0; fff<40; fff++)// Например, 40 байт
    {
        while ( !(U2LSR & 0x20) );// Проверяем 5-й бит - Transmitter Holding Register Empty
        U2THR = 0x40+fff; // Что-то передаю
    }
    for (fff=0; fff<Sch_Receive; fff++){UART2Buffer[fff]=0xFF;}    // Очищаю буфер (просто так)
    Delay(120000); // Тупая задержка (типа for (i=0; i<120000; i++){}  )

    U2IER = IER_THRE | IER_RLS | IER_RBR;    // Re-enable Int
    Bit_Priem = 0;    // Разрешаю прием посылок




}


//Обработчк прерывания – взят из примера UART0
// Остальные обработчики – копия этого (только другие переменные)
//#########################################################################    
void UART2Handler (void) __irq
{  
BYTE IIRValue, LSRValue;
BYTE Dummy;

    IIRValue = U2IIR;
    
    IIRValue >>= 1;        // skip pending bit in IIR
    IIRValue &= 0x07;    // check bit 1~3, interrupt identification

    if ( IIRValue == IIR_RLS )    // Receive Line Status
    {
        LSRValue = U2LSR;
        // Receive Line Status
        if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
        {
            // There are errors or break interrupt
            // Read LSR will clear the interrupt
            UART2Status = LSRValue;
            Dummy = U2RBR;            // Dummy read on RX to clear interrupt, then bail out
            VICVectAddr = 0;            // Acknowledge Interrupt
            return;
        }
        if ( LSRValue & LSR_RDR )    // Receive Data Ready
        {
            // If no error on RLS, normal ready, save into the data buffer.
            // Note: read RBR will clear the interrupt
            UART2Buffer[UART2Count] = U2RBR;
            UART2Count++;
            if ( UART2Count == BUFSIZE )
            {
                UART2Count = 0;        // buffer overflow
            }    
        }
    }
    else if ( IIRValue == IIR_RDA )    // Получаем данные (Receive Data Available)
    {
    
    if (Bit_Priem == 0)// Разрешено принимать данные
    {
        Flag_Nach = 1;// Есть начало передачи
        
        UART2Buffer[Sch_Receive2] = U2RBR;    // Записываем в буфер принятый код
        Sch_Receive2++;
        if (Sch_Receive2 > BUFSIZE)
        {
            Sch_Receive2 = 0; // Начинаем с нуля
        }
        Pause_After_Symbol = 0;
    }
    else {Dummy = U2RBR;} // Подтверждаем прием байта

    }
    else if ( IIRValue == IIR_CTI )    // Character timeout indicator
    {
        // Character Time-out indicator
        UART2Status |= 0x100;        // Bit 9 as the CTI error
    }
    else if ( IIRValue == IIR_THRE )    // THRE, transmit holding register empty
    {
        // THRE interrupt
        LSRValue = U2LSR;        // Check status in the LSR to see if valid data in U0THR or not
        if ( LSRValue & LSR_THRE ){ UART2TxEmpty = 1; }
        else{UART2TxEmpty = 0; }
    }
    

    VICVectAddr = 0;    // Acknowledge Interrupt

}// End Interrupt
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Andrei_S
сообщение Aug 6 2007, 11:45
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535



Цитата(Andrei_S @ Aug 6 2007, 12:54) *
p.s. Надо бы еще проверить передачу байт в прерывании какого-нибудь таймера, а не в main. Не будет ли конфликта. А с аппаратной отправкой массива байт по флагу THRE, наверное, полный облом… (то есть отправляем первый байт откуда угодно, а при срабатывании прерывания THRE загоняем очередной байт и так до окончания массива).


Вдогонку...
smile3009.gif Хрен он посылает байты в таймере!!! Даже и не знаю что делать.
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 22nd June 2025 - 19:10
Рейтинг@Mail.ru


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