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

 
 
> Кольцевой буфер не успевает себя сдвигать до прихода нового байта.., Помогите найти решение.
Alt.F4
сообщение Nov 9 2011, 19:43
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 468
Регистрация: 28-03-10
Из: Беларусь
Пользователь №: 56 256



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

P.S. на данной скорости UART работает стороннее устройство и ее изменять нельзя. Частота МК почти максимальная, т.к. питание 3В.
Go to the top of the page
 
+Quote Post
5 страниц V   1 2 3 > »   
Start new topic
Ответов (1 - 14)
ILYAUL
сообщение Nov 9 2011, 19:49
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Проц -то какой? И зачем сдвигать весь буффер?


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
GinRider
сообщение Nov 9 2011, 19:49
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 58
Регистрация: 13-10-06
Из: Финляндия
Пользователь №: 21 273



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

Сообщение отредактировал GinRider - Nov 9 2011, 19:51
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Nov 9 2011, 19:51
Сообщение #4


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



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


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
rx3apf
сообщение Nov 9 2011, 19:52
Сообщение #5


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



Цитата(Alt.F4 @ Nov 9 2011, 23:43) *
Имеется кольцевой буфер UART на 150 байт. По приходу байта вызывается прерывание, где происходит его запись и сдвиг всего буфера. Но вот незадача, скорость UART 115200, а частота МК 9216кГц. В результате я имею запас всего 80 тактов, которых естественно не хватает на сдвиг этого буфера.
Что можно придумать? 05.gif

Естественно, не сдвигать. Два указателя, для принимаемого и извлекаемого байта.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Nov 9 2011, 20:00
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



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


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
silverio
сообщение Nov 9 2011, 21:01
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 48
Регистрация: 14-06-09
Из: Киев
Пользователь №: 50 273



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

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

Сообщение отредактировал silverio - Nov 9 2011, 21:01
Go to the top of the page
 
+Quote Post
Alt.F4
сообщение Nov 10 2011, 07:07
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 468
Регистрация: 28-03-10
Из: Беларусь
Пользователь №: 56 256



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

Буду пытаться обрабатывать в прерывании по шагам всю строку.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 10 2011, 07:30
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Alt.F4 @ Nov 10 2011, 10:07) *
Таким образом кольцевой буфер с "head" и "tail" не подходит, т.к. надо чтобы в буфере было сразу 150байт.
Простите, а какая связь между 150 байт и реализацией буфера через "голову" и "хвост"? И почему двигать все 150 байт относительно границ буфера подходит, а двигать границы буфера относительно этих же 150 байт - нет?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
xemul
сообщение Nov 10 2011, 08:33
Сообщение #10



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(Alt.F4 @ Nov 10 2011, 11:07) *
Дело в том, что мне надо вылавливать из этих 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 придумайте сами
   }
}
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Nov 10 2011, 09:04
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(Alt.F4 @ Nov 9 2011, 23:43) *
Но вот незадача, скорость UART 115200, а частота МК 9216кГц. В результате я имею запас всего 80 тактов


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


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Nov 10 2011, 09:40
Сообщение #12


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



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


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Nov 10 2011, 09:46
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(Alt.F4 @ Nov 10 2011, 11:07) *
Дело в том, что мне надо вылавливать из этих 150байт только три первых символа, остальные данные переменны ....
т.к. надо чтобы в буфере было сразу 150байт.

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


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
Alt.F4
сообщение Nov 10 2011, 14:46
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 468
Регистрация: 28-03-10
Из: Беларусь
Пользователь №: 56 256



Данные в этих 150байтах лежат не в строгом порядке, в результате надо часто искать запятые, точки и другие символы. На флажках это дело решать муторно.
Я переделал по своему, вопрос исчерпан.
Спасибо.
Цитата
Хочется заметить, что на приём байта (а не бита!) у Вас аж 800 тактов.
Этого тоже не достаточно, ведь надо было прочитать, записать + счетчик перепроверить. В итоге: 150*7тактов=1050тактов.

Сообщение отредактировал Alt.F4 - Nov 10 2011, 15:00
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Nov 11 2011, 05:05
Сообщение #15


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



У вас идеология неверная. Уарт заполняет фифо и только.
Фоновая программа выгребает фифо и парсит фреймы. В таком варианте будет достаточным иметь размер фифо байт на 16-64..
А парсер фреймов (собственно протокол) может иметь свой буфер на максимальный размер пакета.
Как-то так обычно делается.
Благодаря чему выполняется парадигма минимизации времени обработки прерываний...
Более того некоторые протоколы регламентируют максимальный размер фифо канала связи. Так например modbus имеет пожелания на размер фифо в 32 байта...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post

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

 


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


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