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

Кольцевой буфер не успевает себя сдвигать до прихода нового байта..

Добрый день.

Столкнулся с задачей, которую никак не могу решить.

Имеется кольцевой буфер UART на 150 байт. По приходу байта вызывается прерывание, где происходит его запись и сдвиг всего буфера. Но вот незадача, скорость UART 115200, а частота МК 9216кГц. В результате я имею запас всего 80 тактов, которых естественно не хватает на сдвиг этого буфера.

Что можно придумать? :05:

Спасибо.

 

P.S. на данной скорости UART работает стороннее устройство и ее изменять нельзя. Частота МК почти максимальная, т.к. питание 3В.

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


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

Зачем сдвигать буфер? Не проще ли писать по следующему адресу и отслеживать указатель? Если написать обработчик на ассемблере, должно влезть.

Если, конечно, внешний UART с FIFO нельза поставить.

Изменено пользователем GinRider

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


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

А зачем его сдвигать?

Есть такое понятие - голова (head) и хвост (tail ) буфера.

УАРТ пишет по указателю head. Чтец читает по указателю tail? инкрементируя его соотв. образом, догоняя head...

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


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

Имеется кольцевой буфер UART на 150 байт. По приходу байта вызывается прерывание, где происходит его запись и сдвиг всего буфера. Но вот незадача, скорость UART 115200, а частота МК 9216кГц. В результате я имею запас всего 80 тактов, которых естественно не хватает на сдвиг этого буфера.

Что можно придумать? :05:

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

 

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


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

Много не понятного , сразу все 150 принимаются и по одному возвращаются или принял передал . Если принял передал , зачем тогда такой буфер?

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


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

Здесь доходчиво написано:

 

http://chipenable.ru/index.php/programming...uart-queue.html

Изменено пользователем silverio

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


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

Дело в том, что мне надо вылавливать из этих 150байт только три первых символа, остальные данные переменны, и их пишу в СОЗУ и потом обрабатываю.

Таким образом кольцевой буфер с "head" и "tail" не подходит, т.к. надо чтобы в буфере было сразу 150байт.

 

Буду пытаться обрабатывать в прерывании по шагам всю строку.

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


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

Таким образом кольцевой буфер с "head" и "tail" не подходит, т.к. надо чтобы в буфере было сразу 150байт.
Простите, а какая связь между 150 байт и реализацией буфера через "голову" и "хвост"? И почему двигать все 150 байт относительно границ буфера подходит, а двигать границы буфера относительно этих же 150 байт - нет?

 

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


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

Дело в том, что мне надо вылавливать из этих 150байт только три первых символа, остальные данные переменны, и их пишу в СОЗУ и потом обрабатываю.

Таким образом кольцевой буфер с "head" и "tail" не подходит, т.к. надо чтобы в буфере было сразу 150байт.

Да хоть 100500 - суть не меняется.

Буду пытаться обрабатывать в прерывании по шагам всю строку.

Проще сначала подумать.

Нечто С-образное:

// RxBuf, head и tail можно/нужно описать в одной структуре - см./гуглите про кольцевой буфер
volatile bit ICatchIt;
uint8_t CatchPos; // сюда сохранится индекс найденной в буфере CatchStr

static void interrupt URxD(void)
{
   const uint8_t CatchStr[] = { '0', '1', '2' };
   static uint8_t iCatchStr = 0;

   if(head != tail)
   {
// приняли байт, если есть место
      RxBuf[head] = RCREG;

// сравнили с очередным искомым
      if(!ICatchIt)
      {
         if(RxBuf[head] == CatchStr[iCatchStr]
         {
            if(++iCatchStr == sizeof(CatchStr))
            {
// если угадали все буквы, взвели флаг, который, скорее всего, стоит обрабатывать где-то вне прерывания
               ICatchIt = 1;
               CatchPos = head - (sizeof(CatchStr) - 1);
               if(CatchPos > (sizeof(RxBuf) - 1)) CatchPos += sizeof(RxBuf);
               iCatchStr = 0;
            }
         }
         else iCatchStr = 0;
      }

// сдвинули голову на следующий свободный элемент RxBuf
      if(++head) == sizeof(RxBuf)) head = 0;
   }
   else
   {
      // обработку переполнения RxBuf придумайте сами
   }
}

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


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

Но вот незадача, скорость UART 115200, а частота МК 9216кГц. В результате я имею запас всего 80 тактов

 

Хочется заметить, что на приём байта (а не бита!) у Вас аж 800 тактов.

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


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

Размер кольцевого буфера лучше иметь кратным степени 2...

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


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

Дело в том, что мне надо вылавливать из этих 150байт только три первых символа, остальные данные переменны ....

т.к. надо чтобы в буфере было сразу 150байт.

Вы как-то определитесь и не скупитесь на слова при описании проблемы , излейте всё задание , легче станет

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


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

Данные в этих 150байтах лежат не в строгом порядке, в результате надо часто искать запятые, точки и другие символы. На флажках это дело решать муторно.

Я переделал по своему, вопрос исчерпан.

Спасибо.

Хочется заметить, что на приём байта (а не бита!) у Вас аж 800 тактов.
Этого тоже не достаточно, ведь надо было прочитать, записать + счетчик перепроверить. В итоге: 150*7тактов=1050тактов.
Изменено пользователем Alt.F4

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


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

У вас идеология неверная. Уарт заполняет фифо и только.

Фоновая программа выгребает фифо и парсит фреймы. В таком варианте будет достаточным иметь размер фифо байт на 16-64..

А парсер фреймов (собственно протокол) может иметь свой буфер на максимальный размер пакета.

Как-то так обычно делается.

Благодаря чему выполняется парадигма минимизации времени обработки прерываний...

Более того некоторые протоколы регламентируют максимальный размер фифо канала связи. Так например modbus имеет пожелания на размер фифо в 32 байта...

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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