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

 
 
> Как грамотные люди делают прием пакетов по USART
TamTam
сообщение Jun 5 2006, 01:11
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 293
Регистрация: 14-03-06
Пользователь №: 15 254



Ну написал с горем пополам обработку прирывания по окончанию приема байта, процедурку копирования из буфера в eeprom, но вот вопрос ???

Данные приходят всегда по разному иногда в нужной мне строке символ 0х0d и 0х0а встречаються несколько раз значит обработка пришедших данныш по окончанию строки мне не подходит, думаю так
после окончания приема запускать таймер и если за отведенное время не поступит следующий байт тогда начинать обработку данных а если данные еще идут то складываем их в еепром.

Правильно ли я мыслю или может есть способ по приличней, ведь таймер нужная и без этого весчь.
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 20)
TamTam
сообщение Jun 5 2006, 01:59
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 293
Регистрация: 14-03-06
Пользователь №: 15 254



Цитата(kertis @ Jun 5 2006, 05:48) *
не очень понял ваше изложение.

Может вам просто буфер создать и спокойно обрабатывать данные когда МК "свооден" ? Буфер нужного размера вам автоматически нарисует CVAVR и пример есть в задаче 5 запрещенного курса.


я конечно наченающий но немного соображаю,

Буфер у меня 32 байта а информации иной раз и все 200 приходит, поэтому в обработке прерывания по приему байта я делаю так

Код
interrupt [UART_RXC] void uart_rx_isr(void)
{
char status,data;
int i=2;
status=USR;
data=UDR;
if (data != 0x0A)
   {
      if (data != 0x0d)
         {
            if ((status & (FRAMING_ERROR | DATA_OVERRUN))==0)
               {
                  rx_buffer[rx_wr_index]=data;
                  if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
                  if (++rx_counter == RX_BUFFER_SIZE)
                     {
                        rx_counter=0;
                        rx_buffer_overflow=1;
                     };
               };
         }
   }      
   else;
   {
      while(rx_counter != 0x00)
      {
      i++;
      fraza[i]==ReceiveByte();
      }
   }
}


где fraza переменная в еепроме, но из затого что размер полезных данных может меняться от 4 до 190 байт мне както нужно организовать обработку этих данных, когда начать ??? данные могут идти с разной интенсивностью.
Go to the top of the page
 
+Quote Post
rat
сообщение Jun 5 2006, 02:36
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 497
Регистрация: 9-06-05
Из: Новосибирск
Пользователь №: 5 852



Принимаемый поток организуете Вы же? Если так, то можно в сообщении передавать длину посылки, тогда и конец строки не понадобиться. Еще полезно передавать CRC, чтобы ошибки отлавливать.
Go to the top of the page
 
+Quote Post
TamTam
сообщение Jun 5 2006, 02:49
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 293
Регистрация: 14-03-06
Пользователь №: 15 254



Цитата(rat @ Jun 5 2006, 06:36) *
Принимаемый поток организуете Вы же? Если так, то можно в сообщении передавать длительность посылки, тогда и конец строки не понадобиться. Еще полезно передавать CRC, чтобы ошибки отлавливать.


к сожалению не я.

Цитата(kertis @ Jun 5 2006, 06:40) *
Щас наверно более опытные товарищи подскажут, но я б сделал буфер на 200 символов во-первых.


Вы меня натолкнули на мысль что нужно добавить выгрузку и при переполнении буфера.
на 200 не могу поскольку 2313 столько не имеет.
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Jun 5 2006, 03:04
Сообщение #5


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



Может быть эта ссылка Вам поможет?


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
TamTam
сообщение Jun 5 2006, 03:44
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 293
Регистрация: 14-03-06
Пользователь №: 15 254



Цитата(haker_fox @ Jun 5 2006, 07:04) *
Может быть эта ссылка Вам поможет?


Да нет спасибо, протокол не я делаю, есть готовое устройство с которым надо общаться, а вейк я както давно под дельфи реализовывал.
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Jun 5 2006, 05:24
Сообщение #7


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

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Идея правильная, вот пример кода который кочует из проекта в проект:

Код
struct {
        volatile    BYTE    mode;
        volatile    WORD  timeout;
        volatile    BYTE    errc;
        
