Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: NXP LPC1114 Проблемы с UART
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Рашпиль
Столкнулся со следующей проблемой в контроллере LPC1114 фирмы NXP.
Работаю с UART. Разрешил прерывание THRE. Данное прерывание должно наступать когда передающий буфер FIFO пуст.
Но мною было обнаружено что данное прерывание наступает немного раньше и из-за этого мне пришлось вставить задержку. Без задержки байты накладывались друг на друга.

Вот код обработчика прерываний UART:
Код
void UART_IRQHandler(void){
    unsigned long valueIIR;
    unsigned char buffer;

    valueIIR = LPC_UART->IIR >> 1;
    valueIIR &= 0x07;

    switch (valueIIR){
        case 1:     // THRE Interrupt
            UART_HandlerTXInterrupt();
            break;
        case 2:     // Receive Data Available (RDA)
            buffer = LPC_UART->RBR;
            //UART_sendByte(0x11);
            break;
        case 6:     // CTI
            buffer = LPC_UART->RBR;
            //UART_sendByte(0x22);
            break;
        default:
            buffer = LPC_UART->RBR;
            break;

    }
    
}


void UART_HandlerTXInterrupt(void){
    unsigned char valueLSR;
    unsigned char delay = 5;

    valueLSR = (unsigned char)LPC_UART->LSR;
    
    if ((Uart.numberTX > 0) && (CHECKBIT(valueLSR, 5))){
        while(delay--);
        LPC_UART->THR = *Uart.ptrTXBuffer;
        Uart.numberTX --;
        if (Uart.numberTX > 0){
            Uart.ptrTXBuffer ++;
        }
    }
}


Это черновик кода. Критиковать не нужно.

Кто-нибудь сталкивался с такой проблемой?
rezident
А использование FIFO UART у вас вообще где-либо разрешено? В приведенном коде этого не видно.
Рашпиль
Цитата(rezident @ Feb 9 2011, 18:52) *
А использование FIFO UART у вас вообще где-либо разрешено? В приведенном коде этого не видно.

Нет. Его использование обязательно?

Вот функция настройки UART:
Код
/**
* Настройка модуля UART контроллера
* @param baudRate      - желаемая скорость обмена;
* @param wordLength    - количество битов данных: 5 - 8;
* @param nStopBits     - количество стоп битов: 1, 2;
* @param parity        - тип паритета:
*                          0 - отключен;
*                          1 - нечетность;
*                          2 - четность;
* @param frequency     - системная частота контроллера;
*/
void UART_Init(unsigned long baudRate, unsigned char wordLength, unsigned char nStopBits, unsigned char parity, unsigned long frequency){
    
    unsigned long Fdiv;
    unsigned long regVal;

    NVIC_DisableIRQ(UART_IRQn);

    // Настройка выводов используемых аппаратным модулем USART
    LPC_IOCON->PIO1_6 &= ~0x07;        // Очищаем биты отвечающие за выбор функции вывода
    LPC_IOCON->PIO1_6 |=  0x01;     // Устанавливаем для вывода функцию RXD - вход приемника UART
    LPC_IOCON->PIO1_7 &= ~0x07;        // Очищаем биты отвечающие за выбор функции вывода
    LPC_IOCON->PIO1_7 |=  0x01;        // Устанавливаем для вывода функцию RXD - вход приемника UART

    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12);   // Включаем тактирование модуля UART
    LPC_SYSCON->UARTCLKDIV = 0x01;          // Устанавливаем делитель частоты в 1

    LPC_UART->LCR = 0x80;               // Разрешаем доступ к Divisor Latches - настройка скорости работы UART


    // Вычисляем значения регистров настройки скорости
    regVal = LPC_SYSCON->UARTCLKDIV;
    Fdiv = ((frequency/regVal)/16)/baudRate;

    // Устанавливаем значения регистров настройки скорсти
    LPC_UART->DLM = Fdiv / 256;
    LPC_UART->DLL = Fdiv % 256;

    UART_setWordLength(wordLength);     // Устанавливаем длину слова
    UART_setNStopBits(nStopBits);       // Устанавливаем количество стоп битов
    UART_setParity(parity);             // Установка паритета

    RESETBIT(LPC_UART->LCR, 7);         // Запрещаем доступ к Divisor Latches
    
    regVal = LPC_UART->LSR;

    // Настройка FIFO

    LPC_UART->FCR = 0;
    
    SETBIT(LPC_UART->FCR,0);            // Разрешаем работу приемного буффера
    SETBIT(LPC_UART->FCR,1);            // Очищаем RX буффер
    SETBIT(LPC_UART->FCR,2);            // Очищаем TX буффер
    SETBIT(LPC_UART->FCR,6);
    SETBIT(LPC_UART->FCR,7);
    
    while ( LPC_UART->LSR & (LSR_THRE|LSR_TEMT) != (LSR_THRE|LSR_TEMT) );
    while ( LPC_UART->LSR & LSR_RDR ){
        regVal = LPC_UART->RBR;    
    }
  
    UART_Init_IRQ();                    // Настройка прерываний
}

