This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] LP-MSPM0C1104:如何使用 UART 打印浮点数?

Guru**** 2524460 points
Other Parts Discussed in Thread: MSPM0C1104, MSPM0L1306

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1563167/lp-mspm0c1104-how-to-use-uart-to-print-float-number

器件型号:LP-MSPM0C1104
主题中讨论的其他器件:MSPM0C1104MSPM0L1306

工具/软件:

我下载 uart_rw_multibyte_fifo_poll_LP_MSPM0C1104_nortos_ticlang 示例

可以在 UART 上用 4 个字“msp!“进行打印

如果我有一个 float 变量、

我是否可以通过 UART 进行打印?

如下代码所示。

include <stdio.h>
int main(){
    uint8_t correct_word[4] = {'M', 'S', 'P', '!'};
    DL_UART_Main_fillTXFIFO(UART_0_INST, &correct_word[0], 4);
    while (DL_UART_Main_isBusy(UART_0_INST))
        ;
    // previous is work correctly, show the "MSP!" correct
    // below will be compile ok, but nothing show at UART.
    
    float tmp =23.6f;
    char buffer[50]={0};
    sprintf(buffer, "%4.1f", tmp);
    
    
    DL_UART_Main_fillTXFIFO(UART_0_INST, &buffer[0], 4);
    while (DL_UART_Main_isBusy(UART_0_INST))
        ;
}

我知道、也许我需要像 FTOA 函数这样的东西、或者需要使用浮点支持进行编译、或者

