估计很多嵌入式开发上会用到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条评论)
登录后参与讨论