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输出到串口,为何初始化了串口之后就可以使用了?