Keil C51 的printf

发布者:火星叔叔最新更新时间:2017-01-19 来源: eefocus关键字:Keil  C51  printf 手机看文章 扫描二维码
随时随地手机看文章

在Keil C51 中使用printf ,首先需要重新实现 putchar(char c)函数。此函数在

char putchar (char c)   
{        
    ES=0;        
    SBUF = c;        
    while(TI==0);        
    TI=0;        
    ES=1;        
    return 0;
}

我们先分析一下上面这个程序哈, 
关闭串口中断 
发送单字节数据 
等待发送完毕 
清除TI标志 
开启串口中断

在main函数里可以直接使用printf函数进行输出了。 
但是,我一直存在这样一个疑惑:

void main()
{    unsigned char test1 = 55;    printf("the test is %d\r\n",test1);
}

使用串口输出的数值一直不对,我后来自己理解,%d是整型,而在Keil C51整型占用2个byte,所以我一般的解决办法是做一次强制类型转换:

void main()
{    unsigned char test1 = 55;    printf("the test is %d\r\n",(int)test1);
}

后来阅读Keil C51的帮助手册: 
得到这样一条信息:

格式含义针对类型
%d两个字节变量int
%bd单字节变量char
%ld四字节变量long int

所以上面的问题的另一个解决方案是:

void main()
{    unsigned char test1 = 55;    printf("the test is %bd\r\n",test1);
}

下面附上Keil C51手册内容。 
int printf ( 

const char fmtstr / format string */ 
<[>, arguments … <]>); /* additional arguments */

Description The printf function formats a series of strings and numeric values and builds a string to write to the output stream using the putchar function. The fmtstr argument is a format string that may be composed of characters, escape sequences, and format specifications.

Ordinary characters and escape sequences are copied to the stream in the order in which they are interpreted. Format specifications always begin with a percent sign (‘%’) and require that additional arguments are included in the printf function call.

The format string is read from left to right. The first format specification encountered references the first argument after fmtstr and converts and outputs it using the format specification. The second format specification accesses the second argument after fmtstr, and so on. If there are more arguments than format specifications, extra arguments are ignored. Results are unpredictable if there are not enough arguments for the format specifications or if the argument types do not match those specified by fmtstr.

Format specifications have the following general format:

% <[>flags<]> <[>width<]> <[>.precision<]> <[>{b|B|l|L}<]> type 
Each field in the format specification may be a single character or a number which specifies a particular format option.

The type field is a single character that specifies whether the argument is interpreted as a character, string, number, or pointer, as shown in the following table.

Type ArgumentType InputFormat
dintSigned decimal number.
uunsigned intUnsigned decimal number.
ounsigned intUnsigned octal number.
xunsigned intUnsigned hexadecimal number using “0123456789abcedf”.
Xunsigned intUnsigned hexadecimal number using “0123456789ABCDEF”.
ffloatFloating-point number formatted as<[>-<]>dddd.dddd.
efloatFloating-point number formatted as<[>-<]>d.dddde<[>-<]>dd.
EfloatFloating-point number formatted as<[>-<]>d.ddddE<[>-<]>dd.
gfloatFloating-point number using either the e or f format, whichever is more compact for the specified value and precision.
GfloatFloating-point number using either the E or f format, whichever is more compact for the specified value and precision.
ccharA single character.
s*A string of characters terminated by a null character (‘\0’).
p*A generic pointer formatted as t:aaaa where t is the memory type and aaaa is the hexadecimal address.

Note

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. 
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. 
Characters following a percent sign that are not recognized as a format specification are treated as ordinary characters. For example, “%%” writes a single percent sign to the output stream.

The flags field is a single character used to justify the output and to print +/- signs and blanks, decimal points, and octal and hexadecimal prefixes, as shown in the following table.

Flag Description 
- Left justify the output in the specified field width. 
+ Prefix the output value with a + or - sign if the output is a signed type. 
blank (’ ‘) Prefix the output value with a blank if it is a signed positive value. Otherwise, no blank is prefixed.

Prefixes a non-zero output value with 0, 0x, or 0X when used with o, x, and X field types, respectively.

When used with the e, E, f, g, and G field types, the # flag forces the output value to include a decimal point.

