C51单片机自实现printf函数

来源:互联网 发布:金蝶进销存软件多少钱 编辑:程序博客网 时间:2024/06/13 19:32
单片机串口是我们调试的利器,printf函数相信谁都用过,在51单片机中如何实现呢,有人也许会说串口的重定向,直接用printf就可以通过串口格式化打印了。 
为了学习,在这里我实现了一个类似Linux的内核的printk函数,可以格式化打印为%d,%U%S%C,%X,%X。 

代码如下:

/* 实现类似Linux内核的printk函数*/void printk(const char *pstr, ...){char switchN=0;char* argc=NULL;//char point to a stringchar  argchar = 0;int argint=0;  //int unsigned int arguint=0;   //unsigned int//doubleargdouble = 0.0;va_list ap;//可变参数指针 void* apva_start(ap,pstr);//初始化指针ap=...while( *pstr != '\0'){while( (*pstr != '%') && ( *pstr != '\0') )//查找第一个%后面的格式符uart_send(*pstr++);if( *pstr == '\0' ) //结束时{va_end(ap);//清除apreturn;   //退出函数}switch(*(++pstr)){case 'd': argint = va_arg(ap,int); //有符号十进制  if(argint<0)  {  uart_send('-');argint = -argint;  }  if( (argint/10000) != 0 )  switchN=5;  else if( (argint%10000/1000) != 0 )  switchN=4;  else if( (argint%10000%1000/100) != 0 )  switchN=3;  else if( (argint%10000%1000%100/10) != 0 )  switchN=2;  elseswitchN=1;    switch(switchN)  {  case 5:uart_send('0' + argint/10000);  case 4:uart_send('0' + argint%10000/1000);  case 3:uart_send('0' + argint%10000%1000/100);  case 2:uart_send('0' + argint%10000%1000%100/10);  case 1:uart_send('0' + argint%10000%1000%100%10);break;  }  break; case 'u': arguint = va_arg(ap,unsigned int);//无符号十进制  if( (arguint/10000) != 0 )    switchN=5;  else if( (arguint%10000/1000) != 0 )  switchN=4;  else if( (arguint%10000%1000/100) != 0 )  switchN=3;  else if( (arguint%10000%1000%100/10) != 0 )  switchN=2;  elseswitchN=1;    switch(switchN)  {  case 5:uart_send('0' + arguint/10000);  case 4:uart_send('0' + arguint%10000/1000);  case 3:uart_send('0' + arguint%10000%1000/100);  case 2:uart_send('0' + arguint%10000%1000%100/10);  case 1:uart_send('0' + arguint%10000%1000%100%10);break;  }  break;  case 's': argc = va_arg(ap,char*);//字符串  argchar  while(*argc != '\0')  uart_send(*argc++);  break;case 'c': argchar = va_arg(ap,char);//字符串  uart_send(argchar);  break;case 'x': case 'X': uart_send('0' + 0);  uart_send('x');  arguint = va_arg(ap,unsigned int);//十六进制输出 XXXX XXXX XXXX XXXX  for(argint=0;argint<4;argint++)  {  switchN = (unsigned char)((arguint & 0xf000)>>12);if(switchN>9 && switchN<16)//0-9 a-f{switch(switchN){case 10:switchN='A';break;case 11:switchN='B';break;case 12:switchN='C';break;case 13:switchN='D';break;case 14:switchN='E';break;case 15:switchN='F';break;}uart_send(switchN);}elseuart_send('0' + switchN);arguint<<=4;  }  break;}pstr++;}if( *pstr == '\0' ) //结束时va_end(ap);//清除ap}

0 0
原创粉丝点击