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

 
 
 
Reply to this topicStart new topic
> TE-LPC2478LCD+PowerPack, Немогу разобраться с UART
Тоша
сообщение May 30 2011, 13:38
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 13-08-10
Пользователь №: 58 896



Помогите начинающему.
Работаю в IAR 5.41. Взял за основу пример из EXAMPLE PROJECTS,PowerPac Touch Screen demo. Немного помогли переделать под эту плату.
Суть проблемы в том что UART через прерывания работает жутко медленно, как можно это всё оптимизировать. И есть ли там DMA. Потому что при выводе принятых данных на LCD, у него снижается отклик либо вообще не реагирует тачскрин.

Инициализация UART1
Код
void UART1_Initialize(Int32U baudrate)
{
  Int32U Fdiv;
  
  PINSEL0_bit.P0_15 = 0x1;//Ноги
  PINSEL1_bit.P0_16 = 0x1;//Ноги  
  PINMODE0_bit.P0_15 = 0x2;//Отключаем подтяжки
  PINMODE1_bit.P0_16 = 0x2;//Отключаем подтяжки

  
// PINMODE1_bit.P0_17 = 0x2;//Отключаем подтяжки  
  
  PCONP_bit.PCUART1 = 1;      //PCONP
  PCLKSEL0_bit.PCLK_UART1 = 0;//Clock
  
  U1LCR = 0x83;//8 bits, no Parity, 1 Stop bit  
  
  //Fdiv = ((SYS_FREQ/4)/16*256)/baudrate;//делитель                          
  //U3DLL = //Fdiv;//Пишем в регистр
  //U3DLM = 0;//Пишем в регистр    
  
  Fdiv = ( SYS_FREQ / 64 ) / baudrate;    /*baud rate */
  U1DLM = Fdiv / 256;    //    U1DLM =                     
  U1DLL = Fdiv % 256;   //

  U1FCR = 0x07;        /* Enable and reset TX and RX FIFO. */    
  U1LCR = 0x03;        /* DLAB = 0 */
    
/*  // Настроим прерывание
  VIC_SetVectoredIRQ( (void (*)()) UART1Handler, 0xFF, //priority
                        VIC_UART1);*/
  U1IER_bit.RDAIE = 1; /* Enable UART1 interrupt */
// VICINTENABLE_bit.UART1 = 1;
//__REG8  RTSEN : 1;
//__REG8  CTSEN : 1;
  U1MCR_bit.RTSEN=0;
  U1MCR_bit.CTSEN=0;  

  
  OS_ARM_InstallISRHandler(VIC_UART1, (void(*)()) UART1_Handler);
  OS_ARM_EnableISR(VIC_UART1);
}


Обработчик прерывания
Код
void UART1_Handler()
{
  if(U1IIR_bit.IID == 2)// char received
  {
   RxBuf=U1RBR;//Читам значение из регистра
   .... Делаем что либо с принятыми данными.
   }
}


Если есть примеры нормальной работы с UART дайте пожалуйста или помогите советом.
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение May 31 2011, 04:34
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



Проц то вроде нехилый. DMA и FIFO на UART там должен быть. Даже если с DMA не разберетесь, то в прерывании лучше ничего не делать с данными, а писать их в буфер и ставить семафор готовности. Потом в задаче оси снимать семафор и менять местами буферы для UART. Будет работать шустро и не нагружать ось.
Go to the top of the page
 
+Quote Post
Тоша
сообщение May 31 2011, 06:01
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 13-08-10
Пользователь №: 58 896



Цитата(andrewlekar @ May 31 2011, 08:34) *
Проц то вроде нехилый. DMA и FIFO на UART там должен быть. Даже если с DMA не разберетесь, то в прерывании лучше ничего не делать с данными, а писать их в буфер и ставить семафор готовности. Потом в задаче оси снимать семафор и менять местами буферы для UART. Будет работать шустро и не нагружать ось.


Спасибо за совет, сейчас попробую сделать.
Как сделаю напишу.
Go to the top of the page
 
+Quote Post
Тоша
сообщение Jun 1 2011, 12:15
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 13-08-10
Пользователь №: 58 896



Во общем сделал так.
Обработчик прерывания
Код
void UART1_Handler()
{
  if(U1IIR_bit.IID == 2)// char received
  {
    uartRxCout++;
    
    if(uartRxCout==BUFSIZE)//
    {
      uartRxCout=0;
      Status=1;
      if(Simofor==0)
      {  
       Simofor=1;
       RX_Buf = &uartRxBufTwo[0];//Переключаем буфер
      }  
     else
      {
       Simofor=0;
       RX_Buf = &uartRxBufOne[0];//Переключаем буфер
      }
    }
    *RX_Buf=U1RBR;//Читаем значение
    RX_Buf++;//Увеличиваем счётчик
  }    
}


Задача в main для обработки
Код
OS_CREATETASK(&TCBReadPort, "Read Port", ReadPortTask,  100, StackReadPort);

static void ReadPortTask(void)
{
while(1)
{
  OS_EnterRegion();
  if(Status)//Буфер готов
  {
      Status=false;
      unsigned char RxBuf=0;
      for(int i=0;i<BUFSIZE;i++)
      {
       if(Simofor) RxBuf=uartRxBufTwo[i]; else RxBuf=uartRxBufOne[i];
       /*****Обработка полученных данных***/
       .....
      }
  }
  OS_LeaveRegion();
  OS_Delay (300);
}
}



Вроде работает, но иногда сбоит по данным.Если есть вариант полутше(а он точно есть biggrin.gif ) буду рад посмотреть.
И с сифонофорами не понял как их использовать взял булевскую переменную.


Сообщение отредактировал Тоша - Jun 1 2011, 12:18
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Jun 2 2011, 05:17
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



Код просто адский. Если у вас и прежний код был в таком стиле, то неудивительно, что всё тормозило. Если не умеете использовать ось, то лучше и не беритесь.
По существу: обработку данных убрать из критической секции, разобраться с семафорами, убрать постоянное переключение буферов - сделать только при необходимости.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 6th July 2025 - 05:53
Рейтинг@Mail.ru


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