printf函数在Keil 开发C51单片机当中的使用细节

Posted perseverance52

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了printf函数在Keil 开发C51单片机当中的使用细节相关的知识,希望对你有一定的参考价值。

printf函数在Keil 开发C51单片机当中的使用细节


#include <stdio.h>

void tst_printf (void) 
  char a = 1;
  int b  = 12365;
  long c = 0x7FFFFFFF;

  unsigned char x = 'A';
  unsigned int y  = 54321;
  unsigned long z = 0x4A6F6E00;

  float f = 10.0;
  float g = 22.95;

  char buf [] = "Test String";//不定长数组
  char *p = buf;

  printf ("char %bd int %d long %ld\\n",a,b,c);
  printf ("Uchar %bu Uint %u Ulong %lu\\n",x,y,z);
  printf ("xchar %bx xint %x xlong %lx\\n",x,y,z);
  printf ("String %s is at address %p\\n",buf,p);
  printf ("%f != %g\\n", f, g);
  printf ("%*f != %*g\\n", (int)8, f, (int)8, g);


  • %bd

在Keil C51中这里的b表示byte,即1个字符,%bd就是输出一个byte宽度的整型数(char)。

  • %bu

输出一个byte宽度的无符号整型数,(unsigned char)。

  • %ld

输出一个long宽度的,长整型数据

C语言printf输出

%d整型输出,%ld长整型输出,
%o以八进制数形式输出整数,
%x以十六进制数形式输出整数,
%u以十进制数输出unsigned型数据(无符号数)。
%c用来输出一个字符,
%s用来输出一个字符串,
%f用来输出实数,以小数形式输出
%.4f用来输出实数,保留小数点4位。
%e以指数形式输出实数,
%g根据大小自动选f格式或e格式,且不输出无意义的零。

Keil编译中C51数据类型列表

  • bit、sbit、sfr和sfr16数据类型在ANSI c中没有提供,它们在Cx51编译器中是唯一的。

Keil C51中的printf()与标准的C库的printf()函数稍有不同,在相应的帮助文档中有如下描述:

% <[>flags<]> <[>width<]> <[>.precision<]> <[>b|B|l|L<]> type

  • The optional characters l or L may immediately precede the type character to respectively specify long types for d, i, u, o, x, and X.

可选字符l或l可以紧接在type字符之前,分别为d、i、u、o、x和x指定长类型。

  • The optional characters b or B may immediately precede the type character to respectively specify char types for d, i, u, o, x, and X.

可选字符b或B可以紧接在类型字符之前,分别指定d、i、u、o、x和x的字符类型。

  • 不被识别为格式规范的百分号后面的字符将被视为普通字符。例如,“%%”将一个百分号写入输出流。

也就是说,使用C51的printf()函数打印%d/i/u/o/x/X格式时,你必须要指定该变量的存储格式l/L/b/B。
如果定义的变量c为char类型,可将相应的代码改为如下:

printf("%bd\\n",c);
printf("%bu\\n",c);
printf("%bx\\n",c);

即可得到正确的结果。除此之外:

  • 若变量c为uint16时,则需将%bd等改为%hd;
  • 若变量c为uint32时,则需将%bd等改为%ld;

对于定长数组printf打印

unsigned char  rec_dat[4];
....
printf("DHT11 TEMP:%bd.%bd;Hum:%bd.%bd \\n", rec_dat[0], rec_dat[1], rec_dat[2], rec_dat[3]);
  • 切记不能直接使用printf("DHT11 TEMP:%d.%d;Hum:%d.%d \\n", rec_dat[0], rec_dat[1], rec_dat[2], rec_dat[3]);来输出是不正确的。

串口输出示例

以STC15W408AS作为演示

/*
		串口通信
 附:利用单片机和PC机的串口通信的工作方式1(波特率可变),(
 已知晶振为11.0592MHZ)设置通信波特率为9600b/s,

*/
#include <STC15F2K60S2.H>
 
//#include<reg52.h>
#include<stdio.h>
 
#define uint unsigned int 
#define uchar unsigned char
 	
/*------------------------------------------------
                 串口初始化函数,波特率9600
------------------------------------------------*/
void init_com(void)

		SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x01;		//串口1选择定时器2为波特率发生器
	AUXR &= 0xFB;		//定时器时钟12T模式
	T2L = 0xE8;		//设置定时初始值
	T2H = 0xFF;		//设置定时初始值
	AUXR |= 0x10;		//定时器2开始计时
	TI=1;			// 很关键,使用printf函数时必须有此命令
	ES = 1; //开启串口中断
	EA=1;			   //开启总中断

void tst_printf (void) 
	unsigned char str[4];
  char a = 1;
  int b  = 12365;
  long c = 0x7FFFFFFF;

  unsigned char x = 'A';
  unsigned int y  = 54321;
  unsigned long z = 0x4A6F6E00;

  float f = 10.0;
  float g = 22.95;

  char buf [] = "Test String";
  char *p = buf;

  printf ("char %bd int %d long %ld\\n",a,b,c);//这里的int整型数可以用%hd
  printf ("Uchar %bu Uint %u Ulong %lu\\n",x,y,z);
  printf ("xchar %bx xint %x xlong %lx\\n",x,y,z);
  printf ("String %s is at address %p\\n",buf,p);
  printf ("%f != %g\\n", f, g);
  printf ("%*f != %*g\\n", (int)8, f, (int)8, g);
	str[0] = 95;
	str[1] = 27;
	str[2] = 0;
	str[3] = 7;
	printf("str=%bd%bd%bd%bd \\n", str[0], str[1], str[2], str[3]);

void main(void)

//	uint up=0,down=0,high=0;
//	uint result ;
	init_com();
			tst_printf();
	while(1);
		 	
//			printf("********************************\\r\\n");
//			printf("Please input up,dowm,high:\\r\\n");
//			scanf("%d%d%d",&up,&down,&high)	;
//			printf("\\r\\nResult=%d\\r\\n",result=(up+down)*high/2);

		


如果上面代码中打印定长数组的使用printf("str=%d%d%d%d \\n", str[0], str[1], str[2], str[3]);的输出结果:

完全就不对了。

  • 如果使用printf("str=%s \\n", str);来打印,结果:

也不正确

以上是关于printf函数在Keil 开发C51单片机当中的使用细节的主要内容,如果未能解决你的问题,请参考以下文章

单片机C8051在Keil C51环境下使用printf函数打印,发现打印值和实际不对应

51单片机Keil C51下使用printf输出到串口,为何初始化了串口之后就可以使用了?

c51中 printf怎用

keil C51 和 MDK 区别在哪 ?

怎么在51单片机中读取文件 如何在Keil C51使用fopen函数 也就是如何在C51中编写 能打开文件程序

Keil C51软件的使用