优秀的编程知识分享平台

网站首页 > 技术文章 正文

《51单片机笔记》keilC51软件中printf函数详解

nanyue 2024-07-25 06:06:54 技术文章 16 ℃

摘要

#include <stdio.h>

int printf (
  const char *fmtstr       /* format string */
  <[>, arguments ... <]>);   /* additional arguments */

描述

printf函数格式化一系列字符串和数值,并使用putchar函数构建一个字符串以写入输出流。fmtstr参数是一个格式字符串,可以由字符、转义序列和格式规范组成。


普通字符和转义序列按其解释顺序复制到流中。格式规范总是以百分号(“%”)开头,并要求printf函数调用中包含其他参数。


格式字符串从左到右读取。遇到的第一个格式规范引用fmtstr之后的第一个参数,并使用格式规范将其转换和输出。第二个格式规范访问fmtstr之后的第二个参数,依此类推。如果参数多于格式规范,则会忽略额外的参数。如果没有足够的参数用于格式规范,或者参数类型与fmtstr指定的类型不匹配,则结果是不可预测的。


格式规范有以下通用格式:

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

格式规范中的每个字段可以是指定特定格式选项的单个字符或数字。

type字段是一个字符,用于指定参数是被解释为字符、字符串、数字还是指针,如下表所示。

注:

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


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

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


flags字段是一个字符,用于对齐输出,打印+/-符号和空格、小数点、八进制和十六进制前缀,如下表所示。

width 字段是一个非负数,指定打印的最小字符数。如果输出值中的字符数小于宽度,则在左侧(默认情况下)或右侧(指定-标志时)添加空格以填充到最小宽度。如果宽度前缀为“0”,则填充零而不是空格。宽度字段从不截断输出。如果输出值的长度超过指定的宽度,则输出所有字符。


width 字段可以是星号(“*”),在这种情况下,参数列表中的int参数提供宽度值。在星号前面指定一个“b”表示参数是无符号字符。

精度字段是一个非负数,指定要打印的字符数、有效位数或小数位数。对于下表中指定的浮点数,精度字段可能导致输出值的截断或舍入。

precision 字段可以是星号(“*”),在这种情况下,参数列表中的int参数提供值。在星号前面指定一个“b”表示参数是无符号字符。

必须确保参数类型与格式规范的类型匹配。您可以使用类型转换来确保将正确的类型传递给printf。


此函数是特定于实现的,基于__getkey和putchar函数的操作。标准库中提供的这些函数使用微控制器的串行端口读写字符。自定义函数可能使用其他I/O设备。

由于8051施加的内存限制,可传递给该函数的字节总数受到限制。在小型或紧凑型中最多可以传递15个字节。在大型模型中最多可以传递40个字节。

返回值

printf函数返回实际写入输出流的字符数。

参考文献:Cx51 User's Guide (KEIL C51官方参考手册)

视频讲解及测试例子:

视频讲解:

1,https://www.ixigua.com/6921169441401078283

2,https://www.ixigua.com/6921169728379552260

程序:


/*
	1,串口的初始化(设置波特率,设置串口的工作方式,奇偶校验:96N81)
	9600 8 N 1 (不能产生115200)
	2,有必要就设置串口中断:开启串口中断和总中断
	
	3,可以printf函数(需要包含头文件stdio.h)

	3,自己编写发送和接收字符和字符串的函数
	4,发送和接收完后,需要软件清除串口中断标志位(RI,TI) TI=0
*/
#include<reg51.h>
#include<stdio.h>

//毫秒延时函数
void delay_ms(unsigned int t)
{
    unsigned int a = 0,b = 0;

    for(b=0;b<t;b++)
      for(a=110;a>0;a--);
}

void Uart_Init(void)
{
	TMOD |= 0X20;//   使用定时器1 工作方式2
	TH1=TL1=0XFD;    //设置波特率9600 //时钟频率11.0592M
	SCON = 0X50;    //串口工作在方式1 REN=1	接收数据
   	PCON = 0;       //SMOD=1:波特率加倍  这里是不加倍

	ES=1;	   //开启串口中断
	EA=1;    //开启总中断
	TR1=1;  //开启定时器1

}

int main(void)
{
	void tst_printf (void);
	char  a='A';
	Uart_Init();
	TI = 1;			   //RI
	while(1)
	{
		printf("doubixiaohanhan %c\n",a++);
		//tst_printf();
		delay_ms(500);					
	}
	return 0;	
}

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 ("char %c 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);
}

效果:

更多内容欢迎关注逗比小憨憨

Tags:

最近发表
标签列表