передача массива данных по RS-232

Подключаем наши девайсы к компьютеру. Обсуждаются: порты, протоколы, драйвера, языки программирования и т.д.
Аватара пользователя
VOUT
Открыл глаза
Сообщения: 49
Зарегистрирован: Вс сен 30, 2012 00:01:53

передача массива данных по RS-232

Сообщение VOUT »

Товарищи, форумчане ! Помогите, пожалуйста. :cry:
Как передать массив типа float по RS-232. Микроконтроллер ATmega.
Нашёл возможное решение проблемы http://beez-develop.ru/index.php/faq/pr ... float-uart

Но, проблема осталась... :(
История вот в чём. Допустим, записал я числа в массив. Числа типа float. Массив хранится будет видимо во flash или EEPROM (в общем в пямяти МК).
Массив соответственно тоже типа float. Как на ПК его передать ?!
По ссылке выше ищется адрес памяти, где хранится float и далее расписывается программа.
Реклама
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: передача массива данных по RS-232

Сообщение Z_h_e »

А чем собственно проблема? Берете и побайтно передаете. Или Вы не знаете как протокол передачи данных организовать? Как то я передовал массив данных в следующем формате:
  • 0xAA 0xAA - стартовые два байта
    ---- - блок данных строго определенной длины
    ---
    ----
    0x55 0x55 - два байта конца пакета.
Приняв два стартовых байта комп принимал n байт данных и соотвественно обрабатывал, пакет данных обязательно заканчивался двумя стоповыми байтами. По уму надо было добавить контрольную сумму, но у меня было так организовано что ошибочный пакет (а их не было) тут же исправлялся следующим правильным. Но как правило, контроль данных почти всегда обязателе, в служебную иноформацию можно вставить данные о длине пакета и прочее.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Аватара пользователя
frenele
Родился
Сообщения: 16
Зарегистрирован: Вт дек 04, 2012 23:02:59

Re: передача массива данных по RS-232

Сообщение 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
Аватара пользователя
frenele
Родился
Сообщения: 16
Зарегистрирован: Вт дек 04, 2012 23:02:59

Re: передача массива данных по RS-232

Сообщение frenele »

Суть преобразования из ASCII и BIN такова. Допустим нам надо перевести '01' ASCII в '01' BIN. '01' в HEXe это '3031'. Это занимает два байта. А нам нужен один байт но с той же по смыслу информацией '01'. Нам надо получить так, что в HEXe эта информация была представлена не как '3031', а '01'. Для этого необходимо вычесть из каждого байта 30 или 37 в зависимости от информации которую несёт один байт данных. А полученные результаты сгруппировать в один байт.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
menzoda
Вымогатель припоя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Re: передача массива данных по RS-232

Сообщение 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.
Реклама
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6312
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: передача массива данных по RS-232

Сообщение Jack_A »

menzoda писал(а): Преобразуешь float в массив из четырех байтов
В общем-то Float после вычисления его в проге на С и занимает 4 байта (*) , и преобразовывать ничего не надо. Другое дело, не факт, что формат Сишного (МК) float совпадает с float ПК. Так что расщепить float на ЗНАК - ПОРЯДОК - ЗНАК ПОРЯДКА - МАНТИССУ все равно придется. Ну а собрать на приемном конце уже не вопрос, если на обеих сторонах линии соблюдены оговоренные условия.
(*) - я на Си для МК не программлю, так что могу и ошибиться, но мой склероз шепчет, что именно так.
Реклама
Аватара пользователя
menzoda
Вымогатель припоя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Re: передача массива данных по RS-232

Сообщение menzoda »

В общем-то Float после вычисления его в проге на С и занимает 4 байта (*) , и преобразовывать ничего не надо.
Ну надо же из переменной типа float получить массив из четырех байт. Вот это я и имел в виду под преобразованием.
Другое дело, не факт, что формат Сишного (МК) float совпадает с float ПК. Так что расщепить float на ЗНАК - ПОРЯДОК - ЗНАК ПОРЯДКА - МАНТИССУ все равно придется.
А вот это ерунда. Подавляющее большинство архитектур реализует 32-битное значение float согласно стандарту IEEE754. Так что 99.99%, что ничего выдумывать не надо - просто разбей бинарное представление float на байты и передавай. Другое дело порядок байт, да, за этим нужно следить.

Конечно, если автор использует какой-нибудь PIC, где есть 24-битный float, который не поддерживается PC, то я согласен с тем, что придется конвертировать на передающей, или на принимающей стороне.
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6312
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: передача массива данных по RS-232

Сообщение Jack_A »

"Нет, дорогой Битнер, это не ерунда!" (С) Мюллер

Не будем смешивать "железячную" плавучку с реализацией float в языке программирования. В Delphi, напимер, 4 типа
float :
Real48 6 байт
Single 4
Double 8
Extended 10

так что формат и способ хранения совершенно разный.

Вы сами себе противоречите.
Подавляющее большинство архитектур реализует 32-битное значение float согласно стандарту IEEE754.
Переменная float и есть тот самый "массив из 4 байт ", тогда что тут и в чего преобразовывать ? Взял эти 4 байта и тупо передал. А уж на приемной стороне разгребай в соответствии с имеющейся в проге системой плавучки. Другое дело, что в 99% МК аппаратной плавучки нет и она реализуется компилятором софтово, и соблюл ли разработчик в библиотеках этот IEEE754 -- это дело его "партейной совести" .
Я в свое время для передачи float использовал 3-байтовый упакованный формат -- не с целью повыёживаться, а для минимизации времени передачи при сохранении приемлемой точности. "Неизменно превосходный результат" (С) Из рекламы
Аватара пользователя
frenele
Родился
Сообщения: 16
Зарегистрирован: Вт дек 04, 2012 23:02:59

Re: передача массива данных по RS-232

Сообщение frenele »

VOUT писал(а):Товарищи, форумчане ! Помогите, пожалуйста. :cry:
Как передать массив типа 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 то результат был бы точней.

Вот пример организации персонального компьютера с микроконтроллером.
Аватара пользователя
menzoda
Вымогатель припоя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Re: передача массива данных по RS-232

Сообщение 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); // наш флоат
Если вдруг неожиданно флоаты реализованы по-разному, то тогда уже можно задуматься о более сложной упаковке/распаковке.
Аватара пользователя
frenele
Родился
Сообщения: 16
Зарегистрирован: Вт дек 04, 2012 23:02:59