是否有任何提示可以提供给我?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、CK:

    我建议查看这篇文章,看看它是否有助于您的实施: https://software-dl.ti.com/ccs/esd/documents/sdto_cgt_tips_for_using_printf.html

    此致、

    Owen

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Owen、  

    我只读了这篇文章,  

    我重试几种不同的方式、

    #include "ti_msp_dl_config.h"
    #include <stdio.h>
    
    #define ENABLE_LOOPBACK_MODE true
    #define UART_PACKET_SIZE (4)
    
    #define UART_TX_DELAY (160000)
    
    uint8_t txPacket[UART_PACKET_SIZE] = {'M', 'S', 'P', '!'};
    
    int main(void)
    {
        char buffer[50]={0};
        int a = 33;
        sprintf(buffer,"%d",a);
        DL_UART_Main_fillTXFIFO(UART_0_INST, &buffer[0], UART_PACKET_SIZE);
    
        /* Wait until all bytes have been transmitted and the TX FIFO is empty */
        while (DL_UART_Main_isBusy(UART_0_INST))
            ;
    
    //previous code works correctly, will show "33" at UART.
    //below code will stuck at sprintf(buffer, "%4.1f", tmp); no response,
    
    
        float tmp =23.6f;
        buffer[0]=0;
    
        /* Optional delay to ensure UART TX is idle before starting transmission */
        delay_cycles(UART_TX_DELAY);
        sprintf(buffer, "%4.1f", tmp);
        /* Set LED to indicate start of transfer */
        DL_GPIO_clearPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
    
        /* Fills TX FIFO with data and transmits the data */
        DL_UART_Main_fillTXFIFO(UART_0_INST, &buffer[0], UART_PACKET_SIZE);
    
        /* Wait until all bytes have been transmitted and the TX FIFO is empty */
        while (DL_UART_Main_isBusy(UART_0_INST))
            ;
    }

    我想我的失败是 sprintf 不支持“将 float 更改为 char“。

    有没有任何方法可以使它,或者只是不尝试这样编码?  

    我刚刚了解到另一个链接的问题几乎相同、

    MSPM0C1106:如何使用 Keil 启用浮点 printf ();函数输出

    但我读了链接,没有找到 C1104 可以 sprintf 浮到字符或不.

    (或者只是不支持?)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、CK:

    我尝试实施您提供的内容、然后我提出了一个解决方法。 它不适合您的原因很可能是因为 MSPM0C1104 上的存储器限制。 在我发送给您的文档中、建议为栈分配 400 个字节、为堆分配大约 512-1024 个字节。 总的来说、只有一个使用 float 的 printf 可能需要数千个字节。 此 E2E 适用于 MSP430、但仍然与这种情况相关。

    以下是我提出的权变措施:

    float tmp =23.6f;
    int int_part = (int)tmp;
    int frac_part = (int)((tmp - int_part) * 100);
    sprintf(buffer, "%d.%02d", int_part, frac_part);

    这避免了对真正浮点的需求、但仍允许您通过 UART 打印浮点值。

    如果您的解决方案足够、或者您需要进一步的帮助、请告诉我。

    此致、

    Owen

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    snprintf(和朋友)确实需要超过 350B 的堆栈;当它覆盖了我的一些(其他)数据时,我注意到了这一点。 我最后写了一个 ITOA() 等价物。

    我尚未试用 MSPM0 的(软件)浮点库、但我预计成本主要是闪存(代码)空间、而不是 RAM。 C1104 闪存不是那么小,所以它可能是足够的。

    这些都 可以填写 欧文的建议。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Bruce 和 CK、

    澄清一下、该问题与闪存无关。 有足够的闪存来支持 sprintf 函数、但我认为问题在于 sprintf 在执行过程中需要大量的 SRAM 堆栈空间。 假设 MSPM0C1104 只有 1KB SRAM、则堆栈溢出可能是问题。 我尝试在工程设置和链接器文件中调整栈和堆、但我按 Default Handler 步进:

    sprintf(buffer, "%4.1f", tmp);

    我将相同的代码刷写到具有 4KB SRAM 的 MSPM0L1306 中、并且使用 sprintf 转换浮点没有问题。

    我建议使用手动浮动、正如我在上一次答复中分享的那样。

    此致、

    Owen

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我还谈到了 SRAM(堆栈)、并建议根本不使用 snprintf、而是 ioa/ltoa/类似命令。

    我只提到了闪存、因为在您使用的特定示例中(所有编译时常量)、浮点函数可能实际上没有链接进来。

    【编辑:轻微澄清】

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你看,我对这种症状很好奇,所以我试了一下。  

    它是栈溢出;硬故障是由从 SRAM 底部运行的栈(它尝试写入 0x1fffffe0)导致的、即栈占用了所有 RAM、然后部分 RAM。

    这甚至比我去年看到的更大,所以 (1) 浮动支持将堆栈扩展了很多,或者 (2) 实现同时发生了变化。

    也就是说:我仍然建议不要在 C1104 上使用 snprintf;即使它现在“有效“,因为你的程序增长,它最终不会。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好欧文和布鲁斯,

    非常感谢您解决了我的问题、

    今天之前、我没有意识到 浮点将达到 SRAM 的限制 (1KB)

     尽管欧文提供的代码工作正常(单独显示 int_part 和 frac_part )。

    我认为最好的解决方案是尝试将原始数据传递到另一个设备单元、不要以 1104 自身的 UART 显示、

    尝试使 1104-self UART 简单地工作。(虽然当前 sprintf 工作正常在 int 部分现在)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我知道您已经关闭了这个主题、但我想我会添加更多(未经请求)发现:我创建了一个“dummy".bss 数“ 数组、该数组将未使用的 SRAM(在数据顶部和(标称)栈底部之间)填充为 0x55、然后逐步执行该程序。

    1) sprintf(“%d") 调用“ 调用似乎使用了>840 字节的栈,即仅为简单的情况使用了 80%的 SRAM。 只要您的其他数据很少、这将“有效“。

    2) 我们假设 sprintf(“%f") 调用“ 调用的 1K 的其余部分 已与浮点库的栈一起使用(由 TI_printfi () 使用)。 format.h 定义了一个符号 float_value_BUFSIze=100、这也可能是此符号的一部分。

    3) 栈使用量由单个栈变量“char fld[FORMAT_CONVERSION_BUFSIZE]“主导 、其大小为 510 字节。 它由 0x20-s 初始化、因此在 Memory Browser 中脱颖而出。 format.h 中的注释指出“符合 C89 标准的最小最大转换大小为 509 “。 我记得这个变量更像 250 字节,但我的内存经常是错误的。

    4) 我没有找到在替代 printf() 实现之间进行选择的构建设置。 printfi.c 源似乎只是区分最小值、MSP430 和 。

    5) ltoa() 似乎在 libc.a 中、但不在 ftoa() 或 itoa() 中。 ltoa() 在欧文的“分割成整数“方法中很有用。 (我编写了自己的 ltoa () 等效 代码,因为 ltoa () 没有数组边界检查。