Olegus 0 March 20, 2019 Posted March 20, 2019 · Report post Меня тут заругали вчера что я лезу с своими тупыми вопросами и т.д. Вроде как разрешили тут задать вопрос. У меня такой код на дисковери 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); Мне специалисты на других сайтах говорили, что должно работать. Может тут в другом дело? Quote Share this post Link to post Share on other sites More sharing options...
Arlleex 55 March 20, 2019 Posted March 20, 2019 · Report post Компилятор какой? IDE? Quote Share this post Link to post Share on other sites More sharing options...
haker_fox 25 March 20, 2019 Posted March 20, 2019 · Report post 34 minutes ago, Olegus said: Мне специалисты на других сайтах говорили, что должно работать. Может тут в другом дело? Должоно без вариантов, если обычные строки передаются через HAL_UART_Transmit. Скорее всего неправильно сконфигурированы библиотеки компилятора. Quote Share this post Link to post Share on other sites More sharing options...
Olegus 0 March 20, 2019 Posted March 20, 2019 · Report post 2 часа назад, Arlleex сказал: Компилятор какой? IDE? Работаю в True Studio. GCC компилятор ( насколько я разобрался). Quote Share this post Link to post Share on other sites More sharing options...
jcxz 81 March 20, 2019 Posted March 20, 2019 · Report post 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: И изучите возможности этого форума по правильному оформлению вставок исходного кода. Как сделано в этом моём посте. Quote Share this post Link to post Share on other sites More sharing options...
jenya7 0 March 20, 2019 Posted March 20, 2019 (edited) · Report post 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; } Edited March 20, 2019 by jenya7 Quote Share this post Link to post Share on other sites More sharing options...
Lagman 0 March 20, 2019 Posted March 20, 2019 · Report post Вот подсказка, о том что советовал @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 Quote Share this post Link to post Share on other sites More sharing options...
Olegus 0 March 20, 2019 Posted March 20, 2019 · Report post 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, ссылки оказались те, что надо. Quote Share this post Link to post Share on other sites More sharing options...
jcxz 81 March 20, 2019 Posted March 20, 2019 · Report post 10 часов назад, jenya7 сказал: sprintf монстр жрущий ресурсы. Ну-ну... Вы бы сначала что-то своё, не кривое придумали, прежде чем нормально работающее ругать... Цитата я делаю так Скрыть контент while (ap) { fpart *= 10; ap--; } А ничего, что в этом "алгоритме" из-за множественных умножений float-а и накапливающихся на них ошибках округления, иногда (очень редко) в результирующей строке будет совсем не то, что в исходном числе? Это даже не говоря о том, что кроме вещественных чисел, float может содержать и другие значения, которые вы игнорируете.... Quote Share this post Link to post Share on other sites More sharing options...
x893 6 March 20, 2019 Posted March 20, 2019 · Report post 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]; ... } Quote Share this post Link to post Share on other sites More sharing options...
jcxz 81 March 20, 2019 Posted March 20, 2019 · Report post 49 минут назад, x893 сказал: fpart *= after[afterpoint]; Хотя бы так. Осталось ещё о NaN,INF позаботиться.... и получим sprintf() Quote Share this post Link to post Share on other sites More sharing options...
EmbedElektrik 0 April 2, 2019 Posted April 2, 2019 · Report post а куда передается то? может быть с помощью union разбить флоат на 4 байта, а на принимающей стороне обратно собрать? или надо именно в терминал? Quote Share this post Link to post Share on other sites More sharing options...