自己写的printf函数

来源:互联网 发布:叁度装饰预算软件 编辑:程序博客网 时间:2024/05/16 11:39

估计很多嵌入式开发上会用到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