The # flag is ignored in all other cases.

The width field is a non-negative number that specifies the minimum number of characters printed. If the number of characters in the output value is less than width, blanks are added on the left (by default) or right (when the - flag is specified) to pad to the minimum width. If width is prefixed with a ‘0’, zeros are padded instead of blanks. The width field never truncates the output. If the length of the output value exceeds the specified width, all characters are output.

The width field may be an asterisk (‘*’), in which case an int argument from the argument list provides the width value. Specifying a ‘b’ in front of the asterisk specifies that the argument is an unsigned char.

The precision field is a non-negative number that specifies the number of characters to print, the number of significant digits, or the number of decimal places. The precision field can cause truncation or rounding of the output value in the case of a floating-point number as specified in the following table.

Type Precision Field Meaning 
d,u,o,x,X The precision field specifies the minimum number of digits that are included in the output value. Digits are not truncated if the number of digits in the argument exceeds that defined in the precision field. If the number of digits in the argument is less than the precision field, the output value is padded on the left with zeros. 
f The precision field specifies the number of digits to the right of the decimal point. The last digit is rounded. 
e,E The precision field specifies the number of digits to the right of the decimal point. The last digit is rounded. 
g,G The precision field specifies the maximum number of significant digits in the output value. 
s The precision field specifies the maximum number of characters in the output value. Excess characters are not output. 
c,p The precision field has no effect on these field types.

The precision field may be an asterisk (‘*’), in which case an int argument from the argument list provides the value. Specifying a ‘b’ in front of the asterisk specifies that the argument is an unsigned char.

Note

You must ensure that the argument type matches that of the format specification. You may use type casts to ensure that the proper type is passed to printf. 
This function is implementation-specific and is based on the operation of the _getkey and putchar functions. These functions, as provided in the standard library, read and write characters using the microcontroller’s serial port. Custom functions may use other I/O devices. 
The total number of bytes that may be passed to this function is limited due to the memory restrictions imposed by the 8051. A maximum of 15 bytes may be passed in SMALL or COMPACT model. A maximum of 40 bytes may be passed in LARGE model.

Return Value The printf function returns the number of characters actually written to the output stream.

See Also gets, printf517, puts, scanf, scanf517, sprintf, sprintf517, sscanf, sscanf517, vprintf, vsprintf

