自己写的printf函数

估计很多嵌入式开发上会用到printf这个函数,这个函数可以很方便地查看寄存器内容,程序运行流程等信息。曾经在ADS1.2里面这样来实现过printf函数:


#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

//=====================================================================
//If you don't use vsprintf(), the code size is reduced very much.
void Uart_Printf(char *fmt,...)
{
    va_list ap;
    char string[256];

    va_start(ap,fmt);
    vsprintf(string,fmt,ap);
    Uart_SendString(string);
    va_end(ap);
}


则个是samsung给的2410的测试代码来实现printf。


编译后可以发现,大小为200K之多。如果用在DSP和单片机上,可能就不合适了。也正是因为如此,自己写了一个简易的printf函数,之所以说他简易,是因为只实现了 %d %x %s这些参数的打印功能。不过这也够用了。下面是函数代码:


 

char *itoa(int value, char *string, int radix)
{
    int     i, d;
    int     flag = 0;
    char    *ptr = string;

    /* This implementation only works for decimal numbers. */
    if (radix != 10)
    {
        *ptr = 0;
        return string;
    }

    if (!value)
    {
        *ptr++ = 0x30;
        *ptr = 0;
        return string;
    }

    /* if this is a negative value insert the minus sign. */
    if (value < 0)
    {
        *ptr++ = '-';

        /* Make the value positive. */
        value *= -1;
    }

    for (i = 10000; i > 0; i /= 10)
    {
        d = value / i;

        if (d || flag)
        {
            *ptr++ = (char)(d + 0x30);
            value -= (d * i);
            flag = 1;
        }
    }

    /* Null terminate the string. */
    *ptr = 0;

    return string;

} /* NCL_Itoa */
char *utohex(unsigned int value, char *string, int radix)
{
 int     i, d,shift;
 unsigned int cval,mask;
    char    *ptr = string;
 /* This implementation only works for decimal numbers. */
    if (radix != 16)
    {
        *ptr = 0;
        return string;
    }
    i="0";
    shift="12";
 cval=value;
 mask = 0xffff;
    for(i=0;i<4;i++)
    {
     d=cval>>shift;
  cval &= (mask>>(16-shift));
  
     if(d > 9 )
      d = d+0x57;
     else
      d+=0x30;
     string[i]=d;
     
     shift -=4;
     
    }
    
    return string;
 
}
void uprintf(const char *fmt, ...)
{
    const char *s;
    int d,i;
    unsigned int x;
    char buf[16];
    va_list ap;
    va_start(ap, fmt);
    while (*fmt) {
        if (*fmt != '%') 
        {
            uart0_send_char(*fmt++);
            continue;
        }
        switch (*++fmt) {
            case 's':
                s = va_arg(ap, const char *);
                for ( ; *s; s++) {
                    uart0_send_char(*s);
                }
                break;
            case 'd':
                d = va_arg(ap, int);
                itoa(d, buf, 10);
                for (s = buf; *s; s++) {
                    uart0_send_char(*s);
                }
                break;
            case 'x':
                x = va_arg(ap, int);
                utohex(x, buf, 16);
                for (i=0; i<4;i++) {
                    uart0_send_char(buf[i]);
                }
                break;
            /* Add other specifiers here... */              
            default:  
                uart0_send_char(*fmt);
                break;
        }
        fmt++;
    }
    va_end(ap);
    return ;   /* Dummy return value */
}


从节省资源角度出发,每完成一个字符,就调用uart0_send_char()打印出去了,如果资源宽裕的话,当然可以统一打印,类似samsung的代码。utohex()这个函数,实现了unsigned int到hex的转换,只是针对16位的,如果移植到32位机上,需要修改一下。


大家路过了,别忘记留个脚印啊。

转自:http://bbs.ednchina.com/BLOG_ARTICLE_119868.HTM


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值