        volatile    WORD    tx_cnt;
        volatile    WORD    tx_len;
        BYTE*               tx_buf;
        
        volatile    WORD    rx_cnt;
        volatile    WORD    rx_len;
        BYTE*                   rx_buf;
        } UCB; //UART control block

SIGNAL(SIG_UART_RECV)
{
//wdt_reset();
SET_RX_BUSY;

UCB.timeout = 0;
UCB.rx_buf[UCB.rx_cnt] = UDR;

if(hRxProc) hRxProc();

UCB.rx_cnt++;

if(UCB.rx_cnt >= UCB.rx_len)
    {
    CLR_RX_BUSY;
    if(hRxEnd) hRxEnd();    
    UCB.rx_cnt = 0;
    }
}


Здесь:
SET_RX_BUSY - установка флажка занятости UART (пакет в процессе приема)
hRxProc() вызов функции для анализа пришедшего байта проинициализиоравна как NULL
hRxEnd() вызов функции обработки заполненного буфера.
BYTE* tx_buf,rx_buf указатели на объявленные глобально буфера.

Теперь самое интересное- UCB.timeout. Один из таймеров умеющий работать в режиме CTC,
настроен на генерацию миллисекунд, в его прерывании ин(де)крементируются счетчики задержек,
счетчики секунд и UCB.timeout который проверяеться либо в основном контексте либо в hRxProc(),
смотря по протоколу.

И последнее не надо складывать данные сразу в EEPPROM - он не вечен.


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
WHALE
сообщение Jun 5 2006, 05:44
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768



Судя по 0A,0D-это модем.Действительн,в eeprom зачем постоянно складывать-рано илипоздно откажет.
А если нужно энергозависимое с большим обьемом-можно 537ру10 с развязкой по питанию и cs на диодах,а в качесте резервного источника можно конденсатор или аккумулятор-потребление минимально и количество циклов записи неограниченно.
kertisДостал,зараза sad.gif


--------------------
"Hello, word!" - 17 errors 56 warnings
Go to the top of the page
 
+Quote Post
vet
сообщение Jun 5 2006, 05:59
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32



Цитата(TamTam @ Jun 5 2006, 05:11) *
Ну написал с горем пополам обработку прирывания по окончанию приема байта, процедурку копирования из буфера в eeprom


В курсе, что ресурс EEPROM AVR - 100 тыс. записей?

Цитата(TamTam @ Jun 5 2006, 05:11) *
Правильно ли я мыслю или может есть способ по приличней, ведь таймер нужная и без этого весчь.


Трех стандартных AVR таймеров вполне хватит для чего угодно.


--------------------
Главная линия этого опуса ясна мне насквозь!
Go to the top of the page
 
+Quote Post
Nanobyte
сообщение Jun 5 2006, 07:39
Сообщение #10


За битами по регистрам гоняюсь
***

Группа: Свой
Сообщений: 457
Регистрация: 24-04-06
Из: Таганрог
Пользователь №: 16 446



Лучше применять не RAM со всеми его недостатками, а FRAM от Ramtron. Они теперь и с параллельным интерфейсом есть. При 3.3в питания число перезаписей неограничено (у них так написано в DS).


--------------------
Курсор влево, курсор вправо - считается хакерством. FORMAT C: производится без предупреждения
Go to the top of the page
 
+Quote Post
WHALE
сообщение Jun 5 2006, 07:56
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768



а почем нынче fram ?


--------------------
"Hello, word!" - 17 errors 56 warnings
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Jun 5 2006, 08:44
Сообщение #12


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

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Насколько я понял человек пишет во внутреннюю EEPROM, так-что FRAM в данном случае отдыхает. Я так понял речь идет о записии каких-то параметров или лога, 100 000 циклов за глаза хватит.Поэтому просто надо убедится, что да, данные заехали правильные, в полном объеме, а потом сбрасывать в EEPROM.
И еще один нюанс - писать, что во внешнюю, что во внутреннюю память надо вне прерывания - это же время.
Вот так вот выходит боком пресловутый "курс".


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
otrog
сообщение Jun 5 2006, 09:22
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 232
Регистрация: 22-02-06
Из: Воронеж
Пользователь №: 14 589



Цитата(WHALE @ Jun 5 2006, 11:56) *
а почем нынче fram ?

