![]() |
Модераторы: PILOT, ManiaK, Mazzi |
![]() ![]() ![]() |
|
Курсант |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 338 Регистрация: 21.2.2009 Где: Балашиха или Воро неж Репутация: нет Всего: 4 |
Всем доброго времени суток!
У меня следующая проблема: я отправляю из микроконтроллера по UART данные в формате float, получаю их на ПК программой, написанной на VC++. Получаю эти 4 байта я в массив байтов, и привожу их к типу float (на самом деле использую union, ну это не принципиально). Проблема в том, что данные, которые видит ПК, не такие, какими их видит контроллер. Т.е. если для контроллера это 27,24324, то для ПК это оказывается 11,534534. Примерно так. При этом есть ещё одна программа, написанная коллегой на Java, которая также принимает 4 байта, и приводит их к типу float функцией BytesToFloat, или чем-то таким. И программа на Java видит переменные такими, какими их видит контроллер. Но Java выполняется Java-машиной, и как там реализован тип float - не ясно... Может быть кто-нибудь сталкивался с похожими проблемами, знает в какую сторону копать? Спасибо за внимание... |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 8 Всего: 223 |
Копать в сторону совпадения Endianess на МК и ПС, а так же в сторону формата этого самого флоата - совпадают ли они. Если да, то скорее всего это будет IEEE 754, а если не IEEE - то скорее всего не совпадут
![]() |
|||
|
||||
Курсант |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 338 Регистрация: 21.2.2009 Где: Балашиха или Воро неж Репутация: нет Всего: 4 |
Это я и сам понял
![]() Кстати, получается, что учитывая ядро моего контроллера (Cortex-M3, а иногда и Cortex-M0) формат флота контроллера нужно узнавать не в документации на контроллер, а в документации на компилятор? |
|||
|
||||
ФедосеевПавел |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 7.2.2009 Репутация: 1 Всего: 10 |
Не знаком с С, просто предполагаю, что float - обобщённый тип данных с плавающей запятой, для корректной работы на ПК желательно указать конкретно single или double, точнее single. А потом уточнить порядок байт.
|
|||
|
||||
Курсант |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 338 Регистрация: 21.2.2009 Где: Балашиха или Воро неж Репутация: нет Всего: 4 |
Спасибо за ответ. Я не знаком с VB, но если не ошибаюсь, в концепциях VB тип float является обобщённым, и нужно указывать точность - single или double. В языке Си для двойной точности предназначен тип double, а для единичной - float. Добавлено через 11 минут и 26 секунд Проблема так и не решилась. Поэтому начну вдаваться в детали. Вот сюда я записываю свои байты:
Соответственно, я принимаю данные в DataField.Byte1, DataField.Byte2, DataField.Byte3 и DataField.Byte4, а затем вычитываю их как DataField.AsFloat; При этом принятые значения отличаются примерно в два с половиной раза от тех, которые я отправлял. Т.е. Big-Endian - Little-Endian соответствие соблюдено (я пробовал менять байты местами, получался какой-то мусор вместо тех данных, которые я отправлял). Из всего вышеизложенного я сделал вывод, что проблема - в формате данных float, а именно в структуре мантиссы и показателя степени, знака и их сдвигов-размеров-положения. Проблема усугубляется тем, что в микроконтроллере я имею soft-float, т.е. тип float ненастоящий, программируется компилятором используя целочисленную арифметику контроллера. И как он там устроен - большой вопрос... Фактически, он устроен отличным от компьютера образом. Придётся, видимо, делать самую неприятную часть работы - брать 16-ричное значение, и пытаться получить из него отправляемое значение, воссоздавая логику компилятора по работе с float. |
||||
|
|||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 8 Всего: 223 |
||||
|
||||
Курсант |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 338 Регистрация: 21.2.2009 Где: Балашиха или Воро неж Репутация: нет Всего: 4 |
arm-gcc В ПК и в компиляторе, судя по всему, всё соответствует Проблема, похоже, в том, что я теряю некоторые биты при приёме через COM-порт. Использую я для этого класс serialPort из VisualC++. Читаю данные в строку с помощью метода serialPort->ReadLine; Проблема была в методе ReadLine объекта serialPort Судя по всему метод предназначен для вычитывания текстовых строк из COM-порта. Поэтому нетипичные для текстовых строк байты метод "коверкает". Когда я стал вычитывать байты методом ReadByte, все данные стали отображаться нормально. Это сообщение отредактировал(а) Курсант - 13.8.2015, 10:58 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Микроконтроллеры (MCU) и микропроцессоры (MPU)" | |
|
На данный раздел помимо Правил форума распространяются текже следующие правила:
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, PILOT, ManiaK, UniBomb, Mazzi. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Микроконтроллеры (MCU) и микропроцессоры (MPU) | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |