Страница 1 из 2
передача массива данных по RS-232
Добавлено: Пн дек 03, 2012 00:41:50
VOUT
Товарищи, форумчане ! Помогите, пожалуйста.
Как передать массив типа float по RS-232. Микроконтроллер ATmega.
Нашёл возможное решение проблемы
http://beez-develop.ru/index.php/faq/pr ... float-uart
Но, проблема осталась...
История вот в чём. Допустим, записал я числа в массив. Числа типа float. Массив хранится будет видимо во flash или EEPROM (в общем в пямяти МК).
Массив соответственно тоже типа float. Как на ПК его передать ?!
По ссылке выше ищется адрес памяти, где хранится float и далее расписывается программа.
Re: передача массива данных по RS-232
Добавлено: Пн дек 03, 2012 05:50:10
Z_h_e
А чем собственно проблема? Берете и побайтно передаете. Или Вы не знаете как протокол передачи данных организовать? Как то я передовал массив данных в следующем формате:
- 0xAA 0xAA - стартовые два байта
---- - блок данных строго определенной длины
---
----
0x55 0x55 - два байта конца пакета.
Приняв два стартовых байта комп принимал n байт данных и соотвественно обрабатывал, пакет данных обязательно заканчивался двумя стоповыми байтами. По уму надо было добавить контрольную сумму, но у меня было так организовано что ошибочный пакет (а их не было) тут же исправлялся следующим правильным. Но как правило, контроль данных почти всегда обязателе, в служебную иноформацию можно вставить данные о длине пакета и прочее.
Re: передача массива данных по RS-232
Добавлено: Вт дек 04, 2012 23:42:54
frenele
здравствуйте! Итак для того чтобы передать любой массив данных необходимо создать протокол обмена.
Что это такое. Это взаимодействие двух приложений по определённым правилам. Первая программа это терминальное окно на компьютере. В которое пишут сообщения в виде пакета данных. Пример: #kmr01%. Это сообщение(пакет) состоит из 7 символов в ASCII. Суть заключается в следующем. Этот пакет имеет формат. Это первый символ '#' и последний '%'.(Символы можно брать произвольные кроме тех, что внутри пакета). Итак внутри пакета находится тело сообщения. Его размер желательно брать не большим. В этом примере второй символ 'k' указывает, что это команда. Третий 'm'- работа с памятью. И четвертый 'r' - чтение из памяти. А два последний символа '01' - это собственно адрес той ячейки памяти которую мы хотим прочитать. Так вот когда такое сообщение приходит в микроконтроллер. Оно (тело сообщения без символов '#' и '%') помещается в буфер приёма сообщения. После чего выставляется признак(флаг), что сообщение пришло. И другая подпрограмма начинает обрабатывать это сообщение.
Есть один момент при обработке тела сообщения это адрес '01' он передан в ASCII. Железяка ASCII не понимает. Нужен переводчик из ASCII в BIN(бинарный код).
Пример процедуры преобразования для PIC контроллёров.
;Подпрограмма преобразования ASCII в BIN.
ASCII_BIN:
movfw R5 ;Считываем старшый байт для обработки
movwf R7
movfw R6 ;Считываем младший байт для обработки
movwf R8
movlw 0x41 ;Это >= A?
subwf R5,f
btfsc STATUS,C
goto $+4
movlw 0x30 ;НЕТ - вычтем 30
subwf R7,f
goto $+3
movlw 0x37 ;ДА - вычтем 37
subwf R7,f
swapf R7 ;Переносим в старшую тетраду
movlw 0x41 ;Это >= A?
subwf R6,f
btfsc STATUS,C
goto $+4
movlw 0x30 ;НЕТ - вычтем 30
subwf R8,w
goto $+3
movlw 0x37 ;ДА - вычтем 37
subwf R8,w
iorwf R7,w ;Результат преобразования в аккумуляторе
return
пример кода для AVR микроконтроллёров.
;Подпрограмма преобразования ASCII в BIN.
ASCII_BIN:
cpi temp0,'A' ;Это >='A'?
brsh PC+3
subi temp0,0x30 ;НЕТ - вычтем 0x30
rjmp PC+2
subi temp0,0x37 ;ДА - вычтем 0x37
swap temp0
cpi temp1,'A' ;Это >='A'?
brsh PC+3
subi temp1,0x30 ;НЕТ - вычтем 0x30
rjmp PC+2
subi temp1,0x37 ;ДА - вычтем 0x37
or temp0,temp1 ;Результат в temp0
ret
Re: передача массива данных по RS-232
Добавлено: Ср дек 05, 2012 11:41:39
frenele
Суть преобразования из ASCII и BIN такова. Допустим нам надо перевести '01' ASCII в '01' BIN. '01' в HEXe это '3031'. Это занимает два байта. А нам нужен один байт но с той же по смыслу информацией '01'. Нам надо получить так, что в HEXe эта информация была представлена не как '3031', а '01'. Для этого необходимо вычесть из каждого байта 30 или 37 в зависимости от информации которую несёт один байт данных. А полученные результаты сгруппировать в один байт.
Re: передача массива данных по RS-232
Добавлено: Ср дек 05, 2012 22:59:32
menzoda
Я бы с ASCII не заморачивался. Мне кажется в данной ситуации это только усложняет задачу, и лучше использовать бинарный формат. Что-то по типу этого:
<SOF> <данные> <EOF>
SOF (Start Of Frame) - стартовый байт.
EOF (End Of Frame) - стоповый байт.
Это контрольные символы, означающие начало и конец кадра. По понятным причинам они не должны встретиться среди данных. Чтобы обойти это ограничение вводится еще один контрольный символ:
ESC (Escape) - экранирующий байт.
Отправка выглядит следующим образом:
1. Отправить SOF.
2. Взять очередной байт данных.
3. Если он равен SOF, EOF, или ESC, то отправить ESC.
4. Отправить байт данных.
5. Если все данные отправлены перейти в пункт 6, иначе в пункт 2.
6. Отправить EOF.
7. Конец.
Получение выглядит немного сложнее:
1. Получить очередной байт.
2. Если байт равен SOF, выкинуть все ранее сохраненные данные и перейти в пункт 3, иначе в пункт 1.
3. Получить очередной байт.
4. Если байт равен ESC, то перейти в пункт 5.
Если байт равен EOF, то перейти в пункт 6.
Если байт равен SOF, то перейти в пункт 1.
Иначе, сохраняем байт.
5. Получить очередной байт, сохранить, перейти в пункт 3.
6. Конец. Делаем, что нужно с сохраненными данными.
Вариации:
Можно в поле данных добавить контрольную сумму.
Можно использовать одинаковые старт-стоп символы..
Можно использовать или только старт-, или только стоп-символ.
Если мы тут зря пишем такие портянки и главный вопрос заключается не в организации протокола, а в том, как передать конкретно float, то это сделать очень просто. Преобразуешь float в массив из четырех байтов, отправляешь этот массив с оговоренным порядком следования байтов, на принимающей стороне преобразуешь обратно во float.
Re: передача массива данных по RS-232
Добавлено: Чт дек 06, 2012 00:06:43
Jack_A
menzoda писал(а): Преобразуешь float в массив из четырех байтов
В общем-то Float после вычисления его в проге на С и занимает 4 байта (*) , и преобразовывать ничего не надо. Другое дело, не факт, что формат Сишного (МК) float совпадает с float ПК. Так что расщепить float на ЗНАК - ПОРЯДОК - ЗНАК ПОРЯДКА - МАНТИССУ все равно придется. Ну а собрать на приемном конце уже не вопрос, если на обеих сторонах линии соблюдены оговоренные условия.
(*) - я на Си для МК не программлю, так что могу и ошибиться, но мой склероз шепчет, что именно так.
Re: передача массива данных по RS-232
Добавлено: Чт дек 06, 2012 07:47:09
menzoda
В общем-то Float после вычисления его в проге на С и занимает 4 байта (*) , и преобразовывать ничего не надо.
Ну надо же из переменной типа float получить массив из четырех байт. Вот это я и имел в виду под преобразованием.
Другое дело, не факт, что формат Сишного (МК) float совпадает с float ПК. Так что расщепить float на ЗНАК - ПОРЯДОК - ЗНАК ПОРЯДКА - МАНТИССУ все равно придется.
А вот это ерунда. Подавляющее большинство архитектур реализует 32-битное значение float согласно стандарту IEEE754. Так что 99.99%, что ничего выдумывать не надо - просто разбей бинарное представление float на байты и передавай. Другое дело порядок байт, да, за этим нужно следить.
Конечно, если автор использует какой-нибудь PIC, где есть 24-битный float, который не поддерживается PC, то я согласен с тем, что придется конвертировать на передающей, или на принимающей стороне.
Re: передача массива данных по RS-232
Добавлено: Чт дек 06, 2012 11:38:59
Jack_A
"Нет, дорогой Битнер, это не ерунда!" (С) Мюллер
Не будем смешивать "железячную" плавучку с реализацией float в языке программирования. В Delphi, напимер, 4 типа
float :
Real48 6 байт
Single 4
Double 8
Extended 10
так что формат и способ хранения совершенно разный.
Вы сами себе противоречите.
Подавляющее большинство архитектур реализует 32-битное значение float согласно стандарту IEEE754.
Переменная float и есть тот самый "массив из 4 байт ", тогда что тут и в чего преобразовывать ? Взял эти 4 байта и тупо передал. А уж на приемной стороне разгребай в соответствии с имеющейся в проге системой плавучки. Другое дело, что в 99% МК аппаратной плавучки нет и она реализуется компилятором софтово, и соблюл ли разработчик в библиотеках этот IEEE754 -- это дело его "партейной совести" .
Я в свое время для передачи float использовал 3-байтовый упакованный формат -- не с целью повыёживаться, а для минимизации времени передачи при сохранении приемлемой точности. "Неизменно превосходный результат" (С) Из рекламы
Re: передача массива данных по RS-232
Добавлено: Пт дек 07, 2012 00:17:24
frenele
VOUT писал(а):Товарищи, форумчане ! Помогите, пожалуйста.
Как передать массив типа float по RS-232. Микроконтроллер ATmega.
Нашёл возможное решение проблемы
http://beez-develop.ru/index.php/faq/pr ... float-uart
Но, проблема осталась...
История вот в чём. Допустим, записал я числа в массив. Числа типа float. Массив хранится будет видимо во flash или EEPROM (в общем в пямяти МК).
Массив соответственно тоже типа float. Как на ПК его передать ?!
По ссылке выше ищется адрес памяти, где хранится float и далее расписывается программа.
Ребята вы о чём пишите?! Человек спрашивает как передать данные от персонального компьютера с операционной системой которая оперирует числами с формате ANSI и ASCII в микроконтроллер ATmega который не работает бод операционной системой и его ядро не понимает эту кодировку как персональный компьютер. А какую вы передаёте смысловую информацию роли не играет. Главное чтобы она была упакована.
Пример:
Допустим на компьютере есть два числа
первое пусть будет - 110000
второе пусть будет - 44000
которые надо передать в микроконтроллер и там к примеру сложить
представим с начало эти числа в таком виде
первое 11*10^4
второе 44*10^3
Далее их мантиссы и степени необходимо перевести в HEX, а основания примем как стандартное основание для всех чисел.
первое B и 4
второе 2С и 3
Затем эти шесть символов(байт) отправляем в микроконтроллер где они преобразуется в бинарное представление и далее
программа видит, что степени разные одно равно 4 другое 3. Делим 2С на A при этом увеличиваем степень с 3 до 4. По сути вещей мы сдвинули запятую влево у числа тем самым приравняли степени. Теперь мантиссы можно сложить.
4+B=F
Итак получили результат мантисса F и степень 4
затем преобразуемый результат в ASCII и полученные два байта отправляем на терминальное окно персонального компьютера
мы видим 'F4'
представим в десятичной системе
15*10^4=150000
проверим 44000+110000=154000
погрешность 4000 объясняется тем, что взята маленькая разрядная сетка в 8 бит. Если бы мы взяли 16 то результат был бы точней.
Вот пример организации персонального компьютера с микроконтроллером.
Re: передача массива данных по RS-232
Добавлено: Пт дек 07, 2012 07:56:33
menzoda
Да это вы тут несете какую-то ерунду. Заняться что-ли нечем, флоаты на мантисы и основания раскладывать/складывать? Берете ПК, смотрите. Ага, есть 32-битный флоат. Ага, реализован по стандарту IEEE754. Берете ATMega с компилятором, смотрите. Ага, есть 32-битный флоат (аппаратный или программный, не суть). Ага, реализован по стандарту IEEE754. ВСЕ! Передаете побайтно бинарное представление флоата и радуетесь!
Получить из флоата массив байтов и наоборот можно, например, вот так:
Код: Выделить всё
// На С/С++.
union
{
flaot foo;
char bar[4];
} converter;
converter.foo = 0.35356; // наш флоат
converter.bar[0..3] // наши байты.
// На С#
float foo;
byte[] bar = BitConverter.GetBytes(foo); // наши байты.
foo = BitConverter.ToSingle(bar, 0); // наш флоат
Если вдруг неожиданно флоаты реализованы по-разному, то тогда уже можно задуматься о более сложной упаковке/распаковке.
Re: передача массива данных по RS-232
Добавлено: Сб дек 08, 2012 00:03:45
frenele
А теперь дружок возьми терминальное окно и попробуй передать свой флоат по какому либо интерфейсу. Весь обмен по цифровым линиям связи осуществляется в виде кодировки ASCII. Все терминальные окна работают в основном в стандарте ASCII. Терминальное окно удобно использовать для отладки софта для цифрового устройства.
Re: передача массива данных по RS-232
Добавлено: Сб дек 08, 2012 00:08:42
ploop
А теперь дружок возьми терминальное окно и попробуй передать свой флоат по какому либо интерфейсу
Легко.
Весь обмен по цифровым линиям связи осуществляется в виде кодировки ASCII
Что за бред?
Re: передача массива данных по RS-232
Добавлено: Сб дек 08, 2012 00:09:45
Tolmi
frenele писал(а):
А теперь дружок возьми терминальное окно и попробуй передать свой флоат по какому либо интерфейсу. Весь обмен по цифровым линиям связи осуществляется в виде кодировки ASCII.
Можно конечно и так. Можно, но необязательно

