打印

适合arm的通用的printf,只要提供putc函数就可..

[复制链接]
3740|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lixun00|  楼主 | 2008-8-28 17:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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
沙发
王紫豪| | 2008-8-28 18:07 | 只看该作者

太复杂,眼疼

使用特权

评论回复
板凳
xwj| | 2008-8-28 18:31 | 只看该作者

什么意思? printf还用自己写???

使用特权

评论回复
地板
lixun00|  楼主 | 2008-8-28 18:31 | 只看该作者

是有点,不过用起来爽

使用特权

评论回复
5
lixun00|  楼主 | 2008-8-28 18:36 | 只看该作者

就如你既要窜口,又要LCD,或者其它的I/O...

就不好配置了,而且不同的编译器要关联需不同的配置,

使用特权

评论回复
6
mohanwei| | 2008-8-28 18:45 | 只看该作者

支持钻研。但是一般编译器都提供putc,putchar……

一类的接口函数的,修改一下即可。

使用特权

评论回复
7
yjgyiy| | 2008-8-28 22:10 | 只看该作者

我一般用va_list va_start va_end 
再自己写个Senduart

使用特权

评论回复
8
lixun00|  楼主 | 2008-10-3 03:16 | 只看该作者

调用时发现错了,好的应该是这样:

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

使用特权

评论回复
9
walnutcy| | 2008-10-4 12:32 | 只看该作者

自己写太麻烦了,

找一个完整的拷贝过来就可以用了,

还可以控制浮点数的支持与否,

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

56

主题

683

帖子

3

粉丝