• 嵌入式 printf的实现


    在嵌入式中,经常需要用到printf来调试程序

    标准库函数的默认输出设备是显示器,要实现在串口或LCD输出,必须重定义标准库函数里调用的与输出设备相关的函数.

    printf输出到串口,需要将fputc里面的输出指向串口(重定向)

    因此,实现printf就需要重定向相关的函数。有的时候,我们想自己实现printf的功能,不妨自己写一个

    #include <stdarg.h>
    #include <stdio.h>
    #include <unistd.h>
    
    #define BUFSIZE  1024
    char myprintf_buf[BUFSIZE];
    
    
    void Debug_printf(const char* fmt, ...)
    {
        va_list args;
        int n;
    
        va_start(args, fmt);
        n = vsnprintf(myprintf_buf, BUFSIZE, fmt, args);
        va_end(args);
        int i = 0;
        for(i = 0; i < n; i++)
        {
           HAL_UART_Transmit(&huart2, (uint8_t *)&myprintf_buf[i], 1, 0xFFFF); //根据不同的平台,修改串口输出的函数
        }
    }
    
    int main(void)
    {
        Debug_printf("test %d
    ", 100);
        return 0;
    }

    方法二:

    #include <stdarg.h>
    #include <stdio.h>
    #include <string.h>
    static unsigned long m_pow(int x,int y)
    {
          unsigned long sum = 1;
          while(y--)
          {
                sum *= x;
          }
          return sum;
    }
    //打印字符​
    void m_putchar(const char ch)
    {
          HAL_UART_Transmit(&huart2, (uint8_t *)ch, 1, 0xFFFF);
    }
    //打印字符串
    void m_putstr(const char *str)
    {
          while(*str)
          {
                m_putchar(*str++);
          }
    }
    int printint(const int dec)
    {
          int count = 0, ret = 0;
          int r_val = dec;
          char ch;
          while(r_val)
          {
                count++;
                r_val /= 10;
          }
          ret = count;
          r_val = dec;
          while(count)
          {
                ch = r_val / m_pow(10, count - 1);
                r_val %= m_pow(10, count - 1);
                m_putchar(ch + '0');
                count--;
          }
          return ret;
    }
    int printfloat(const float flt)
    {
       int countint = 0,countflt = 0;
              int count = 0, r_val = 0;
          int tmpint = (int)flt;
          int tmpflt = (long int)(10000000 * (flt - tmpint));
       if(tmpflt % 10 >= 5)
          {
                tmpflt = tmpflt / 10 + 1;
          }
          else
          {
                tmpflt = tmpflt / 10;
          }
              r_val = tmpflt;
              count = 0;
              while(r_val)
          {
                count++;
                r_val /= 10;
          }
        
          countint = printint(tmpint);
          m_putchar('.');
            
              int i = 0;
              for(i = 0; i < 6 - count; i++)
              {
                    m_putchar('0');
              }
          countflt = printint(tmpflt);
      return countint + 1 + count + countflt;
    }
    int m_printf(const char *str,...)
    {
        va_list ap;
        int val,r_val;
        float val_float;
        char count,ch;
        char *s = NULL;
        int res = 0;
        va_start(ap, str);
        while('' != *str)
        {
         switch(*str)
          {
          case '%':
           str++;
           switch(*str)
           {
           case 'd':
             val = va_arg(ap, int);
               count = printint(val);
               res += count;
               break;
            case 'x':
               val = va_arg(ap, int);
               r_val = val;
               count = 0;
               while(r_val)
               {
                 count++;
                 r_val /= 16;
               }
               res += count;
               r_val = val;
               while(count)
               {
                 ch = r_val / m_pow(16, count - 1);
                  r_val %= m_pow(16, count - 1);
                   if(ch <= 9)
                     m_putchar(ch + '0');
                   else
                     m_putchar(ch - 10 + 'a');
                   count--;
                }
                break;
             case 'f':
               val_float = va_arg(ap, double);
               count = printfloat(val_float);
               res += count;
               break;
             case 's':
               s = va_arg(ap, char*);
               m_putstr(s);
               res += strlen(s);
               break;
             case 'c':
               m_putchar((char)va_arg(ap, int));
               res += 1;
               break;
             default:
              ;
             }
             case '
    ':
              m_putchar('
    ');
              res += 1;
              break;
             case '
    ':
              m_putchar(*str);
              res += 1;
              break;
             default:
              m_putchar(*str);
              res += 1;
             }
             str++;
         }
         va_end(ap);
         return res;
    }
     
    int main(void)
    {
        char buf[64];
        m_printf("======== begin test =========
    ");
        snprintf(buf, sizeof(buf), "%s %f", "hello world", 20.043);
        m_printf("%s
    ", buf);
        return 0;
    }
  • 相关阅读:
    教你一招Linux下文本比对方法
    Linux下find与exec的联手干大事
    Linux下Shell日期的格式,你知道几种?
    Linux下Python3.6的安装及避坑指南
    多线程中使用CompletableFuture
    ElasticSearch7.6.2中语法使用(更新中)
    ElasticSearch7.6.2使用_update_by_query语法
    ElasticSearch7.6.2使用_delete_by_query产生版本冲突问题
    filebeat7.6.2进程运行一段时间后自动退出问题解决
    把本地项目提交到gitLab
  • 原文地址:https://www.cnblogs.com/birdBull/p/10939597.html
Copyright © 2020-2023  润新知