在网上看到有人在单片机上使用printf函数,心痒痒,也想用,看了网上的一些方法,
大都是51单片机的,说的是在51单片机编译软件库中有自带printf函数,也有自己实现
一个自己的printf函数的,但是讲的不详细,看了好几个博客,东拼西凑,也在自己的
单片机上弄出来了。
1,先进行用到的知识讲解:
宏va_start(ap,fmt) 、 va_end(ap) 、va_arg(A,T) 以及类型定义va_list 主要用于获取 printf() 的参数,因为 printf() 参数数量可变,
// 参考 http://blog.csdn.net/lingran07/article/details/7680888
在我的编译器安装路径中找到文件 stdarg.h, 里面有如下定义:
#define va_arg(ap, T) \
((ap) += _Bnd(T, _AUPBND), *(T __near *)((ap) - _Bnd(T, _ADNBND)))
#define va_end(ap) (void)0
#define va_start(ap, A) \
(void)((ap) = (char __near *)&(A) + _Bnd(A, _AUPBND))
#define _Bnd(X, bnd) (sizeof (X) + (bnd) & ~(bnd))
在另一文件yvals.h 中找到 #define _AUPBND 1U // 1U 即 1,后面的U是 unsigned 的意思
因此,可以得到 #define va_arg(ap, T) ((ap) += sizeof(T), *(T*)((ap) - sizeof(T))
((ap) += sizeof(T), *(T*)((ap) - sizeof(T)) 是一个逗号表达式,功能是先将指针 ap 指向下一个参数,然后取出当前的参数数据。
#define va_start(ap, A) (void)((ap) = (char *)&A + sizeof(A)) 功能是将 ap 指向第二个参数,例如 printf("%s\n", "hello world"); 第一个参数"%s\n", 第二个参数"hello world"
2,下面贴出代码。(只需要确定存在文件stdarg.h ,实现针对特定芯片的函数 void Uart1WriteByte(unsigned char databyte),下面的代码即可直接使用)
主要参考;
http://blog.csdn.net/googlemi/article/details/8996605
http://blog.sina.com.cn/s/blog_6dee515f0100v75r.html
/*
* stdarg.h 针对特定芯片定义的头文件,主要定义了va_start(ap,fmt); va_end(ap); va_arg(A,T);
* 特定芯片是因为有的芯片栈是自下而上,有的相反
*/
#include <stdarg.h>
typedef char *va_list;
/*
* 将整形数字转换成字符,如 0 转换成 '0'
*/
char number2char(int num)
{
char ch;
大都是51单片机的,说的是在51单片机编译软件库中有自带printf函数,也有自己实现
一个自己的printf函数的,但是讲的不详细,看了好几个博客,东拼西凑,也在自己的
单片机上弄出来了。
1,先进行用到的知识讲解:
宏va_start(ap,fmt) 、 va_end(ap) 、va_arg(A,T) 以及类型定义va_list 主要用于获取 printf() 的参数,因为 printf() 参数数量可变,
// 参考 http://blog.csdn.net/lingran07/article/details/7680888
在我的编译器安装路径中找到文件 stdarg.h, 里面有如下定义:
#define va_arg(ap, T) \
((ap) += _Bnd(T, _AUPBND), *(T __near *)((ap) - _Bnd(T, _ADNBND)))
#define va_end(ap) (void)0
#define va_start(ap, A) \
(void)((ap) = (char __near *)&(A) + _Bnd(A, _AUPBND))
#define _Bnd(X, bnd) (sizeof (X) + (bnd) & ~(bnd))
在另一文件yvals.h 中找到 #define _AUPBND 1U // 1U 即 1,后面的U是 unsigned 的意思
因此,可以得到 #define va_arg(ap, T) ((ap) += sizeof(T), *(T*)((ap) - sizeof(T))
((ap) += sizeof(T), *(T*)((ap) - sizeof(T)) 是一个逗号表达式,功能是先将指针 ap 指向下一个参数,然后取出当前的参数数据。
#define va_start(ap, A) (void)((ap) = (char *)&A + sizeof(A)) 功能是将 ap 指向第二个参数,例如 printf("%s\n", "hello world"); 第一个参数"%s\n", 第二个参数"hello world"
2,下面贴出代码。(只需要确定存在文件stdarg.h ,实现针对特定芯片的函数 void Uart1WriteByte(unsigned char databyte),下面的代码即可直接使用)
主要参考;
http://blog.csdn.net/googlemi/article/details/8996605
http://blog.sina.com.cn/s/blog_6dee515f0100v75r.html
/*
* stdarg.h 针对特定芯片定义的头文件,主要定义了va_start(ap,fmt); va_end(ap); va_arg(A,T);
* 特定芯片是因为有的芯片栈是自下而上,有的相反
*/
#include <stdarg.h>
typedef char *va_list;
/*
* 将整形数字转换成字符,如 0 转换成 '0'
*/
char number2char(int num)
{
char ch;