Re: передача массива данных по RS-232

Сообщение frenele »

А теперь дружок возьми терминальное окно и попробуй передать свой флоат по какому либо интерфейсу. Весь обмен по цифровым линиям связи осуществляется в виде кодировки ASCII. Все терминальные окна работают в основном в стандарте ASCII. Терминальное окно удобно использовать для отладки софта для цифрового устройства.
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: передача массива данных по RS-232

Сообщение ploop »

А теперь дружок возьми терминальное окно и попробуй передать свой флоат по какому либо интерфейсу
Легко.
Весь обмен по цифровым линиям связи осуществляется в виде кодировки ASCII
Что за бред?
Tolmi
Говорящий с текстолитом
Сообщения: 1658
Зарегистрирован: Вс дек 11, 2011 05:25:04
Откуда: Киев, Украина
Контактная информация:

Re: передача массива данных по RS-232

Сообщение Tolmi »

frenele писал(а): А теперь дружок возьми терминальное окно и попробуй передать свой флоат по какому либо интерфейсу. Весь обмен по цифровым линиям связи осуществляется в виде кодировки ASCII.
Можно конечно и так. Можно, но необязательно :)
Более того, если важна скорость передачи, то такой подход безусловно вреден.

К примеру устройство хочет передать плавающее число с одинарной точностью 3.1156204
Если передавать в ASCII, то понадобится 9 байт ( и это не самое длинное представление числа, а если там порядок очень маленький, и оно отрицательное ? -0.123456E-27 будет занимать целых 13 байт ! )
При прямой передаче байтами это же число занимает 4 байта : То, что человек не может увидеть напрямую что @GfS это вовсе не это, а 3.1156204, на самом деле ничего не значит, ведь чаще всего общаться будут с обоих сторон программы. А им всё равно.
Последний раз редактировалось Tolmi Сб дек 08, 2012 00:58:29, всего редактировалось 2 раза.
In theory, theory and practice are the same. In practice, they're not.
Аватара пользователя
frenele
Родился
Сообщения: 16
Зарегистрирован: Вт дек 04, 2012 23:02:59

