void CommPrintf( void (*fputc)(CPU_INT08S),const CPU_INT08S *format, ...)
{
static const CPU_INT08S hex[] = "0123456789ABCDEF";
static const CPU_INT32U pulDiv[3][12] =
{
{
01,010,0100,01000,010000,0100000,01000000,010000000,
0100000000,01000000000,010000000000,010000000000,
},
{
1,10,100,1000,10000,100000,1000000,
10000000,100000000,1000000000,1000000000,
},
{
0x1,0x10,0x100,0x1000,0x10000,
0x100000,0x1000000,0x10000000,
},
};
CPU_INT08S c;
CPU_INT08U i,type,wide=0;
CPU_INT08S t;
CPU_INT32U ulDivValue;
CPU_INT32S lParValue;
CPU_INT08S *ptr;
va_list ap;
//DispLock();
va_start (ap, format);
for (;;) /* Until full format string read */
{
while ((c = *format++) != '%') /* Until '%' or '\0' */
{
if (!c)
{
va_end (ap);
//DispUnlock();
return ;
}
fputc(c);
}
switch (c = *format++)
{
default:
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
wide = c-'1';
wide %= 9;//×î¶àÖ»ÓÐ8λ
c = *format++;
switch(c)
{
case 'o':
type = 0;
goto CONVERSION_LOOP;
case 'd':
case 'u':
type = 1;
goto CONVERSION_LOOP;
case 'x':
type = 2;
goto CONVERSION_LOOP;
default:
break;
}
break;
case '%':
fputc('%');
break;
case 'c':
c = va_arg(ap, int);
fputc(c);
break;
case 's':
ptr = va_arg(ap,CPU_INT08S *);
while ((c = *ptr++)!=0)
{
fputc(c);
}
break;
case 'o':
type = 0;
goto CONVERSION_LOOP;
case 'd':
case 'u':
type = 1;
goto CONVERSION_LOOP;
case 'x':
type = 2;
CONVERSION_LOOP:
lParValue = va_arg(ap,int);
if (c == 'd' || c=='u')
{
if ((lParValue) < 0)
{
lParValue = - lParValue;
if(c!='u')
{
fputc('-');
}
}
}
for(t=-1;;)
{
if(lParValue<=pulDiv[type][++t])
{
if(t)
{
t--;
}
break;
}
}
if(t>=wide) //´ËʱºöÂÔwide
{
i=t;
}
else
{
i=wide;
}
do
{
ulDivValue = pulDiv[type];
t=lParValue/ulDivValue;
lParValue -= t*ulDivValue;
fputc(hex[t]);
}while(i--);
wide=0;//ΪÏÂÒ»×÷×¼±¸
}
}
}
注意:此时要调用此函数实现可变要用如下方法,还是举个例子吧
void LcdPrintf(const CPU_INT08S *format, ...)
{
va_list ap;
CPU_INT32U p1,p2,p3;
DispLock();
va_start (ap, format);
p1 = va_arg(ap,CPU_INT32U);//
p2 = va_arg(ap,CPU_INT32U);//
p3 = va_arg(ap,CPU_INT32U);//
CommPrintf(_LcdPutChar,format,p1,p2,p3);
va_end(ap);
DispUnlock();
}
必须要传递p1,p2,p3,否则堆栈会出错
修改后也可以适合其他的编译器和CPU
就如你既要窜口,又要LCD,或者其它的I/O...
就不好配置了,而且不同的编译器要关联需不同的配置,
支持钻研。但是一般编译器都提供putc,putchar……
一类的接口函数的,修改一下即可。
呵
我一般用va_list va_start va_end
再自己写个Senduart
调用时发现错了,好的应该是这样:
void CommPrintf( void (*fputc)(CPU_INT08S),const CPU_INT08S *format, va_list ap)
{
static const CPU_INT08S hex[] = "0123456789ABCDEF";
static const CPU_INT32U pulDiv[3][12] =
{
{
01,010,0100,01000,010000,0100000,01000000,010000000,
0100000000,01000000000,010000000000,010000000000,
},
{
1,10,100,1000,10000,100000,1000000,
10000000,100000000,1000000000,1000000000,
},
{
0x1,0x10,0x100,0x1000,0x10000,
0x100000,0x1000000,0x10000000,
},
};
CPU_INT08S c;
CPU_INT08U i,type,wide=0;
CPU_INT08S t;
CPU_INT32U ulDivValue;
CPU_INT32S lParValue;
CPU_INT08S *ptr;
for (;;) /* Until full format string read */
{
while ((c = *format++) != '%') /* Until '%' or '\0' */
{
if (!c)
{
return ;
}
fputc(c);
}
switch (c = *format++)
{
default:
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
wide = c-'1';
wide %= 9;//×î¶àÖ»ÓÐ8λ
c = *format++;
switch(c)
{
case 'o':
type = 0;
goto CONVERSION_LOOP;
case 'd':
case 'u':
type = 1;
goto CONVERSION_LOOP;
case 'x':
type = 2;
goto CONVERSION_LOOP;
default:
break;
}
break;
case '%':
fputc('%');
break;
case 'c':
c = va_arg(ap, int);
fputc(c);
break;
case 's':
ptr = va_arg(ap,CPU_INT08S *);
while ((c = *ptr++)!=0)
{
fputc(c);
}
break;
case 'o':
type = 0;
goto CONVERSION_LOOP;
case 'd':
case 'u':
type = 1;
goto CONVERSION_LOOP;
case 'x':
type = 2;
CONVERSION_LOOP:
lParValue = va_arg(ap,int);
if (c == 'd' || c=='u')
{
if ((lParValue) < 0)
{
lParValue = - lParValue;
if(c!='u')
{
fputc('-');
}
}
}
for(t=-1;;)
{
if(lParValue<=pulDiv[type][++t])
{
if(t)
{
t--;
}
break;
}
}
if(t>=wide) //´ËʱºöÂÔwide
{
i=t;
}
else
{
i=wide;
}
do
{
ulDivValue = pulDiv[type];
t=lParValue/ulDivValue;
lParValue -= t*ulDivValue;
fputc(hex[t]);
}while(i--);
wide=0;//ΪÏÂÒ»×÷×¼±¸
}
}
}
注意:此时要调用此函数实现可变要用如下方法,还是举个例子吧
void LcdPrintf(const CPU_INT08S *format, ...)
{
va_list ap;
DispLock();
va_start (ap, format);
CommPrintf(_LcdPutChar,format,ap);
va_end(ap);
DispUnlock();
}
修改后也可以适合其他的编译器和CPU
自己写太麻烦了,
找一个完整的拷贝过来就可以用了,
还可以控制浮点数的支持与否,