Прерывания пока вообще запрещаю. Заполняю буфер и получается наложение байтов.
Вот код заполнения буфера:
Код
void UART_send(unsigned char *buffer, unsigned char number){
    unsigned char count = 0;

    Uart.ptrTXBuffer    = buffer;
    Uart.numberTX       = number;
    
    while ((Uart.numberTX > 0) && (count < 14)){
        LPC_UART->THR = *Uart.ptrTXBuffer;
        Uart.ptrTXBuffer ++;
        Uart.numberTX --;
        count ++;
    }
}
swisst
Цитата(Рашпиль @ Feb 9 2011, 18:05) *
Вот код заполнения буфера:
Код
void UART_send(unsigned char *buffer, unsigned char number){
    unsigned char count = 0;

    Uart.ptrTXBuffer    = buffer;
    Uart.numberTX       = number;
    
    while ((Uart.numberTX > 0) && (count < 14)){
        LPC_UART->THR = *Uart.ptrTXBuffer;
        Uart.ptrTXBuffer ++;
        Uart.numberTX --;
        count ++;
    }
}


после count++ добавьте строку
Код
while (!(LPC_UART->LSR & TEMT));
Рашпиль
Из данного цикла программа не выходит.

Мне нужно организовать побайтовую передачу массива. Алгоритм действий мой таков:
1. Записываю первый байт в буфер.
2. Жду прерывания что буфер освободился (данные скопированы в передающий регистр).
3. Записываю следующий байт.

Повторяю необходимое количество раз.
swisst
Цитата(Рашпиль @ Feb 9 2011, 18:36) *
Из данного цикла программа не выходит.

Мне нужно организовать побайтовую передачу массива. Алгоритм действий мой таков:
1. Записываю первый байт в буфер.
2. Жду прерывания что буфер освободился (данные скопированы в передающий регистр).
3. Записываю следующий байт.

Повторяю необходимое количество раз.


не выходит из цикла - не беда...вместо моей строчки - вставьте задержку на время отправки 1 байта на вашей скорости.
завтра посмотрю, как я это делаю...делаю с фифо, работает...
rezident
Цитата(Рашпиль @ Feb 9 2011, 21:05) *
Нет. Его использование обязательно?
...
Прерывания пока вообще запрещаю. Заполняю буфер и получается наложение байтов.
Использовать FIFO не обязательно, но не нужно в таком случае дезинформировать его упоминанием. Раз вы FIFO не используете, то считайте, что его нет. Есть только регистр-буфер на один байт. Аналогично с прерыванием.
Рашпиль
Всем спасибо за ответы. Проблема была в не правильных настройках программы COM Port Toolkit. Было установлено 2 стоп бита и контроль четности. А контроллер 1 стоп бит и без контроля четности. Тема закрыта.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.