Более того, если важна
скорость передачи, то такой подход безусловно вреден.
К примеру устройство хочет передать плавающее число с одинарной точностью 3.1156204
Если передавать в ASCII, то понадобится 9 байт ( и это не самое длинное представление числа, а если там порядок очень маленький, и оно отрицательное ? -0.123456E-27 будет занимать целых 13 байт ! )
При прямой передаче байтами это же число занимает 4 байта :
То, что человек не может увидеть напрямую что @GfS это вовсе не это, а 3.1156204, на самом деле ничего не значит, ведь чаще всего общаться будут с обоих сторон программы. А им всё равно.
Re: передача массива данных по RS-232
Добавлено: Сб дек 08, 2012 00:11:58
frenele
ploop писал(а):А теперь дружок возьми терминальное окно и попробуй передать свой флоат по какому либо интерфейсу
Легко.
Весь обмен по цифровым линиям связи осуществляется в виде кодировки ASCII
Что за бред?
Вы пользовались терминальными окнами при отладки цифровых устройств?
Re: передача массива данных по RS-232
Добавлено: Сб дек 08, 2012 00:13:23
Goldsmith
frenele писал(а):Весь обмен по цифровым линиям связи осуществляется в виде кодировки ASCII.
Крайне смелое утверждение, однако.
frenele писал(а):Терминальное окно удобно использовать для отладки софта для цифрового устройства.
Для
отладки софта для цифрового устройства (а бывает еще и софт для аналоговых устройств?) удобно использовать
отладчик.
Re: передача массива данных по RS-232
Добавлено: Сб дек 08, 2012 00:17:53
ploop
Вы пользовались терминальными окнами при отладки цифровых устройств?
Да, постоянно. Даже не используя никакого терминального софта я прямо сейчас могу передать что угодно куда угодно:
Код: Выделить всё
echo -e "\x00\x35\x00\xАА\xFF\x00\x01\x0C\xF4" > /dev/ttyX
Не нужно ничего, кроме стандартной линуксовой консоли.
Re: передача массива данных по RS-232
Добавлено: Сб дек 08, 2012 00:22:13
frenele
Goldsmith писал(а):frenele писал(а):Весь обмен по цифровым линиям связи осуществляется в виде кодировки ASCII.
Крайне смелое утверждение, однако.
frenele писал(а):Терминальное окно удобно использовать для отладки софта для цифрового устройства.
Для
отладки софта для цифрового устройства (а бывает еще и софт для аналоговых устройств?) удобно использовать
отладчик.
причём здесь аналоговая аппаратура. Речь идёт о цифровой аппретуре.
Самое распространённое терминальное окно это
HyperTerminal
а вот справочные ссылки
http://ru.wikipedia.org/wiki/%C3%E8%EF% ... 8%ED%E0%EB
http://ru.wikipedia.org/wiki/Telnet
Re: передача массива данных по RS-232
Добавлено: Сб дек 08, 2012 00:30:06
frenele
И ещё для передачи больших чисел лучше их заранее разложить на мантиссу и степень таким образом можно уплотнить данные в потоке.
Re: передача массива данных по RS-232
Добавлено: Сб дек 08, 2012 00:34:38
Tolmi
frenele писал(а):
Самое распространённое терминальное окно это
HyperTerminal
Telnet
И при чём тут это ? Для собственных протоколов между своими разработками вовсе необязательно приводить информацию к читаемому виду, в ущерб скорости и объёму программы на МК. Перевод в ASCII вещественного числа - здоровый кусок кода в флеше, которым можно спокойно пожертвовать. Тем, что при этом для отладки, чтобы посмотреть, что же там передаётся, нужно написать простейшую программу-заглушку для чтения и перевода в человекочитаемый вид, можно смело пренебречь. Это не самая большая проблема. Да обычно и не так это делают, на ПК в своей программе делают обильный отладочный вывод, куда-нибудь в stderr и всё.
Re: передача массива данных по RS-232
Добавлено: Сб дек 08, 2012 00:39:34
ploop
А при какой тут кухне telnet? Может TCP/IP до кучи сюда приплетём? Да чего уж мелочиться, передавать данные в HTML.
Хотя последний вариант не так уж сложен - поднять веб-сервер на каком-нибудь SOC гораздо проще, чем уместить 8 кило эффективного и надёжного кода в какой-нибудь AVR-ке.