Перейти к содержанию
    

NXP LPC1114 Проблемы с UART

Столкнулся со следующей проблемой в контроллере 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 ++;
        }
    }
}

 

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

 

Кто-нибудь сталкивался с такой проблемой?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А использование FIFO UART у вас вообще где-либо разрешено? В приведенном коде этого не видно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А использование 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 ++;
    }
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот код заполнения буфера:

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. Записываю следующий байт.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Из данного цикла программа не выходит.

 

Мне нужно организовать побайтовую передачу массива. Алгоритм действий мой таков:

1. Записываю первый байт в буфер.

2. Жду прерывания что буфер освободился (данные скопированы в передающий регистр).

3. Записываю следующий байт.

 

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

 

не выходит из цикла - не беда...вместо моей строчки - вставьте задержку на время отправки 1 байта на вашей скорости.

завтра посмотрю, как я это делаю...делаю с фифо, работает...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

...

Прерывания пока вообще запрещаю. Заполняю буфер и получается наложение байтов.

Использовать FIFO не обязательно, но не нужно в таком случае дезинформировать его упоминанием. Раз вы FIFO не используете, то считайте, что его нет. Есть только регистр-буфер на один байт. Аналогично с прерыванием.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всем спасибо за ответы. Проблема была в не правильных настройках программы COM Port Toolkit. Было установлено 2 стоп бита и контроль четности. А контроллер 1 стоп бит и без контроля четности. Тема закрыта.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...