用串口实现简单的printf函数

       在VC6中,打开printf函数的源代码,发现这个函数的代码量无比巨大,闲来无事,自己用C写了一个简单的printf函数,只实现了VC库中printf函数的部分简单功能,贴出自己写的代码只为抛砖引玉,娱人娱己,仅此而已!

     printf.h  头文件
#ifndef _prinrf_h
#define _printf_h
#include "uart.h"
typedef  char *  va_list;
#define  maxparments   128
#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )  //保证是4字节对齐

#define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )
  /*如果定义了两个表达式,先计算表达式1,再计算表达式2,返回表达式2的值*/

#define va_arg(ap,t)    ( ap =ap+ _INTSIZEOF(t),*(t *)(ap- _INTSIZEOF(t)))   
#define va_end(ap)      ( ap = (va_list)0 )


int printf_test(void);
int outc(char c,unsigned char w);
int outs(va_list p);
int va_printf(const char* fmt,char* p);
int printf( const char* format,...);
int out_num(int m,int base,unsigned char c,unsigned char w);
//int out_float(float m,unsigned char c,unsigned char w,unsigned char wd);

#endif

printf.c文件
#include "printf.h"
unsigned char temp[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
int outc(char c,unsigned char w)                           //输出字符
{     unsigned char i;
     for(i=1;i<w;i++)

putchar(' ');
      }
  putchar(c);
return 0;
}


int outs(va_list p)                                                                  //输出字符串
{   
     puts( p);
return 0;
}


int out_num( int m,int base,unsigned char c,unsigned char w)   //输出数字
{     unsigned int n;
      unsigned char buf[maxparments],count=0,i;
unsigned char *s = (unsigned char *)buf+sizeof(buf);

*--s=' ';
if(m<0)
n=-m;
else 
n=m;
do
{
          *--s=temp[n%base];
n=n/base;
          count++;
}while(n!=0);
 
for(i=1;i<=(w-count);i++)
{
*--s=c;
      }
if(m<0)
*--s='-';
outs(s);
return 0;
}
int va_printf(const char* fmt,char* p)
{     
    while(*fmt!='\0')
      {
               unsigned char width=0;           //总位宽
unsigned char width_decimal=0;   //小数位宽
unsigned char lead=' ';          //默认前导为空格
if(*fmt=='%')                    
                {
fmt++;
if(*fmt=='0')
{
 lead='0';
 fmt++;
     } 
while((*fmt>='0')&&(*fmt<='9'))       //得到总位宽
{
width=width*10;
width=width+(*fmt)-'0';
fmt++;
              }
if(*fmt=='.')                          //得到小数位宽
    {
       fmt++;
                                 while((*fmt>='0')&&(*fmt<='9'))
    {
width_decimal=width_decimal*10;
width_decimal=width_decimal+(*fmt)-'0';
fmt++;
                }
    }
switch(*fmt)                           //调用相应的函数
  {
    case  'd': out_num(va_arg(p,int),10,lead,width); break;
  case  'o': out_num(va_arg(p,unsigned int),8,lead,width); break;
case  'x': out_num(va_arg(p,unsigned int),16,lead,width) ;break;
case  'c': outc(va_arg(p,int),width); break;
case  's': outs(va_arg(p,char *)); break;
//case 'f': out_float(va_arg(p,float),lead,width,width_decimal); break;
default: outc(*fmt,1); break;
        }
}
               else putchar(*fmt);
    fmt++;


    }
 return 0;  
}


int printf(const char* format,...)
{
     va_list apt;
va_start(apt,format);
va_printf(format,apt);
va_end(apt);
     return 0;
}

  int printf_test()                          //测试函数
   {   
printf("test char           =%c,%c\n\r", 'A','a') ;
printf("test decimal number =%d\n\r",    123456) ;
printf("test decimal number =%d\n\r",    -123456) ;
printf("test hex     number =0x%x\n\r",  0x55aa55aa) ;
printf("num=%08d\n\r",   12345);
printf("num=%8d\n\r",    12345);
printf("num=0x%08x\n\r", 0x12345);
printf("num=0x%8x\n\r",  0x12345);
printf("num=0x%02x\n\r", 0x1);
printf("num=0x%2x\n\r",  0x1);
printf("num=%05d\n\r", 0x1);
printf("num=%5d\n\r",  0x1);
        return 0;

}

main函数:

#include "s3c2440_reg.h"
#include "uart.h"
#include "printf.h" 
int  main()
{
uart_init0();
puts("Hello CSDN!\n\r");
       printf_test();
return 0;

}

串口初始化程序请自行按照S3C2440数据手册编写!十分简单!

笔者的实验平台为JZ2440,下载后验证通过!



   

猜你喜欢

转载自blog.csdn.net/u014069939/article/details/80713891