Пару месяцев назад FM24CL64-S мне привезли по 81.81р.
вообщем:
http://www.efind.ru/icsearch/?search=FM24


--------------------
Истина рождается в спорах; но когда страсти кипят, истина испаряется.
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 5 2006, 09:37
Сообщение #14


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(kertis @ Jun 5 2006, 12:16) *
Да курс то причем тут ?

в запрещенном курсе на стр 03.htm ясно написано
...

На пачках сигарет тоже пишут "курение опасно для здоровья". Много вы встретили курильщиков, которые бросили курить из-за этой надписи?
Go to the top of the page
 
+Quote Post
TamTam
сообщение Jun 6 2006, 02:06
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 293
Регистрация: 14-03-06
Пользователь №: 15 254



Цитата(WHALE @ Jun 5 2006, 09:44) *
Судя по 0A,0D-это модем.Действительн,в eeprom зачем постоянно складывать-рано илипоздно откажет.
А если нужно энергозависимое с большим обьемом-можно 537ру10 с развязкой по питанию и cs на диодах,а в качесте резервного источника можно конденсатор или аккумулятор-потребление минимально и количество циклов записи неограниченно.
kertisДостал,зараза sad.gif


Да имено модем. Почему именно eeprom ??? да только лиш по тому что ситуация при котором может что то появиться крайне редко может возникнуть, да и лучшебы ей вовсе не возникать, а то люди потеряют баксы, а баксы это для людей святое :-))))
Go to the top of the page
 
+Quote Post
vesago
сообщение Jun 6 2006, 08:08
Сообщение #16


Тутэйшы
****

Группа: Свой
Сообщений: 708
Регистрация: 30-11-04
Пользователь №: 1 263



Мне понравилось как у Атмела сделано. Я такую конструкцию не только для уарта применяю, но и вообще где надо стыковать асинхронные процессы. Также в примерах исходников prottos привел классный драйверок - аналог. На прием естественно надо таймаут ставить - после приема каждого байта заряжать таймер. Если нет данных в течение опеределенного времени - сбрасываем стэк. Кроме кольцевого буфера нужен буфер для сборки принимаемых пакетов и буфер для сборки отправляемых пакетов. А на будущее - haker_fox далл ссылку на прекрасный на мой субъективный взгляд протокол. Сам его повсеместно использую. Четко и стабильно работает. Програмная реализация тоже есть в исходниках.
Прикрепленные файлы
Прикрепленный файл  avr306.zip ( 4.01 килобайт ) Кол-во скачиваний: 84
 
Go to the top of the page
 
+Quote Post
TamTam
сообщение Jun 6 2006, 08:46
Сообщение #17


Местный
***

Группа: Свой
Сообщений: 293
Регистрация: 14-03-06
Пользователь №: 15 254



Цитата(vesago @ Jun 6 2006, 12:08) *
Мне понравилось как у Атмела сделано. Я такую конструкцию не только для уарта применяю, но и вообще где надо стыковать асинхронные процессы. Также в примерах исходников prottos привел классный драйверок - аналог. На прием естественно надо таймаут ставить - после приема каждого байта заряжать таймер. Если нет данных в течение опеределенного времени - сбрасываем стэк. Кроме кольцевого буфера нужен буфер для сборки принимаемых пакетов и буфер для сборки отправляемых пакетов. А на будущее - haker_fox далл ссылку на прекрасный на мой субъективный взгляд протокол. Сам его повсеместно использую. Четко и стабильно работает. Програмная реализация тоже есть в исходниках.


Да WAKE штука хорошая. Я его тоже однажды применял. но железо не моё было я токо под дельфю переписывал. Хотел библу с исходником выложить да так и потерял сурц а библа гдето лежит.
Go to the top of the page
 
+Quote Post
Sergiy
сообщение Jun 6 2006, 09:15
Сообщение #18


Участник
*

Группа: Новичок
Сообщений: 26
Регистрация: 29-05-06
Из: Netherlands (Delft)/Ukraine (Odessa)
Пользователь №: 17 547



