printf--适合00x小容量芯片使用的浮点打印库

在使用003等小容量芯片时,经常也会有浮点数打印需求,但编译器自带浮点库大概需要十几K的

flash,对于003本身就只有16K  flash的芯片来说,那就用不了了。

下面介绍怎么自己自定义一个%f 浮点数打印函数

注:整体思路就是将浮点数转换成字符串输出。

涉及到的头文件

#include "my_printf.h"
#include <stdarg.h>
#include <string.h>  
#include "debug.h"

 

(1) 浮点数转字符串函数 ftoa

void ftoa(float num, char *buf) {
    char *ptr = buf;

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

    // 提取整数部分
    int integer = (int)num;
    float decimal = num - integer;

    // 整数部分转换为字符串
    char int_buf[16];
    char *p = int_buf + sizeof(int_buf) - 1;
    *p = '\0';

    do {
        *--p = '0' + (integer % 10);
        integer /= 10;
    } while (integer > 0);

    // 复制整数部分到输出缓冲区
    while (*p) *ptr++ = *p++;

    // 添加小数点
    *ptr++ = '.';

    // 提取小数部分(最多6位)
    for (int i = 0; i < 6; i++) {
        decimal *= 10;
        int digit = (int)decimal;
        *ptr++ = '0' + digit;
        decimal -= digit;
    }

    *ptr = '\0';  // 结束符
}

(2) 自定义 printf 函数

void my_printf(const char *fmt, ...) {
    va_list args;
    va_start(args, fmt);
    char buffer[32];  // 确保足够存放浮点字符串

    while (*fmt) {
        if (*fmt == '%' && *(fmt + 1) == 'f') {
            fmt += 2;
            float num = va_arg(args, double);  // float在变参中提升为double
            ftoa(num, buffer);
            uart_send_str(buffer);
        } else {
            uart_send_char(*fmt++);
        }
    }
    va_end(args);
}

(3) 硬件适配:串口输出

void uart_send_char(char c) {
    // 例如:ARM Cortex-M 的 UART 发送函数
    while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
    USART_SendData(USART1, c);
}

// 发送字符串
void uart_send_str(const char *s) {
    while (*s) {
        uart_send_char(*s++);
    }
}

(3) 测试

 

 
posted @ 2025-05-28 17:26  WCH_CH32  阅读(145)  评论(0)    收藏  举报