Re: передача массива данных по RS-232

Сообщение frenele »

ploop писал(а):
А теперь дружок возьми терминальное окно и попробуй передать свой флоат по какому либо интерфейсу
Легко.
Весь обмен по цифровым линиям связи осуществляется в виде кодировки ASCII
Что за бред?
Вы пользовались терминальными окнами при отладки цифровых устройств?
Аватара пользователя
Goldsmith
Опытный кот
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону
Контактная информация:

Re: передача массива данных по RS-232

Сообщение Goldsmith »

frenele писал(а):Весь обмен по цифровым линиям связи осуществляется в виде кодировки ASCII.
Крайне смелое утверждение, однако.
frenele писал(а):Терминальное окно удобно использовать для отладки софта для цифрового устройства.
Для отладки софта для цифрового устройства (а бывает еще и софт для аналоговых устройств?) удобно использовать отладчик.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: передача массива данных по RS-232

Сообщение ploop »

Вы пользовались терминальными окнами при отладки цифровых устройств?
Да, постоянно. Даже не используя никакого терминального софта я прямо сейчас могу передать что угодно куда угодно:

Код: Выделить всё

echo -e "\x00\x35\x00\xАА\xFF\x00\x01\x0C\xF4" > /dev/ttyX
Не нужно ничего, кроме стандартной линуксовой консоли.
Аватара пользователя
frenele
Родился
Сообщения: 16
Зарегистрирован: Вт дек 04, 2012 23:02:59

Re: передача массива данных по RS-232

Сообщение frenele »

Goldsmith писал(а):
frenele писал(а):Весь обмен по цифровым линиям связи осуществляется в виде кодировки ASCII.
Крайне смелое утверждение, однако.
frenele писал(а):Терминальное окно удобно использовать для отладки софта для цифрового устройства.
Для отладки софта для цифрового устройства (а бывает еще и софт для аналоговых устройств?) удобно использовать отладчик.
причём здесь аналоговая аппаратура. Речь идёт о цифровой аппретуре.
Самое распространённое терминальное окно это
HyperTerminal

а вот справочные ссылки
http://ru.wikipedia.org/wiki/%C3%E8%EF% ... 8%ED%E0%EB
http://ru.wikipedia.org/wiki/Telnet
Аватара пользователя
frenele
Родился
Сообщения: 16
Зарегистрирован: Вт дек 04, 2012 23:02:59

Re: передача массива данных по RS-232

Сообщение frenele »

И ещё для передачи больших чисел лучше их заранее разложить на мантиссу и степень таким образом можно уплотнить данные в потоке.
Tolmi
Говорящий с текстолитом
Сообщения: 1658
Зарегистрирован: Вс дек 11, 2011 05:25:04
Откуда: Киев, Украина
Контактная информация:

Re: передача массива данных по RS-232

Сообщение Tolmi »

frenele писал(а): Самое распространённое терминальное окно это
HyperTerminal
Telnet
И при чём тут это ? Для собственных протоколов между своими разработками вовсе необязательно приводить информацию к читаемому виду, в ущерб скорости и объёму программы на МК. Перевод в ASCII вещественного числа - здоровый кусок кода в флеше, которым можно спокойно пожертвовать. Тем, что при этом для отладки, чтобы посмотреть, что же там передаётся, нужно написать простейшую программу-заглушку для чтения и перевода в человекочитаемый вид, можно смело пренебречь. Это не самая большая проблема. Да обычно и не так это делают, на ПК в своей программе делают обильный отладочный вывод, куда-нибудь в stderr и всё.
In theory, theory and practice are the same. In practice, they're not.
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: передача массива данных по RS-232

Сообщение ploop »

А при какой тут кухне telnet? Может TCP/IP до кучи сюда приплетём? Да чего уж мелочиться, передавать данные в HTML.
Хотя последний вариант не так уж сложен - поднять веб-сервер на каком-нибудь SOC гораздо проще, чем уместить 8 кило эффективного и надёжного кода в какой-нибудь AVR-ке.
Ответить

Вернуться в «Интеграция с ПК»