[STM32F3] sprintf 的 %f 浮点数格式无法正常工作

[复制链接]
梧桐uuu 发表于 2025-8-19 10:46 | 显示全部楼层 |阅读模式

代码中 sprintf 的 %f 浮点数格式无法正常工作,输出了一些垃圾值。%u 和 %d 在 sprintf 中工作正常,但 %f 在我的代码中输出了垃圾值。代码如下。

float Channel_5_Volt;
Channel_5_Volt = ((float)Adc_5_Data/4095)*3.3;
sprintf(Buf,"adc0 %f \r\n", Channel_5_Volt);
HAL_UART_Transmit(&huart1,Buf, sizeof(Buf), 100);

duo点 发表于 2025-8-19 11:31 | 显示全部楼层
默认情况下,嵌入式 C 库可能未启用浮点数支持。
onlycook 发表于 2025-8-19 11:32 | 显示全部楼层
可能是链接器未链接浮点库。
七毛钱 发表于 2025-8-19 11:33 | 显示全部楼层
如果 MCU 支持硬件浮点,但未在编译选项中启用,可能导致浮点运算异常。
内政奇才 发表于 2025-8-19 11:33 | 显示全部楼层
启用 newlib-nano 的浮点格式化支持。
海滨消消 发表于 2025-8-19 11:34 | 显示全部楼层
检查链接器配置,确保链接器未排除浮点库。
豌豆爹 发表于 2025-8-19 11:34 | 显示全部楼层
替换为 snprintf 或 vsnprintf。
麻花油条 发表于 2025-8-19 11:35 | 显示全部楼层
newlib-nano 默认未启用 %f 支持,或链接器未链接浮点库。
豌豆爹 发表于 2025-8-19 11:35 | 显示全部楼层
添加 -u _printf_float 和 -lm 编译选项,启用硬件 FPU如适用。
macpherson 发表于 2025-8-19 22:47 | 显示全部楼层
精简版的 C 库默认不包含对浮点数格式化
vivilyly 发表于 2025-8-20 07:30 | 显示全部楼层
支持浮点数的 stdio 库。              
zerorobert 发表于 2025-8-20 14:28 | 显示全部楼层
标准 C 库               
jonas222 发表于 2025-8-20 15:48 | 显示全部楼层
使用 snprintf 或 vsnprintf
yorkbarney 发表于 2025-8-20 16:50 | 显示全部楼层
用整数运算替代浮点数输出              
averyleigh 发表于 2025-8-20 17:26 | 显示全部楼层
缺少浮点数支持库              
51xlf 发表于 2025-8-20 18:15 | 显示全部楼层
char Buf[64];  // 确保缓冲区足够大
wilhelmina2 发表于 2025-8-20 20:20 | 显示全部楼层
手动启用浮点数支持。              
jimmhu 发表于 2025-8-20 20:40 | 显示全部楼层
void float_to_string(char *str, float f, int precision) {
    long p[] = {0,10,100,1000,10000,100000,1000000,10000000,100000000};
   
    char *ptr = str;
    char *p1;
    char *p2;
    unsigned long tmp;

    // 处理负数
    if (f < 0) {
        *ptr++ = '-';
        f = -f;
    }

    // 1. 处理整数部分
    tmp = (unsigned long)f;
    // 将整数部分转换为字符串并放入缓冲区
    // 这里用一个简单的递归或循环来实现,为了简化,我们假设有一个整数转字符串的函数
    // 或者直接用 sprintf 处理整数部分 (MicroLIB支持 %d)
    ptr += sprintf(ptr, "%lu", tmp);

    // 2. 处理小数部分
    if (precision > 0) {
        *ptr++ = '.'; // 添加小数点

        // 计算小数部分
        f -= (float)tmp;
        tmp = roundf(f * p[precision]); // 四舍五入到指定精度

        // 处理小数部分前导0的情况 (例如 0.05)
        if (tmp < p[precision-1]) {
            // 计算需要补多少个0
            int leading_zeros = precision - 1;
            unsigned long temp = tmp;
            while (temp >= 10) {
                temp /= 10;
                leading_zeros--;
            }
            for(int i = 0; i < leading_zeros; i++) {
                *ptr++ = '0';
            }
        }
        
        // 将小数部分转换为字符串
        ptr += sprintf(ptr, "%lu", tmp);
    }
   
    *ptr = '\0'; // 字符串结束符
}
jkl21 发表于 2025-8-20 21:26 | 显示全部楼层
增加缓冲区大小              
macpherson 发表于 2025-8-21 15:42 | 显示全部楼层
可尝试使用printf重定向到UART并验证硬件连接。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

40

主题

42

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部