Jump to content

    
syoma

Простой протокол для UART на 8051 чтобы послать/принять 10 переменных

Recommended Posts

Привет всем.

Такой вопрос - в одном очень legacy проекте надо замутить периодический прием/передачу нескольких переменных по UART между двумя устройствами на 8052. Переменных порядка 10шт байтовых. Сейчас устройства обмениваются данными, но только одним байтом с проверкой четности.

Хочется сделать это самым экономичным способом, так как в ПЗУ осталось всего 500-700 байт памяти. Можно было бы попытаться сделать какое-то мультиплексирование, но не хочется изобретать велосипед, если он уже изобретен, поэтому хочется следовать какому-нибудь стандарту.

Я вот подумал о том, чтобы тупо слать фрейм в формате Modbus ASCII с функцией 0x10 (Write Multiple Registers). Думаю, что это проще, чем RTU, так как LRC посчитать проще, чем CRC-16.

Какие-нибудь еще простые варианты есть?

 

Share this post


Link to post
Share on other sites
6 minutes ago, MegaVolt said:

Ну сложить переменные друг за другом в памяти и передать этот кусок памяти побайтно использую имеющуюся функцию. 

Так сейчас в имеющейся функции приема никакого контроля первого/последнего принимаемого байта нет. Как прием будет угадывать, где первый байт?

Использовать бит четности или спец-символ?

Кстати, с оперативкой тоже есть напряг.

Share this post


Link to post
Share on other sites
11 минут назад, syoma сказал:

Так сейчас в имеющейся функции приема никакого контроля первого/последнего принимаемого байта нет. Как прием будет угадывать, где первый байт?

Использовать бит четности или спец-символ?

Можно byte stuffing применить. Можно применить четность как маркер начала пакета (встречал такое решение на практике). Если четность уже занята, можно сделать 9-и битовую посылку (8052 вроде это поддерживал).
А вообще мало от вас данных. Эти два байта туда-сюда они какие? Фиксированные, разные, в диапазоне...

Share this post


Link to post
Share on other sites
11 минут назад, syoma сказал:

Так сейчас в имеющейся функции приема никакого контроля первого/последнего принимаемого байта нет. Как прием будет угадывать, где первый байт?

Использовать бит четности или спец-символ?

Да некий флаг показывающий начало передачи. Например ещё одну переменную с фиксированным значением.

Цитата

Кстати, с оперативкой тоже есть напряг.

Если переменные существуют значит они уже лежат в памяти. Я предлагаю лишь расположить их в этой памяти рядом. Никаких доп затрат не нужно.

Share this post


Link to post
Share on other sites

У меня сейчас уже и используется 9-битовая посылка.

По поводу четности, как маркера начала пакета я думал - это стандартная практика? 

Переменные все фиксированные - пока лежат по разным адресам, но да, могу сдвинуть вместе. Также пара переменных лежит в битовом пространстве - их нужно будет упаковать в один байт для пересылки.

 

 

Share this post


Link to post
Share on other sites
33 minutes ago, syoma said:

. . . Я вот подумал о том, чтобы тупо слать фрейм в формате Modbus ASCII с функцией 0x10 (Write Multiple Registers). Думаю, что это проще, чем RTU, так как LRC посчитать проще, чем CRC-16.

Если в Вас фреймы, а не байтовый "поток" с интервалами то они (фреймы) могут выделяться паузами. CRC-любая, формат фрейма - любой. те. надо организовать "детектор молчания"/паузы. Это флаг "готовность приема следующего пакета"

 

Share this post


Link to post
Share on other sites

Переменные в каких диапазонах находятся?

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

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

Если данные должны сопровождаться некой CRC, то автоматом попадаем в пункт 1.

 

Данные передаются пакетами? Если да, то каков межпакетный интервал? Он есть? Вам и прием, и передачу замутить надо?

Если переменные представляют бинарные данные и спецсимволов выделить не получается, то посмотрите в сторону байт-стаффинга, например, он простой.

Если данные передаются пакетами (все переменные сразу за одну отправку), и всегда между пакетами существует минимальный гарантированный межкадровый интервал (например, в 1 байт), то можно выуживать кадры из потока с помощью таймера (ну или, если периферия МК позволяет, с помощью обнаружение IDLE шины).

Share this post


Link to post
Share on other sites
2 minutes ago, Arlleex said:

Переменные в каких диапазонах находятся?

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

5 minutes ago, Arlleex said:

Данные передаются пакетами? Если да, то каков межпакетный интервал? Он есть? Вам и прием, и передачу замутить надо?

Сейчас с одним байтом межпакетного интервала нет вообще - новые данные пихаются в SBUF прямо в прерывании TI от последовательного порта.

Мне нужно переделывать и прием и передачу и если мутить межкадровый интервал, то надо будет что-то придумывать - насколько я смотрю у меня свободных таймеров нет.

 

 

Share this post


Link to post
Share on other sites
9 минут назад, syoma сказал:

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

Как правило, это слово уже предопределяет судьбу любого не кодонезависимого протокола не в лучшую сторону:wink:

Посмотрите в сторону байт-стаффинга. Правда, и у него есть особенности: если они Вам не критичны - то решение огонь.

Особенности там таковы, что при некотором наборе данных на отправку, реально отправится в 2 раза больше кодированных символов.

Но это максимум. Т.е. не всегда, а при определенном наборе байт. Если интересно - почитайте за него, он прост как два пальца.

Share this post


Link to post
Share on other sites
3 minutes ago, syoma said:

Сейчас с одним байтом межпакетного интервала нет вообще . . . 

На сайте обсуждалость, с подачи jcxz (насколько помню) байтовый протокол, COBS.

Share this post


Link to post
Share on other sites
3 минуты назад, k155la3 сказал:

На сайте обсуждалость, с подачи jcxz (насколько помню) байтовый протокол, COBS.

Для COBS памяти (ОЗУ, по крайней мере) требуется больше и в реализации он чуть сложнее обычного стаффинга.

А у ТС с памятью напряг (с ПЗУ, а учитывая это, предполагаю, с ОЗУ еще хуже дела).

Share this post


Link to post
Share on other sites
14 minutes ago, Arlleex said:

Для COBS памяти (ОЗУ, по крайней мере) требуется больше и в реализации он чуть сложнее обычного стаффинга.

А у ТС с памятью напряг (с ПЗУ, а учитывая это, предполагаю, с ОЗУ еще хуже дела).

COBS требует буфера размера не менее 256 байт.

Но, в случае ТС, можно COBS подрезать и сделать его на 10 байт. Соответственно, буфер понадобится тоже на 10 байт. Избыточность - не более 1 байта.

 

ИМХО, проще взять готовую реализацию, там будет буфер на 256 байт. Зато никакого ограничения на размер пересылаемых данных.

 

ЗЫ. В интернетах куча примеров и реализаций - от pure C до python и delphi.

Share this post


Link to post
Share on other sites

Ну если "экономичным способом" и не критичен возникающий оверхед по передаваемым данным, то проще сделать SLIP-кодирование. Или типа него. Очень простое - кодировать/декодировать можно на лету, без буфера. COBS конечно красивее, но реализация будет более громоздкой + буфер.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.