You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AVR单片机串口发送double数据异常,如何正确转换为char数组?

解决AVR单片机发送double类型数据到PC的乱码问题

你遇到的乱码问题核心原因很明确:AVR GCC的标准库默认没有启用浮点数格式化支持。因为AVR单片机资源有限,默认的sprintf只实现了整数和字符串的格式化,处理浮点数时会输出无意义的乱码。下面是具体的修复方案和优化代码:

一、启用浮点数格式化支持

AVR的libc提供了带浮点数支持的printf/sprintf版本,但需要在编译时手动指定链接参数来启用:

  • 如果使用命令行编译,添加以下参数:
    -Wl,-u,vfprintf -lprintf_flt
    
  • 如果是Atmel Studio:在项目属性 → 工具链 → AVR/GNU Linker → Miscellaneous里,把上述参数加到"Other flags"中。
  • 如果是PlatformIO:在platformio.ini的build_flags里添加:
    build_flags = -Wl,-u,vfprintf -lprintf_flt
    

二、优化你的代码

除了启用浮点数支持,你的代码还有几个小问题需要调整:

  1. 串口发送函数里的冗余延迟和未清除的TXC标志,可能导致发送异常。
  2. 直接操作UDR发送换行符,没有遵循串口发送的等待逻辑。
  3. 缓冲区大小可以更合理,避免溢出风险。

修改后的完整代码

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>

void print_char(char letter) {
    // 等待发送缓冲区为空
    loop_until_bit_is_set(UCSRA, UDRE);
    UDR = letter;
    // 等待发送完成,并清除TXC标志(通过写1来清除)
    loop_until_bit_is_set(UCSRA, TXC);
    UCSRA |= (1 << TXC);
}

// 新增字符串发送函数,更方便批量发送
void print_string(const char* str) {
    while (*str != '\0') {
        print_char(*str++);
    }
}

int main(void) {
    // 初始化串口:9600波特率,8位数据,1停止位,无校验
    UBRRL = 103;
    UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
    UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);

    double pi = 3.1415;
    char cpi[10]; // 足够容纳格式化后的字符串和终止符

    // 方法1:使用sprintf格式化浮点数
    sprintf(cpi, "%.4f", pi);

    // 方法2:使用AVR专用的dtostrf函数(更可靠的浮点数转字符串)
    // dtostrf(pi, 1, 4, cpi); // 参数:数值、最小宽度、小数位数、目标缓冲区

    while (1) {
        print_string(cpi);
        print_char('\r');
        print_char('\n');
        _delay_ms(1000);
    }
}

三、额外说明:用dtostrf替代sprintf

AVR libc专门提供了dtostrf函数,用于将浮点数转换为字符串,相比sprintf更专注,也能避免一些格式化字符串的坑。它的参数说明:

char *dtostrf(double val, signed char width, unsigned char prec, char *s);
  • val:要转换的浮点数
  • width:输出字符串的最小宽度(不足会补空格,设为1即可)
  • prec:小数部分的位数
  • s:目标字符数组缓冲区

使用这个函数同样需要启用前面提到的浮点数库链接参数。

内容的提问来源于stack exchange,提问作者Mavimix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 17:02:28