在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
芯片精品文章合集(500篇!) 创芯人才网--重磅上线啦!
查看: 5030|回复: 1

简易的printf实现

[复制链接]
发表于 2008-5-29 17:57:38 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

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

这个已经发在我的EDN博客上了,大家可以过去看看。
发表于 2010-5-14 14:20:36 | 显示全部楼层
不错,值得参考一下!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-11-25 01:58 , Processed in 0.024963 second(s), 9 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表