Example #include 

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);
}



    关键字:Keil  C51  printf 引用地址:Keil C51 的printf

    上一篇:KEIL C51 printf格式化输出特殊用法
    下一篇:MCS-51单片机的定时器/计数器概念

    推荐阅读最新更新时间:2024-03-16 15:31

    STM32L0低功耗设计2: 使用Keil和ST-Link下载低功耗程序
    继续项目的开发工作,突然发现,程序不能够正常下载到单片机中了,提示如下图所示的错误,我使用的是keil和ST-Link。 这个问题在我第1次调试的时候发生过1次,我认为是我误操作将芯片烧坏了,因为当时又反复的焊接了一下芯片,也没有修好,就把这件事情放下了。 今天再次出现,自己感觉可能和低功耗有关,仔细查看刚刚下载的程序,里面上来程序就进入低功耗,没有任何退出语句,所以应该是CPU不响应下载命令了。 按照这种思路,先将单片机的复位引脚接地,然后点击下载按钮的同时,放开复位引脚,居然成功了。 再仔细想不应该呀,ST-Link控制着复位引脚了,应该在下载的时候复位单片机才对呀。 查看Keil中的ST-
    [单片机]
    Keil4中建立基于V3.4.0固件库的STM32工程
    几个月前刚接触STM32时,第一感觉就是固件库里的文件又多又深,还好发现固件库里自带有范例文件,但是它们全都是针对特定的评估板的,手头只有一块STM MCU 3 in 1 MiniKit。虽说作些修改就可为我所用,可对于像我这样还没入门的菜鸟,知道要如何修改,并且编译通过,却是非常困难。 昨晚闲暇,在网上找了一些资料,自己也学着新建了一个工程。今天写下来,顺带温故一遍。 首先介绍一下操作环境: Keil版本: μVision 4.1.0 STM32固件库版本: V3.4.0 第一步,建立工程文件夹,在其子文件夹内拷贝并整理好相应的文件。 1.1、建立工程文件夹,将它命名为 Sys
    [单片机]
    Keil C51中直接使用二进制数方法
    在Keil C51中数不能直接以二进制形式赋值,虽然在8051的汇编中是可以的。二进制数虽然书写长,易出错,但是由于是一位位写的,所以程序设计者能够很明确的看到每一位的状态,看得比较直观。于是很多人怀念了8051的汇编,很想在C51中使用二进制。没猜错的话搜到本篇日志的人很可能就是来找这种解决办法的,下面两种办法都是不错的选择。   方法一:   建立一个头文件,将所有的二进制数宏定义列举出来,用的时候直接使用宏定义,头文件定义:binary(右键 “目标另存为” 下载)。   方法二:   做一个带参数宏定义,将输入的类二进制数变换为对应的16进制数,整个定义和使用实例请见下文,可以直接使用,如果想研究原理又看不懂带参宏
    [单片机]
    c51: 巡检 DS18B20
    //DS1820 应用,根据序列号读取温度, //实现温度巡检 #include reg51.h #include intrins.h #include ctype.h //变量声明 #define uchar unsigned char #define uint unsigned int uchar digit = 0123456789ABCDEF ; //序列号 uchar number1 = 2600000012345628 ; uchar number2 = 1100000012345728 ; uchar* serial ={number1,number2}; uchar array ; //延时
    [单片机]
    C51---3.2 独立按键控制LED亮灭状态
    原理图 按键消抖 对于机械开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动。所以我们需要给按键进行延时消抖 main函数 独立按键控制LED灯亮灭 按键按下并松开时 LED灯状态翻转 #include REGX52.H //0 num 65535 void Delay_ms(unsigned int num) //@12.000MHz { unsigned char i, j; while(num) { i = 2; j = 239; do { while (-
    [单片机]
    C51---3.2 独立按键控制LED亮灭状态
    单片机成长之路(51基础篇) - 018 keil51的STARTUP.A51
    STARTUP.A51原始文件: 1 $NOMOD51;Ax51宏汇编器控制命令,禁止预定义的8051。使编译器不使能预定义的;8051符号,避免产生重复定义的错误。 2 ;------------------------------------------------------------------------------ 3 ; This file is part of the C51 Compiler package 4 ; Copyright (c) 1988-2005 Keil Elektronik GmbH and Keil Software, Inc. 5 ; Version 8.01 6 ;
    [单片机]
    AT89S52与LCD1602(asm/c51)
    LCD1602 DDRAM地址映射表: 第一行地址80H 第二行地址C0H 单片机与LCD1602接口 ;/////////////////////////////////////////////// 项目名称:AT89S52与LCD1602接口实验 功能:在LCD1602的第一行显示WWW.LZY.EDU.CN : 在LCD1602的第二行显示0830--3150897 ;/////////////////////////////////////////////// RS EQUP2.4 ;P2.4接LCD的RS RW EQUP2.5 ;P2.5接L
    [单片机]
    AT89S52与LCD1602(asm/<font color='red'>c51</font>)
    一种基于C51的多任务机制及应用
    摘要:本文介绍了一种在MCS51单片机程序中实现多任务机制的简单方法,并给出了源代码和一个应用实例。通过中断进行实时任务切换,具有结构简单清晰、代码量少、不需使用汇编等优点。该方法亦可应用于其他单片机系统。 关键词:多任务系统 单片机 C51 中断 安防系统 引言 传统的单片机程序一般采用单任务机制,单任务系统具有简单直观、易于控制的优点。然而由于程序只能按顺序依次执行,缺乏灵活性,只能使用中断函数实时地处理一些较短的任务,在较复杂的应用中使用极为不便。嵌入式多任务操作系统的出现解决了这个问题。在多任务系统中,可以同时执行多个并行任务,任务之间可以相互跳转。但是嵌入式操作系统在提供强大功能的同时,也带来了代码量大、结构复杂
    [单片机]
    小广播
    添点儿料...
    无论热点新闻、行业分析、技术干货……
    设计资源 培训 开发板 精华推荐

    最新单片机文章
    何立民专栏 单片机及嵌入式宝典

    北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

    换一换 更多 相关热搜器件
    电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved