单片机C语言实现printf

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

单片机串口实现printf函数

背景叙述:

在初学C语言时,利用printf函数向屏幕上输出字符,非常的好用和方便。学会单片机以后,尤其在学会串口通信之后,通过单片机的串口向PC机发送数据,怎么实现printf函数的功能。对于学习单片机来说,如果没有仿真器,出错误的时候不好找,只能用最笨的办法,使用printf函数,可是在KEIL里面使用printf却不像VC里面那么简单,因为其发送和硬件是有关系的。所以今天就简单来说说怎么在51单片机中使用"printf"函数:包括使用自带的printf函数和自己动手写一个printf函数

功能描述:

通过printf函数向串口发送数据,显示在终端或者串口助手上Proteus中串口终端的介绍

1、连接方法如下所示

2、串口的配置

尤其注意配置的波特率一定要和程序代码中所写的一样(否则会造成

无法显示字符)

数据位

停止位

奇偶校验位

极性(这些属性基本上是默认的配置)

3、串口终端的使用

proteus virtual terminal 使用注意事项

a. virtual terminal 默认显示字符,如果单片机发送的是非显示字符,则虚拟终端不会显示,会导致用户认为通讯未通。

运行程序,在虚拟终端窗口里面点击右键,在弹出菜单里面:

选HEX DISPLAY MODE,则显示按十六进制显示,能显示所有字符。

b.virtual terminal 默认情况下不显示回显字符,

运行程序,在虚拟终端窗口里面点击右键,在弹出菜单里面:

选Echo Typed Characters 显示回显字符

c.virtual terminal 和模拟物理串口COMPIM不能同时使用,同时使用会发生相互影响。

d. 启动仿真后可以右键单击终端,最后一栏打开和关闭串口显示终端

源程序

直接使用系统自带的printf函数:特别注意需要置位TI=1,否则是无法发送的,程序如下(此程序在proteus终端上不能显示汉字,但在串口调试助手上可以)

/******decription******************

利用printf函数向串口打印信息

51单片机晶振频率11.0592MHZ

串口通信波特率9600bps

利用printf函数TI初始值必须置1

***********************************/

/*******includes file*************/

#include

#include

#include

#include

#define uchar unsigned char

#define uint unsigned int

void delay_1ms(uint z)

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

void uart_init(void)

TMOD=0x20; //定时计数器1,工作方式2

TH1=0xFD; //设置波特率9600

TL1=0xFD;

TR1=1;

SCON=0x50;

PCON=0x00;

EA=1;

ES=1;

TI=1; //若利用printf函数则TI初始值必须置1 }

void main()

{

uart_init();

while(1)

{

// SBUF = 'H';

// while(TI==0);

// TI=0;

printf("i am herro!\n\r");

delay_1ms(1000);

if(ff)

{

ff=0;

printf("%c",num);

}

}

}

void ser_interrupt() interrupt 4

{

if(RI==1)

{

ES=0;

RI=0;

num=SBUF;

ES=1;

ff=1;

}

}

4.编写自己的printf函数(这个函数不能再proteus中仿真,但实际中可以使用)

a.预备知识

①C语言函数:vsprintf,

其原型为int vsprintf(char *string, char *format, va_list param);,作用为将param按格式format写入字符串string中,因此他可以用于将任何格式数据转化为字符串数据,比如把整数97转化为ASCII码的97的程序就像下面这样vsprintf(string,"%d",97),当然还有一点需要注意:在keil里面使用sprintf需要包含stdio.h这个头文件(当然这里也可以使用sprintf,作用完全差不多,只需要稍加修改即可,不多介绍)。说到这里,再来说说另一个函数itoa吧,其实他比vsprintf更简单,其原型为char *itoa(int value, char *string, int radix),作用为将value按radix进制写入到string字符串中,使用时需要包含头文件stdlib.h,可是在keil里面却无法使用,头文件里面不包含itoa,即使把VC里面的复制进来貌似还是不行,呵呵,目前不知道原因。

②可变参数函数

具体来说就是stdarg.h里面的这几个函数va_start,va_arg,va_list,va_end,这几个参数用于开辟一段内存区域,可以配合vsprintf使用,但是对内存使用较大,需要单片机具备一定的RAM,否则程序就算能编译通过也是无法运行的。

函数形参列表中的变量在内存中的位置是顺次排列的。头文件Stdarg.h里的几个宏定义就是利用了这么一点,顺次获取多个参数Keil中上述函数的定义如下

typedef char * va_list; //va_list即为字符指针类型

#define va_start(ap,v) ap = (va_list)&v + sizeof(v)

相关文档
最新文档