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

LPC21xx. Криво принимаются данные по UART.

LPC2129

Прерывания возникают нормально.

Если отправлять по одному байту то все хорошо(каждую мс.).

Но если отправитьт несколько подряд(без задержек) то U0RBR хранится только последний байт.

Такое ощущение что буфер не заполняется.

 

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

 

 

void UART0Init(U16 baud)
{
 U16 divisor = getperipheralClockFreq() / (16 * baud);

 U0FCR_bit.FCRFE = 1;
 U0FCR_bit.RFR = 1;  
 U0FCR_bit.TFR = 1;  
 U0FCR_bit.RTLS = 2; 

 U0LCR_bit.WLS=3;  //8 bits 
 U0LCR_bit.SBS=1;  //1 stop bit

 U0LCR_bit.DLAB=1; //Enable DLAB                       
 U0DLL = LSB(divisor);
 U0DLM = MSB(divisor);
 U0LCR_bit.DLAB=0; //Disable DLAB                      


 PINSEL0 = PINSEL0 & ~0xF | 0x5;

 // Set Interrupt Enable Register
 U0IER_bit.RDAIE =1;  //(Receive Data Interrupt Enable)
}

//////////////////////////////////////////////////////

static void ISR_UART0Interrupt(void)
{
 unsigned char ISR_type,temp;
 while(((ISR_type = U0IIR) & 0x01) == 0)
   {
       switch (ISR_type & 0x0e) 
       {
           case 0x02:        //THRE Interrupt.
                break;
           //--------------------------------------
           case 0x04:        //Receive Data Available (RDA)
               while( (U0LSR&0x01) == 1 )    //Вот тут всегда хранится один, последний байт из посылки
                   UART_PutChar(0, U0RBR+1);    //а по идее должны бытьт данные из буфера
               A_LED1_OFF;
               A_LED2_ON;
               break;
           //--------------------------------------
           case 0x06:        //Receive Line Status (RLS)
               temp = U0LSR;
               A_LED2_ON;
               A_LED1_ON;
               break;
           //--------------------------------------
           case 0x0c:        // по таймауту //Character Time-out Indicator (CTI)
               A_LED2_OFF;
               A_LED1_ON;
               while( (U0LSR&0x01) == 1 ) //тоже самое. всегда один байт
                   UART_PutChar(0, U0RBR-1);
               break;
           //--------------------------------------
           default :
               break;
           //--------------------------------------
       }
   }
}

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


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

к регистру FCR нельзя доступаться через битовые поля, поскольку этот регистр доступен только для записи, а читается с этого адреса IIR.

Доступ к битовым полям компилятор выполняет как чтение-модификацию-запись, а поскольку чтение происходит из IIR, то и в FCR значение записывается невалидное.

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


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

Не когда не задумывался на эту тему, хотя сто раз видел что на одних адресах висят.

 

Нашел ссылку с примерами может кому поможет

http://www.siwawi.arubi.uni-kl.de/avr_proj...cts/glcd_dcf77/

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


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

Вот пример инициализации и готового обработчика. Все проверено и отлажено.

 

DWORD UART_Calc_div(DWORD baud_rate)
/*******************************************************************
* Название
*   UART_Calc_div
* Описание
*   вычисление делителя UART
* Вызов
*   baud_rate - бит/с
* Возвращаемые значения
*   делитель для UART
* Статус тестирования
*   функция работоспособна
********************************************************************/
{
   return((Fpclk/baud_rate)/16);// Fpclk - опарная частота - частота процессора
}

void UART_init(void)
/*******************************************************************
* Название
*   UART_init
* Описание
*   инициализация UART
* Вызов
*   без параметров
* Возвращаемые значения
*   нет
* Статус тестирования
*   функция работоспособна
********************************************************************/
{
   DWORD val;

   // делитель
   U0LCR=0x80;
   val=UART_Calc_div(230400);
   U0DLM=(val & 0x0000ff00) >> 8;
   U0DLL=val & 0x000000ff;

   // 8-bit, 2-stop, no parity, no break
   U0LCR=0x7;

   // ena FIFO with clearing
   U0FCR=0x7;

   // ena recieve ints
   U0IER=1;

   // подключаем к пинам
   // TXD0
   PINSEL0_bit.P0_0=1;
   // RXD0
   PINSEL0_bit.P0_1=1;

}

void UART_handler(void)
/*******************************************************************
* Название
*   UART_handler
* Описание
*   обработчик прерывания UART'а
* Вызов
*   без параметров
* Возвращаемые значения
*   нет
* Статус тестирования
*   функция работоспособна
********************************************************************/
{
   DWORD tmp_val;
   // читаем состояние прерываний
   while(!((tmp_val=U0IIR) & 1))
   {
       switch(tmp_val & 0xe)
       {
           case 2:
           // прерывание по передаче
               // проверяем есть ли данные на передачу
               // если нет - запрещаем прерывание
               UART_send();
               break;

           case 4:
           // прерывание по приему
           // ADD: переделать потом чтобы ждать хотя бы 4 байт в FIFO и сделать прерывание по таймауту...
               // складываем очередное значение в буфер
               UART_receive();
               break;

           default:
           // хрень какая-то вычитываем регистр на всякий случай
               tmp_val=U0LSR;
               tmp_val=U0RBR;
       }
   }
}

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


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

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

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

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

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

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

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

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

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

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