Перейти к содержанию
    

Как передать дробное число по UART stm32F3_2

Меня тут заругали вчера что я лезу с своими тупыми вопросами и т.д. Вроде как разрешили тут задать вопрос.

У меня такой код на дисковери 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); 

Мне специалисты на других сайтах говорили, что должно работать. Может тут в другом дело?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

34 minutes ago, Olegus said:

Мне специалисты на других сайтах говорили, что должно работать. Может тут в другом дело?

Должоно без вариантов, если обычные строки передаются через HAL_UART_Transmit. Скорее всего неправильно сконфигурированы библиотеки компилятора.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, Arlleex сказал:

Компилятор какой? IDE?

Работаю в True Studio.  GCC компилятор ( насколько я разобрался).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, Olegus сказал:

Меня тут заругали вчера что я лезу с своими тупыми вопросами и т.д.

Потому что вопросы задаёте совершенно безграмотно. И не в ту ветку.

Цитата

      sprintf(str1,"%.3f\r\n", 1.23);

"1.23" - это double, а в форматной строке указываете "f" - float.

Цитата

        HAL_UART_Transmit(&huart2, (uint8_t*)str1, strlen(str1), 0x1000);

Зачем ещё раз вычислять длину строки, если она уже известна??? :unknw:

Нужно примерно так:

char str1[30];

HAL_UART_Transmit(&huart2, (uint8_t*)str1, sprintf(str1, "%.3f\r\n", 1.23f), 0x1000);

Также нужно в свойствах проекта проверить, что подключен вариант stdlib с поддержкой плавающей точки. О чём вам тут уже не раз сказали.

Цитата

Мне специалисты на других сайтах говорили, что должно работать. Может тут в другом дело?

"специалисты"....  :russian_ru:

 

PS: И изучите возможности этого форума по правильному оформлению вставок исходного кода. Как сделано в этом моём посте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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;
	   
}

 

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

Вот подсказка, о том что советовал @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&amp;t=141&amp;p=3897&amp;hilit=float#p3897

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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&amp;t=141&amp;p=3897&amp;hilit=float#p3897

Установил в Tool Setting моей ID  Runtime library    Newlib standart    вместо   Newlib Nano.  И все заработало (все варианты кода которые я пробовал) . Всем спасибо.  Особое спасибо Lagman, ссылки оказались те, что надо.                                       

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 часов назад, jenya7 сказал:

  sprintf монстр жрущий ресурсы.

Ну-ну... Вы бы сначала что-то своё, не кривое придумали, прежде чем нормально работающее ругать...

Цитата

я делаю так

  Скрыть контент


        while (ap)
        {
            fpart *= 10;
            ap--;
        }

 

 

А ничего, что в этом "алгоритме" из-за множественных умножений float-а и накапливающихся на них ошибках округления, иногда (очень редко) в результирующей строке будет совсем не то, что в исходном числе?

Это даже не говоря о том, что кроме вещественных чисел, float может содержать и другие значения, которые вы игнорируете....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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];

   ...

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

49 минут назад, x893 сказал:

 fpart *= after[afterpoint];

Хотя бы так. Осталось ещё о NaN,INF позаботиться.... и получим sprintf()  :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а куда передается то? может быть с помощью union разбить флоат на 4 байта, а на принимающей стороне обратно собрать? или надо именно в терминал?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...