原创 简易的printf实现

2008-5-29 17:48 4673 8 8 分类: MCU/ 嵌入式

估计很多嵌入式开发上会用到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=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);
                }
                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位机上,需要修改一下。


 


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


 

文章评论0条评论)

登录后参与讨论
我要评论
0
8
关闭 站长推荐上一条 /2 下一条