Да, обратите внимание на фразу, что в обработчиках прерывания должны быть краткие функции, и не в коем случае писать незя в ЕЕПРОМ, потому что процесс достаточно длителен (мс на байт), выставьте битовую переменную, что нужный пакет в буфере обмена и готовьте следующее окно (я использую двухоконные буфера), когда один заполняется, второй готов и константен для целевой функции - все довольны, а оперирую двумя битовыми флагами, один показывает, что новый буфер подготовлен и ожидает, а второй что какое окно надо пользовать в данный момент целевой функцией, первое может менять в активное состояние прерывание приемника, в пассивное возвращает целевая функция, а окна переключаются в инверсии, да два буфера хватит если есть простой в конце заполнения второго буфера и ждать пока не будет сброшен обработки первого буфера в целевой функции.

Когда позволяет выбрать протокол - выбор вообще делаю в пользу битовой синхронизации начала пакета, работает не просто железно, а супержелезно. По таймауту тоже применяю, когда надо минимальная длина пакета с простой упаковкой. Применять шапочную синхронизацию по голове и-или хвосту без таймаутной проверки не стал бы - рискуете потерять часть пакетов и рассинхронизироваться, когда в секторе данных будут шапки - поймете их за служебные - а это только данные на самом деле. Но когда нить конечно синхронизация будет восстановлено, но пакеты патеряны для вас. Можно синхронизировать тройками, когда в секторе данных есть синхросимволы, то повторять их подряд три раза, это знак что это данные. Но это немного увеличит трафик и распаковку пакетов. Да, при таймаутах учитывайте особенности программирования под винду. Обрамляйте процесс передачи пакета в Делфи или Билдере где вы там пишете в РиалТайм процесс, это делается парой строчкой на Делфи но значительно понижает вероятность ложного таймаута внутри пакета. Хотя шанс маленький все равно остается, иногда больший (на раком установленных операционках, высокоприоритетных задачах, выполняемых одновременно с вашим приложением - запись, форматирование дисков smile.gif.
Go to the top of the page
 
+Quote Post
TamTam
сообщение Jun 6 2006, 09:38
Сообщение #19


Местный
***

Группа: Свой
Сообщений: 293
Регистрация: 14-03-06
Пользователь №: 15 254



Цитата(Sergiy @ Jun 6 2006, 13:15) *
Да, обратите внимание на фразу, что в обработчиках прерывания должны быть краткие функции, и не в коем случае писать незя в ЕЕПРОМ, потому что процесс достаточно длителен (мс на байт), выставьте битовую переменную, что нужный пакет в буфере обмена и готовьте следующее окно (я использую двухоконные буфера), когда один заполняется, второй готов и константен для целевой функции - все довольны, а оперирую двумя битовыми флагами, один показывает, что новый буфер подготовлен и ожидает, а второй что какое окно надо пользовать в данный момент целевой функцией, первое может менять в активное состояние прерывание приемника, в пассивное возвращает целевая функция, а окна переключаются в инверсии, да два буфера хватит если есть простой в конце заполнения второго буфера и ждать пока не будет сброшен обработки первого буфера в целевой функции.


Советик дельный, а вот что делать с размерностью буферов, ведь как известно памяти в AT90S2313
всего 128 байт надеюсь 2Х32 мне хватит через глаза.
Go to the top of the page
 
+Quote Post
Sergiy
сообщение Jun 7 2006, 08:03
Сообщение #20


Участник
*

Группа: Новичок
Сообщений: 26
Регистрация: 29-05-06
Из: Netherlands (Delft)/Ukraine (Odessa)
Пользователь №: 17 547



Цитата(TamTam @ Jun 6 2006, 11:38) *
Цитата(Sergiy @ Jun 6 2006, 13:15) *

Да, обратите внимание на фразу, что в обработчиках прерывания должны быть краткие функции, и не в коем случае писать незя в ЕЕПРОМ, потому что процесс достаточно длителен (мс на байт), выставьте битовую переменную, что нужный пакет в буфере обмена и готовьте следующее окно (я использую двухоконные буфера), когда один заполняется, второй готов и константен для целевой функции - все довольны, а оперирую двумя битовыми флагами, один показывает, что новый буфер подготовлен и ожидает, а второй что какое окно надо пользовать в данный момент целевой функцией, первое может менять в активное состояние прерывание приемника, в пассивное возвращает целевая функция, а окна переключаются в инверсии, да два буфера хватит если есть простой в конце заполнения второго буфера и ждать пока не будет сброшен обработки первого буфера в целевой функции.


Советик дельный, а вот что делать с размерностью буферов, ведь как известно памяти в AT90S2313
всего 128 байт надеюсь 2Х32 мне хватит через глаза.


Вообще все просто - надо брать размер буфера не менее чем максимальная длина пакета (он у вас наверное переменно
Go to the top of the page
 
+Quote Post
Sergiy
сообщение Jun 7 2006, 08:15
Сообщение #21


Участник
*

Группа: Новичок
Сообщений: 26
Регистрация: 29-05-06
Из: Netherlands (Delft)/Ukraine (Odessa)
Пользователь №: 17 547



Цитата(TamTam @ Jun 6 2006, 11:38) *
Цитата(Sergiy @ Jun 6 2006, 13:15) *

Да, обратите внимание на фразу, что в обработчиках прерывания должны быть краткие функции, и не в коем случае писать незя в ЕЕПРОМ, потому что процесс достаточно длителен (мс на байт), выставьте битовую переменную, что нужный пакет в буфере обмена и готовьте следующее окно (я использую двухоконные буфера), когда один заполняется, второй готов и константен для целевой функции - все довольны, а оперирую двумя битовыми флагами, один показывает, что новый буфер подготовлен и ожидает, а второй что какое окно надо пользовать в данный момент целевой функцией, первое может менять в активное состояние прерывание приемника, в пассивное возвращает целевая функция, а окна переключаются в инверсии, да два буфера хватит если есть простой в конце заполнения второго буфера и ждать пока не будет сброшен обработки первого буфера в целевой функции.


Советик дельный, а вот что делать с размерностью буферов, ведь как известно памяти в AT90S2313
всего 128 байт надеюсь 2Х32 мне хватит через глаза.


Вообще все просто - надо брать размер буфера не менее чем максимальная длина пакета (он у вас наверное переменной длины - выберите максимальный вариант) - если же пакет больше, то такая буферизация вам не подходит. Странный выбор контроллера на 2006 год, надеюсь что выбор продиктован только тем, что у вас есть какая то готовая плата пятилетней давности, и вы ее хотите использовать. Потому что щас можно дешевле купить то, что получше, например Атмега8 - стоит в Украине чуть больше евро - интересно сколько стоит ваш кристалл.

Так вот если все таки максимально длинная команда больше размера того, что вы ей можете предложить, то замедляйте обмен (скорость, интервалы между байтами в одном пакете), используйте буферизацию, но выполнение выгрузки из буфера прийдется начинать тогда, когда вы не дошли до конца пакета. В основном цикле сканируйте флаг наличия нового байта в буфере (буфер должен быть кольцевой), если есть - делайте выемку байта - сдвиг указателя кольцевого буфера на -1 и запись в ЕЕПРОМ, и так постоянно. Выбор невелик. Пример реализации кольцевого буфера на cvavr:

#define RX_BUFFER_SIZE1 32 //size of rx buffer

unsigned char rx_buffer[RX_BUFFER_SIZE1+1];
register unsigned char rxr_pntr=0, rxw_pntr = 0;


// UART Receiver interrupt service routine
//--------------------------------------------------------------------------
// Procedure of RXD interrupt processing
//--------------------------------------------------------------------------
interrupt [USART_RXC] void uart_rx_isr(void)
{
unsigned char temp_byte;

temp_byte=UDR;
rx_buffer[rxw_pntr]=temp_byte;
if (rxw_pntr < RX_BUFFER_SIZE1-1)
rxw_pntr++;
else rxw_pntr=0;
}

//--------------------------------------------------------------------------
// Extract a byte from rx-buffer if buffer isn't empty
//--------------------------------------------------------------------------
void check_rx_buffer()
{
unsigned char current_byte_from_buffer;

if (rxr_pntr != rxw_pntr)
{
#asm("cli");
current_byte_from_buffer=rx_buffer[rxr_pntr];
if (rxr_pntr < RX_BUFFER_SIZE1-1)
rxr_pntr++;
else rxr_pntr=0;
#asm("sei");
rx_buffer_processor(current_byte_from_buffer); <- ваша целевая функция над текущем байтом
}
}


Удачи
Go to the top of the page
 
+Quote Post

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

 


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


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