嵌入式 printf的实现
阅读原文时间:2023年07月11日阅读:1

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

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

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

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

#include
#include
#include

#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 = ;  
for(i = ; i < n; i++)  
{  
   HAL\_UART\_Transmit(&huart2, (uint8\_t \*)&myprintf\_buf\[i\], , 0xFFFF); //根据不同的平台,修改串口输出的函数  
}  

}

int main(void)
{
Debug_printf("test %d\r\n", );
return ;
}

方法二:

#include
#include
#include
static unsigned long m_pow(int x,int y)
{
  unsigned long sum = ;
  while(y--)
  {
    sum *= x;
  }
  return sum;
}
//打印字符​
void m_putchar(const char ch)
{
  HAL_UART_Transmit(&huart2, (uint8_t *)ch, , 0xFFFF);
}
//打印字符串
void m_putstr(const char *str)
{
  while(*str)
  {
    m_putchar(*str++);
  }
}
int printint(const int dec)
{
  int count = , ret = ;
  int r_val = dec;
  char ch;
  while(r_val)
  {
    count++;
    r_val /= ;
  }
  ret = count;
  r_val = dec;
  while(count)
  {
    ch = r_val / m_pow(, count - );
    r_val %= m_pow(, count - );
    m_putchar(ch + '');
    count--;
  }
  return ret;
}
int printfloat(const float flt)
{
  int countint = ,countflt = ;
  int count = , r_val = ;
  int tmpint = (int)flt;
  int tmpflt = (long int)( * (flt - tmpint));
  if(tmpflt % >= )
  {
    tmpflt = tmpflt / + ;
  }
  else
  {
    tmpflt = tmpflt / ;
  }
  r_val = tmpflt;
  count = ;
  while(r_val)
  {
    count++;
    r_val /= ;
  }

  countint = printint(tmpint);  
  m\_putchar('.');

      int i = ;  
      for(i = ; i <  - count; i++)  
      {  
            m\_putchar('');  
      }  
  countflt = printint(tmpflt);  

  return countint + + 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 = ;
va_start(ap, str);
while('\0' != *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 = ;
while(r_val)
{
  count++;
  r_val /= ;
}
res += count;
r_val = val;
while(count)
{
  ch = r_val / m_pow(, count - );
  r_val %= m_pow(, count - );
if(ch <= )
  m_putchar(ch + '');
else
  m_putchar(ch - + '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 += ;
break;
default:
 ;
}
case '\n':
 m_putchar('\n');
 res += ;
 break;
case '\r':
 m_putchar(*str);
 res += ;
 break;
default:
 m_putchar(*str);
 res += ;
 }
 str++;
 }
 va_end(ap);
 return res;
}

int main(void)
{
char buf[];
m_printf("======== begin test =========\n");
snprintf(buf, sizeof(buf), "%s %f", "hello world", 20.043);
m_printf("%s\n", buf);
return ;
}