Jump to content
    

Как передать дробное число по 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); 

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

Share this post


Link to post
Share on other sites

34 minutes ago, Olegus said:

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

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

Share this post


Link to post
Share on other sites

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

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

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

Share this post


Link to post
Share on other sites

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: И изучите возможности этого форума по правильному оформлению вставок исходного кода. Как сделано в этом моём посте.

Share this post


Link to post
Share on other sites

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 by jenya7

Share this post


Link to post
Share on other sites

 

Вот подсказка, о том что советовал @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

Share this post


Link to post
Share on other sites

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, ссылки оказались те, что надо.                                       

Share this post


Link to post
Share on other sites

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

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

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

Цитата

я делаю так

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


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

 

 

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

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

Share this post


Link to post
Share on other sites

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

   ...

}

Share this post


Link to post
Share on other sites

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

 fpart *= after[afterpoint];

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...