[MM32软件] MMF103 中 printf.c 对Printf 的实现

[复制链接]
 楼主| stm32jy 发表于 2020-3-30 20:48 | 显示全部楼层 |阅读模式

此例程将pad字符放入输出缓冲区
  1. static void padding( const int l_flag, params_t *par)
  2. {
  3.     int i;

  4.     if (par->do_padding && l_flag && (par->len < par->num1))
  5.         for (i = par->len; i < par->num1; i++)
  6.             outbyte( par->pad_character);
  7. }


 楼主| stm32jy 发表于 2020-3-30 20:50 | 显示全部楼层
此例程按照填充和定位标志的指示将字符串移动到输出缓冲区
  1. static void outs( charptr lp, params_t *par)
  2. {
  3.     /* pad on left if needed                         */
  4.     par->len = strlen( lp);
  5.     padding( !(par->left_flag), par);

  6.     /* Move string to the buffer                     */
  7.     while (*lp && (par->num2)--)
  8.         outbyte( *lp++);

  9.     /* Pad on right if needed                        */
  10.     /* CR 439175 - elided next stmt. Seemed bogus.   */
  11.     /* par->len = strlen( lp);                       */
  12.     padding( par->left_flag, par);
  13. }


 楼主| stm32jy 发表于 2020-3-30 20:51 | 显示全部楼层
此例程按照填充和定位标志的指示将数字移动到输出缓冲区
  1. static void outnum( const long n, const long base, params_t *par)
  2. {
  3.     charptr cp;
  4.     int negative;
  5.     char outbuf[32];
  6.     const char digits[] = "0123456789ABCDEF";
  7.     unsigned long num;

  8.     /* Check if number is negative                   */
  9.     if (base == 10 && n < 0L)
  10.     {
  11.         negative = 1;
  12.         num = -(n);
  13.     }
  14.     else
  15.     {
  16.         num = (n);
  17.         negative = 0;
  18.     }

  19.     /* Build number (backwards) in outbuf            */
  20.     cp = outbuf;
  21.     do
  22.     {
  23.         *cp++ = digits[(int)(num % base)];
  24.     }
  25.     while ((num /= base) > 0);
  26.     if (negative)
  27.         *cp++ = '-';
  28.     *cp-- = 0;

  29.     /* Move the converted number to the buffer and   */
  30.     /* add in the padding where needed.              */
  31.     par->len = strlen(outbuf);
  32.     padding( !(par->left_flag), par);
  33.     while (cp >= outbuf)
  34.         outbyte( *cp--);
  35.     padding( par->left_flag, par);
  36. }


 楼主| stm32jy 发表于 2020-3-30 20:52 | 显示全部楼层
从格式字符串中获取一个数字
  1. static int getnum( charptr* linep)
  2. {
  3.     int n;
  4.     charptr cp;

  5.     n = 0;
  6.     cp = *linep;
  7.     while (isdigit(*cp))
  8.         n = n * 10 + ((*cp++) - '0');
  9.     *linep = cp;
  10.     return(n);
  11. }


 楼主| stm32jy 发表于 2020-3-30 20:53 | 显示全部楼层
主角登场 串口printf打印函数
  1. void uart_printf( const charptr ctrl1, ...)
  2. {

  3.     int long_flag;
  4.     int dot_flag;

  5.     params_t par;

  6.     char ch;
  7.     va_list argp;
  8.     charptr ctrl = ctrl1;

  9.     va_start( argp, ctrl1);

  10.     for ( ; *ctrl; ctrl++)
  11.     {

  12.         /* move format string chars to buffer until a  */
  13.         /* format control is found.                    */
  14.         if (*ctrl != '%')
  15.         {
  16.             outbyte(*ctrl);
  17.             continue;
  18.         }

  19.         /* initialize all the flags for this format.   */
  20.         dot_flag   = long_flag = par.left_flag = par.do_padding = 0;
  21.         par.pad_character = ' ';
  22.         par.num2 = 32767;

  23. try_next:
  24.         ch = *(++ctrl);

  25.         if (isdigit(ch))
  26.         {
  27.             if (dot_flag)
  28.                 par.num2 = getnum(&ctrl);
  29.             else
  30.             {
  31.                 if (ch == '0')
  32.                     par.pad_character = '0';

  33.                 par.num1 = getnum(&ctrl);
  34.                 par.do_padding = 1;
  35.             }
  36.             ctrl--;
  37.             goto try_next;
  38.         }

  39.         switch (tolower(ch))
  40.         {
  41.             case '%':
  42.                 outbyte( '%');
  43.                 continue;

  44.             case '-':
  45.                 par.left_flag = 1;
  46.                 break;

  47.             case '.':
  48.                 dot_flag = 1;
  49.                 break;

  50.             case 'l':
  51.                 long_flag = 1;
  52.                 break;

  53.             case 'd':
  54.                 if (long_flag || ch == 'D')
  55.                 {
  56.                     outnum( va_arg(argp, long), 10L, &par);
  57.                     continue;
  58.                 }
  59.                 else
  60.                 {
  61.                     outnum( va_arg(argp, int), 10L, &par);
  62.                     continue;
  63.                 }
  64.             case 'x':
  65.                 outnum((long)va_arg(argp, int), 16L, &par);
  66.                 continue;

  67.             case 's':
  68.                 outs( va_arg( argp, charptr), &par);
  69.                 continue;

  70.             case 'c':
  71.                 outbyte( va_arg( argp, int));
  72.                 continue;

  73.             case '\\':
  74.                 switch (*ctrl)
  75.                 {
  76.                     case 'a':
  77.                         outbyte( 0x07);
  78.                         break;
  79.                     case 'h':
  80.                         outbyte( 0x08);
  81.                         break;
  82.                     case 'r':
  83.                         outbyte( 0x0D);
  84.                         break;
  85.                     case 'n':
  86.                         outbyte( 0x0D);
  87.                         outbyte( 0x0A);
  88.                         break;
  89.                     default:
  90.                         outbyte( *ctrl);
  91.                         break;
  92.                 }
  93.                 ctrl++;
  94.                 break;

  95.             default:
  96.                 continue;
  97.         }
  98.         goto try_next;
  99.     }
  100.     va_end( argp);
  101. }


您需要登录后才可以回帖 登录 | 注册

本版积分规则

44

主题

1118

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部

44

主题

1118

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部