在嵌入式中,经常需要用到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. 实验1 GIT代码版本管理

    (一)实验目的: 1)了解分布式分布式版本控制系统的核心机理: 2) 熟练掌握git的基本指令和分支管理指令: (二)实验内容: 1)安装git 2)初始配置git ,git init git sta ...

  2. 如何使html中的元素不被选中

    有时候,为了提高用户的体验度,需要使网页中的部分内容防误操作,不被选中,比如今天的商城项目中的一个细节部分: + —号其实是a标签做的,当连续点击多次,就会使符号被选中,这样感觉起来不太好,于是查找解 ...

  3. DOCKSWARM服务网络原理

    如图所示,我们将在 swarm 集群中部署 “client” 服务 和 “vote” 服务,其中 “vote” 服务部署多个副本. 客户端请求 “vote” 服务时,输出结果中包含服务端的容器 ID, ...

  4. JavaScript位置:window&client&offset&scroll&MouseEvent&getBoundingClientRect&计算任意元素滚动条宽度

    Window: window.innerWidth:浏览器viewport视口宽,包括垂直滚动条 window.innerHeight:浏览器视口高,包括水平滚动条 window.outerWidth ...

  5. MSE-初始化MSE

    MSE(Mobility Services Engine) Cisco MSE可以配合无线实现很多功能,MSE的功能简单概括有: 1.基本位置服务捕获并聚合关键网络信息,例如设备位置,RF频谱详细信息 ...

  6. 【原】Django总结

    centos7下部署django详细步骤:https://www.cnblogs.com/djangocn/p/9538551.html 快速入门:https://www.cnblogs.com/ze ...

  7. 阅读build to win的个人感想

    一个程序员要向各个方面学习,向市场.向用户学习等,不能局限于一方面.除此以外还要有自己的想法,要懂得创新,也需要在各个方面都有所突破,有所超越,实力才是取得胜利的根关键.

  8. linux修改文件的权限和修改文件所有者和所属组

    文件设定法:chmod    [who]   [+][-][=]   [mode] who 文件所有者:u 文件所属组:g 其他:o 所有人:a +  添加权限 -  减少权限 =  覆盖原来权限 权 ...

  9. [A]List`1[MyObject] cannot be cast to [B]List`1[MyObject]

    Description I have created a small class in a single ASP.NET 4.5 web forms page that is instantiated ...

  10. ElementUI el-message 提示信息的用法

    引入message Element 注册了一个$message方法用于调用,Message 可以接收一个字符串或一个 VNode 作为参数,它会被显示为正文内容. Element 为 Vue.prot ...