Olegus 0 20 марта, 2019 Опубликовано 20 марта, 2019 · Жалоба Меня тут заругали вчера что я лезу с своими тупыми вопросами и т.д. Вроде как разрешили тут задать вопрос. У меня такой код на дисковери F3 while (1) { char str1[30]={0}; // Объявил массив куда sprintf положит мое значение sprintf(str1,"%d\r\n", 15); // число десятичное ставлю соответствующий спецификатор новая строка и т.д. HAL_UART_Transmit(&huart2, (uint8_t*)str1, strlen(str1), 0x1000); // использую библиотеку HAL для передачи в USART моего числа (именно числа). Смотрю в // монитор порта вижу число 15 непрерывно передающееся Следовательно Во-первых идея правильная (в смысле код рабочий), во-вторых USART настроен верно. HAL_Delay(500); // делаю задержку чтобы порт успевал заполнится заведомо. Вроде то что надо. Но вот теперь мне надо передать также float. Вроде идея та же, меняю спецификатор в функции sprintf(), задаю точность (кол-во цифер после запятой) и все. Но результат в мониторе каретка двигается но никаких символов не наблюдаю. Вот код while (1) { char str1[30]={0}; // Объявил массив куда sprintf положит мое значение sprintf(str1,"%.3f\r\n", 1.23); HAL_UART_Transmit(&huart2, (uint8_t*)str1, strlen(str1), 0x1000); HAL_Delay(500); Мне специалисты на других сайтах говорили, что должно работать. Может тут в другом дело? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 20 марта, 2019 Опубликовано 20 марта, 2019 · Жалоба Компилятор какой? IDE? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 20 марта, 2019 Опубликовано 20 марта, 2019 · Жалоба 34 minutes ago, Olegus said: Мне специалисты на других сайтах говорили, что должно работать. Может тут в другом дело? Должоно без вариантов, если обычные строки передаются через HAL_UART_Transmit. Скорее всего неправильно сконфигурированы библиотеки компилятора. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Olegus 0 20 марта, 2019 Опубликовано 20 марта, 2019 · Жалоба 2 часа назад, Arlleex сказал: Компилятор какой? IDE? Работаю в True Studio. GCC компилятор ( насколько я разобрался). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 20 марта, 2019 Опубликовано 20 марта, 2019 · Жалоба 3 часа назад, Olegus сказал: Меня тут заругали вчера что я лезу с своими тупыми вопросами и т.д. Потому что вопросы задаёте совершенно безграмотно. И не в ту ветку. Цитата sprintf(str1,"%.3f\r\n", 1.23); "1.23" - это double, а в форматной строке указываете "f" - float. Цитата HAL_UART_Transmit(&huart2, (uint8_t*)str1, strlen(str1), 0x1000); Зачем ещё раз вычислять длину строки, если она уже известна??? Нужно примерно так: char str1[30]; HAL_UART_Transmit(&huart2, (uint8_t*)str1, sprintf(str1, "%.3f\r\n", 1.23f), 0x1000); Также нужно в свойствах проекта проверить, что подключен вариант stdlib с поддержкой плавающей точки. О чём вам тут уже не раз сказали. Цитата Мне специалисты на других сайтах говорили, что должно работать. Может тут в другом дело? "специалисты".... PS: И изучите возможности этого форума по правильному оформлению вставок исходного кода. Как сделано в этом моём посте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 20 марта, 2019 Опубликовано 20 марта, 2019 (изменено) · Жалоба HAL_UART_Transmit(&huart2, (uint8_t*)str1, sprintf(str1, "%.3f\r\n", 1.23f), 0x1000); sprintf монстр жрущий ресурсы. я делаю так Spoiler void FtoA(float n, char *res, int afterpoint) { int ap = afterpoint; //signed? if(n < 0) { n *= -1; *res = '-'; res++; } // Extract integer part int ipart = (int)n; // Extract floating part float fpart = n - (float)ipart; // convert integer part to string int i = IntToStr(ipart, res, 0); // check for display option after point if (afterpoint != 0) { res[i] = '.'; // add dot // Get the value of fraction part up to given no. // of points after dot. The third parameter is needed // to handle cases like 233.007 //fpart = fpart * pow(10, afterpoint); while (ap) { fpart *= 10; ap--; } IntToStr((int)fpart, res + i + 1, afterpoint); } } void Parser_SendFloat(USART_TypeDef *USARTx, float number, uint32_t afterpoint, uint32_t cr, uint32_t out) { uint32_t sign = 0; char strbuf[12]=""; if (number < 0) { number *= -1; sign = 1; } FtoA(number, strbuf, afterpoint); if (sign) USART_SendString(USARTx, "-"); USART_SendString(USARTx, strbuf); if(cr) USART_SendString(USARTx,"\r"); break; } Изменено 20 марта, 2019 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lagman 1 20 марта, 2019 Опубликовано 20 марта, 2019 · Жалоба Вот подсказка, о том что советовал @jcxz, для True Studio , https://www.eevblog.com/forum/microcontrollers/float-and-sprintf-atollic-truestudio-stm32f407/ Quote I think I got it. When creating a new project option like 'use tiny_printf' has to be unticked... And now my code is twice bigger but formatting also works. А если знаете хорошо IDE и знаете где настроить то можно и в текущем проекте поменять. Может кто работает в этой среде подскажет как изменить. Вот еще подсказка https://forum.atollic.com/viewtopic.php?f=3&t=141&p=3897&hilit=float#p3897 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Olegus 0 20 марта, 2019 Опубликовано 20 марта, 2019 · Жалоба 7 часов назад, Lagman сказал: Вот подсказка, о том что советовал @jcxz, для True Studio , https://www.eevblog.com/forum/microcontrollers/float-and-sprintf-atollic-truestudio-stm32f407/ А если знаете хорошо IDE и знаете где настроить то можно и в текущем проекте поменять. Может кто работает в этой среде подскажет как изменить. Вот еще подсказка https://forum.atollic.com/viewtopic.php?f=3&t=141&p=3897&hilit=float#p3897 Установил в Tool Setting моей ID Runtime library Newlib standart вместо Newlib Nano. И все заработало (все варианты кода которые я пробовал) . Всем спасибо. Особое спасибо Lagman, ссылки оказались те, что надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 20 марта, 2019 Опубликовано 20 марта, 2019 · Жалоба 10 часов назад, jenya7 сказал: sprintf монстр жрущий ресурсы. Ну-ну... Вы бы сначала что-то своё, не кривое придумали, прежде чем нормально работающее ругать... Цитата я делаю так Скрыть контент while (ap) { fpart *= 10; ap--; } А ничего, что в этом "алгоритме" из-за множественных умножений float-а и накапливающихся на них ошибках округления, иногда (очень редко) в результирующей строке будет совсем не то, что в исходном числе? Это даже не говоря о том, что кроме вещественных чисел, float может содержать и другие значения, которые вы игнорируете.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 34 20 марта, 2019 Опубликовано 20 марта, 2019 · Жалоба 53 minutes ago, jcxz said: Ну-ну... Вы бы сначала что-то своё, не кривое придумали, прежде чем нормально работающее ругать... А ничего, что в этом "алгоритме" из-за множественных умножений float-а и накапливающихся на них ошибках округления, иногда (очень редко) в результирующей строке будет совсем не то, что в исходном числе? Это даже не говоря о том, что кроме вещественных чисел, float может содержать и другие значения, которые вы игнорируете.... const float after[] = { 1f, 10f, 100f, 1000f, 10000f, ... }; ... if (afterpoint > 0 && afterpoint < N_ELMENT(after)) { fpart *= after[afterpoint]; ... } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 20 марта, 2019 Опубликовано 20 марта, 2019 · Жалоба 49 минут назад, x893 сказал: fpart *= after[afterpoint]; Хотя бы так. Осталось ещё о NaN,INF позаботиться.... и получим sprintf() Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EmbedElektrik 0 2 апреля, 2019 Опубликовано 2 апреля, 2019 · Жалоба а куда передается то? может быть с помощью union разбить флоат на 4 байта, а на принимающей стороне обратно собрать? или надо именно в терминал? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться