在嵌入式中,经常需要用到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 = ;
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 <stdarg.h>
#include <stdio.h>
#include <string.h>
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 ;
}

嵌入式 printf的实现的更多相关文章

  1. 嵌入式 printf函数

    来自:https://www.cnblogs.com/02xiaoma/archive/2012/06/22/2558618.html #include <stdio.h> #includ ...

  2. OpenCL Hello World

    ▶ OpenCL 的环境配置与第一个程序 ● CUDA 中自带 OpenCL 需要的头文件和库,直接拉近项目里边去就行:AMD 需要下载 AMD APP SDK(https://community.a ...

  3. 嵌入式操作系统---打印函数(printf/sprintf)的实现

    一.打印函数简介 作用:将“给定的内容”按照“指定的格式”输出到“指定目标内”. 打印函数的基本格式: char print_buf[BUF_SIZE]; void printf(const char ...

  4. [misc]如何在嵌入式平台使用printf功能

    转自:http://www.cnblogs.com/liu_xf/archive/2011/04/14/2015726.html 摘要: 当我们在调试代码时,通常需要将程序中的某个变量打印至PC机上, ...

  5. 嵌入式处理器通过UART实现scanf和printf

    #include <stdint.h> #include <stdarg.h> extern int vsscanf(const char *, const char *, v ...

  6. 学号20145332 《信息安全系统设计基础》实验五 简单嵌入式WEB服务器实验

    实验目的 掌握在 ARM 开发板实现一个简单 WEB 服务器的过程. 学习在 ARM 开发板上的 SOCKET 网络编程. 学习 Linux 下的 signal()函数的使用. 实验内容 学习使用 s ...

  7. 可变参数列表与printf()函数的实现

    问题 当我们刚开始学习C语言的时候,就接触到printf()函数,可是当时"道行"不深或许不够细心留意,又或者我们理所当然地认为库函数规定这样就是这样,没有发现这个函数与普通的函数 ...

  8. 20145216 20145330 《信息安全系统设计基础》 实验五 简单嵌入式WEB 服务器实验

    20145216 20145330 <信息安全系统设计基础> 实验五 简单嵌入式WEB 服务器实验 实验报告封面 实验步骤 1.阅读理解源码 进入/arm2410cl/exp/basic/ ...

  9. sqlite嵌入式数据库C语言基本操作(2)

    :first-child{margin-top:0!important}img.plugin{box-shadow:0 1px 3px rgba(0,0,0,.1);border-radius:3px ...

随机推荐

  1. 顾家办公两不误,容智ibot帮你实现高效居家办公

    春节假期结束,大部分企业已陆续开始复工.经调查显示,受新型冠状病毒疫情影响,不少企业开放了员工“在家办公“模式,就此,员工被动“SOHO”,在家办公火了. 2020 在家办公靠谱吗?会不会成为未来的趋 ...

  2. Spring Boot Thymeleaf 模板引擎的使用

    Spring Boot 中可以支持很多模板引擎,Thymeleaf 是 Spring Boot 官方推荐使用的模板引擎,虽然在社区 Thymeleaf 的性能被许多人所吐糟,但这仍然不影响大量的开发人 ...

  3. Many Formulas

    You are given a string S consisting of digits between 1 and 9, inclusive. You can insert the letter ...

  4. Hibernate学习(二)

    持久化对象的声明周期 1.Hibernate管理的持久化对象(PO persistence object )的生命周期有四种状态,分别是transient.persistent.detached和re ...

  5. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 网格系统实例:手机、平板电脑、台式电脑

    <!DOCTYPE html> <html> <head> <title>Bootstrap 实例 - 手机.平板电脑.台式电脑</title&g ...

  6. HDU1875 畅通工程再续

    相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全 ...

  7. Codeforces Round #619 (Div. 2) Ayoub's function

    Ayoub thinks that he is a very smart person, so he created a function f(s)f(s) , where ss is a binar ...

  8. wpf表单验证

    在做表单的,需要对User提交数据做验证,wpf与silverlight 都提供自带的验证机制,但是只是验证,并不能在提交时提供详细的信息,此时可使用 依赖属性将错误信息整合进自定义错误集合中,即可在 ...

  9. git切换分支导致代码丢失找回(git reflog找回错误的重置)

    1.使用git reflog查看日志 2.切换到丢失的分支 3. 创建一个临时分支  如(diff),并切换到dev(原分支),然后合并diff到dev分支 4.查看状态 5.强制合并,然后提交到de ...

  10. VS2019 发布单文件

    在项目.csproj文件下添加 <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework&g ...