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

 
 
 
Reply to this topicStart new topic
> 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
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
corel_
сообщение Aug 12 2007, 19:13
Сообщение #3





Группа: Новичок
Сообщений: 6
Регистрация: 6-08-07
Пользователь №: 29 596



Тоже столкнулся с этим...пока решения не нашел....
Хто-нить, плиз подскажите как решить проблему с передачей и приемом Uart2,3
Go to the top of the page
 
+Quote Post
Andrei_S
сообщение Aug 17 2007, 12:17
Сообщение #4


Участник
*

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



Итак, наконец сегодня получил внятный ответ от NXP. К сожалению, у них НЕ НАШЛОСЬ!!! LPC2366. Тестовые испытания у них были проведены на 2368. Тестируемый код - как на форуме. Ответ - с UARTами все в порядке...
Рекомендуют: после инициализации UARTа в дебаггере ручками загнать какой-нибудь байт в U2THR(или U3THR) и посмотреть, передастся ли байт...

Завтра я ту-ту на юга, менять 2366 на 2368 и проверять - времени нет, а приеду только 6-го сент.
corel_, на тебя надежда, поюзай этот кристалл(если он у тебя есть), пожалуйста...

Большое спасибо всем за очень внятные ответы.
Пока, приятного мне отдыха...
Go to the top of the page
 
+Quote Post
corel_
сообщение Aug 20 2007, 07:13
Сообщение #5





Группа: Новичок
Сообщений: 6
Регистрация: 6-08-07
Пользователь №: 29 596



за пятницу были настроены UARTы 2,3 на lpc2368 - все заработало.
правда пришлось двигать второй уарт на другие ноги.
Тестовый проэкт выложу чуть позже.
Go to the top of the page
 
+Quote Post
bigarmer
сообщение Dec 16 2008, 09:37
Сообщение #6


Участник
*

Группа: Новичок
Сообщений: 52
Регистрация: 5-12-08
Пользователь №: 42 221



You need to turn on the power bit for UART2 and UART3 in PCONP register, since these bits are clear on reset by default.
Go to the top of the page
 
+Quote Post

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

 


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


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