嵌入式 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 = ;
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的实现的更多相关文章
- 嵌入式 printf函数
来自:https://www.cnblogs.com/02xiaoma/archive/2012/06/22/2558618.html #include <stdio.h> #includ ...
- OpenCL Hello World
▶ OpenCL 的环境配置与第一个程序 ● CUDA 中自带 OpenCL 需要的头文件和库,直接拉近项目里边去就行:AMD 需要下载 AMD APP SDK(https://community.a ...
- 嵌入式操作系统---打印函数(printf/sprintf)的实现
一.打印函数简介 作用:将“给定的内容”按照“指定的格式”输出到“指定目标内”. 打印函数的基本格式: char print_buf[BUF_SIZE]; void printf(const char ...
- [misc]如何在嵌入式平台使用printf功能
转自:http://www.cnblogs.com/liu_xf/archive/2011/04/14/2015726.html 摘要: 当我们在调试代码时,通常需要将程序中的某个变量打印至PC机上, ...
- 嵌入式处理器通过UART实现scanf和printf
#include <stdint.h> #include <stdarg.h> extern int vsscanf(const char *, const char *, v ...
- 学号20145332 《信息安全系统设计基础》实验五 简单嵌入式WEB服务器实验
实验目的 掌握在 ARM 开发板实现一个简单 WEB 服务器的过程. 学习在 ARM 开发板上的 SOCKET 网络编程. 学习 Linux 下的 signal()函数的使用. 实验内容 学习使用 s ...
- 可变参数列表与printf()函数的实现
问题 当我们刚开始学习C语言的时候,就接触到printf()函数,可是当时"道行"不深或许不够细心留意,又或者我们理所当然地认为库函数规定这样就是这样,没有发现这个函数与普通的函数 ...
- 20145216 20145330 《信息安全系统设计基础》 实验五 简单嵌入式WEB 服务器实验
20145216 20145330 <信息安全系统设计基础> 实验五 简单嵌入式WEB 服务器实验 实验报告封面 实验步骤 1.阅读理解源码 进入/arm2410cl/exp/basic/ ...
- sqlite嵌入式数据库C语言基本操作(2)
:first-child{margin-top:0!important}img.plugin{box-shadow:0 1px 3px rgba(0,0,0,.1);border-radius:3px ...
随机推荐
- 理解Linux内核注释
内核是Linux的心脏,它是在引导时装入的程序,用来提供用户层程序和硬件之间的接口,执行发生在多任务系统中的实际任务转换,处理读写磁盘的需求,处理网络接口,以及管理内存.一般情况下,自动安装的内核无需 ...
- 【转】django 三件套(render,redirect,HttpResponse)
Django基础必备三件套**: HttpResponse 内部传入一个字符串参数,返回给浏览器. from django.shortcuts import HttpResponse def inde ...
- 电源适配器DC插头规格
电源适配器 DC 插头的内径外径规格有 (单位为 MM) :2.0*0.72.35*0.72.35*1.12.5*0.73.5*1.13.5*1.354.0*1.75.5*2.15.5*2.54.75 ...
- kudu-master服务启动失败
执行service kudu-master start , 提示启动失败failed. 进入报错日志目录 (cd /var/log/kudu/),看到报错信息(vim kudu-master.ER ...
- Mapgis地图颜色配置(专题图配置)----对比Arcgis根据属性配置图斑颜色
对于大多数arcgis用户来说,根据属性配置图斑颜色对于大家来说应该并不陌生.本文将就arcgis图斑颜色设置与mapgis做出比对,为大家提供更为绚丽的地图配色. Arcgis颜色配置方案 右 ...
- mysql 官方读写分离方案
mysql 8.0 集群模式下的自动读写分离方案 问题 多主模式下的组复制,看起来挺好,起始问题和限制很多.而且中断一个复制就无法配置了 多主模式下,innodbcluster 等于是无用的,不需要自 ...
- 15、python面对对象之类和对象
前言:本文主要介绍python面对对象中的类和对象,包括类和对象的概念.类的定义.类属性.实例属性及实例方法等. 一.类和对象的概念 问题:什么是类?什么是实例对象? 类:是一类事物的抽象概念,不是真 ...
- 测试者出的APP测试面试题
测试者出的APP测试面试题 一.开场问题:(自由发挥) 1.请自我介绍一下: 2.为什么离开上一个公司呢? 3.做测试多久了?以前做过哪些项目?你们以前测试的流程是怎样的?用过哪些测试工具? 4.你觉 ...
- 操作系统OS - Zip Bomb
42.zip - A 42 kb zip file that contains 4.5 Petabytes of uncompressed data.
- Java Juc学习笔记
Java JUC 简介 在 Java 5.0 提供了 java.util.concurrent (简称JUC )包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括 ...