单片机中printf函数的运用
单片机C语言实现printf

单片机串口实现printf函数背景叙述:在初学C语言时,利用printf函数向屏幕上输出字符,非常的好用和方便。
学会单片机以后,尤其在学会串口通信之后,通过单片机的串口向PC机发送数据,怎么实现printf函数的功能。
对于学习单片机来说,如果没有仿真器,出错误的时候不好找,只能用最笨的办法,使用printf函数,可是在KEIL里面使用printf却不像VC里面那么简单,因为其发送和硬件是有关系的。
所以今天就简单来说说怎么在51单片机中使用"printf"函数:包括使用自带的printf函数和自己动手写一个printf函数功能描述:通过printf函数向串口发送数据,显示在终端或者串口助手上Proteus中串口终端的介绍2、串口的配置尤其注意配置的波特率一定要和程序代码中所写的一样(否则会造成无法显示字符)数据位停止位奇偶校验位极性(这些属性基本上是默认的配置)3、串口终端的使用proteusvirtualterminal使用注意事项a.virtualterminal默认显示字符,如果单片机发送的是非显示字符,则虚拟终端不会显示,会导致用户认为通讯未通。
运行程序,在虚拟终端窗口里面点击右键,在弹出菜单里面:选HEXDISPLAYMODEU显示按十六进制显示,能显示所有字符。
b.virtualterminal默认情况下不显示回显字符,运行程序,在虚拟终端窗口里面点击右键,在弹出菜单里面:选EchoTypedCharacters显示回显字符c.virtualterminal和模拟物理串口COMPIM不能同时使用,同时使用会发生相互影响。
d.启动仿真后可以右键单击终端,最后一栏打开和关闭串口显示终直接使用系统自带的printf函数:特别注意需要置位TI=1,否则是无法发送的,程序如下(此程序在proteus终端上不能显示汉字,但在串口调试助/******decription ******************手上可以)利用printf函数向串口打印信息51单片机晶振频率11.0592MHZ 串口通信波特率9600bps******* includesfile ************* **********************************『#include<reg51.h>#include<intrins.h>#include<string.h>#include<stdio.h>#defineucharunsignedchar #defineuintunsignedintvoiddelay_1ms(uintz){uintx,y;for(x=z;x>0;x--)for(y=110;y>0;y--); }voiduart_init(void)TMOD=0x20;〃定时计数器1,工作方式2TH1=0xFD;〃设置波特率9600TL1=0xFD;TR1=1;SCON=0x50;PCON=0x00;EA=1;ES=1;TI=1;〃若利用printf函数则TI初始值必须置1 )voidmain()(uart_init();while(1)(//SBUF='H';//while(TI==0);//TI=0;printf("iamherro!\n\r");delay_1ms(1000);(ff=0;printf("%c",num);)))voidser_interrupt()interrupt4(if(RI==1)(ES=0;RI=0;num=SBUF;ES=1;ff=1;))4.编写自己的printf函数(这个函数不能再proteus中仿真,但实际中可以使用)a.预备知识①C语言函数:vsprintf,其原型为intvsprintf(char*string,char*format,va_listparam);,作用为将param按格式format写入字符串string中,因此他可以用于将任何格式数据转化为字符串数据,比如把整数97转化为ASCII码的97的程序就像下面这样vsprintf(string,"%d",97),当然还有一点需要注意:在keil 里面使用sprintf需要包含stdio.h这个头文件(当然这里也可以使用sprintf,作用完全差不多,只需要稍加修改即可,不多介绍)。
关于printf的详细分析陈

*Exceptions:
*,诠释_flush(流) - 刷新缓冲区的一个单一的流
unsigned char y;
char putchar (char c)
{
disp(x,y,8,16,ZF+(c-ASCII)*16);
x+=8; //每个字符占8个像素
return c;
}
//扩展的printf //带x y坐标的printf (可不要)
//用在单片机中 x,y为全局坐标 如果坐标为为其它类型,如int 只需将unsigned char改为int
#include
#include
#include
#include
#include
/***
*int printf(format, ...) - print formatted data
*
*Purpose:
* Prints formatted data on stdout using the format string to
* problems flushing the buffer, set the stream flag to error.
* Multi-thread version assumes stream lock is held by caller.
*
*Entry:
* FILE* stream - stream to flush
//函数__iob_func()又在是_file.c中实现的:
/*
* FILE descriptors; preset for stdin/out/err (note that the __tmpnum field * is not Nhomakorabea*
单片机中printf函数的运用

51中printf使用注意C51标准串口发送程序(已C8051F120为例,注意C8051F120特殊功能寄存器是分页的)/***********************************************************函数名称:send_char_com函数功能:向串口发送一字节字符入口参数:unsigned char sendByte 一个字节字符(8 bit)出口参数:无备注:***********************************************************/void send_char_com(unsigned char sendByte){char SFRPAGE_SA VE = SFRPAGE; //用到TI0(SCON0.1)SFR页:0SFRPAGE = UART0_PAGE;SBUF0=sendByte;while (TI0== 0); //等待发送完毕TI0= 0; //清发送中断标志TI0SFRPAGE = SFRPAGE_SA VE;}/***********************************************************函数名称:send_char_com函数功能:向串口发送一个字符串入口参数:unsigned char *str 字符串数组首地址unsigned int strlen 该字符串长度出口参数:无备注:***********************************************************/void send_string_com( unsigned char *str, unsigned int strlen){unsigned int k= 0 ;do {send_char_com(*(str + k));k++;}while (k < strlen);}在C51中直接使用printf比自己编个串口发送字符串的函数方便,但有几个问题要注意的。
单片机中printf函数的重映射

单片机中printf函数的重映射
一、源自于:大侠有话说1.如果你在学习单片机之前学过C 语言,那么一定知道printf 这个函数.它最最好用的功能
除了打印你想要的字符到屏幕上外,还能把数字进行格式化.例如十进制的33, 用十进制
方式输出就是33,用十六进制的形式就输出成21,如果用字符形式输出,那就是ASCII 码
表对应的!.
2. 51 年代,一些人软件仿真的时候也很喜欢使用printf,但实际代码运行中,用的人则不多,因
为别说51 年代,就是用AVR 的,也会觉得printf 这个函数耗费的CPU 资源相当可观.所以
printf 在8 位单片机时代,熟悉的人的确不多.但到了ARM 时代,情况则大为不同.毕竟
ARM 的处理能力和51 完全不是一个级别,这使得不少人开始喜欢使用printf 在实际项目
中作为调试过程的串口输出.因为它的格式化功能实在是相当方便.
而本例程就是教会你这么使用printf.
3.程序把printf 的输出对象设定为串口1.有一个标准的函数是必须要自己定义的,那就是
fputc,把这个函数的功能写成串口输出一个字符.建议在串口的初始化模块中定义
int fputc(int ch)。
c51 printf使用方法

c51 printf使用方法
C51是一种被广泛使用的单片机芯片,printf是一种常用的输出函数。
在C51中,使用printf函数可以简便地输出结果。
使用方法如下:
1. 在程序开头添加头文件 #include <stdio.h>。
2. 使用printf函数输出结果。
例如,printf('Hello World!'); 将会输出字符串Hello World!。
3. 可以使用格式化字符串输出变量的值。
例如,printf('x = %d', x); 将会输出x的值,%d是占位符,表示输出整数。
4. 如果要输出多个变量,可以在格式化字符串中使用多个占位符。
例如,printf('x = %d, y = %f', x, y); 将会输出x和y的值,%d 表示整数,%f表示浮点数。
5. 如果要换行输出,可以在字符串中添加转义字符。
例如,printf('Hello
World!'); 将会输出两行,第一行是Hello,第二行是World!。
注意事项:
1. 在使用printf函数时,要确保所要输出的变量类型与格式化字符串中所指定的类型一致,否则会输出错误的结果。
2. 在使用printf函数时,要注意输出缓冲区的大小,以防止缓冲区溢出。
3. 在使用printf函数时,要注意输出的内容是否会影响程序的运行,以防止出现意外的错误。
51单片机之printf

51单片机之printftypedef char *va_list;我先在知道想要在51单片机使用printf有两种办法,一种是用库自己的printf,一种是写自己的printf,不过都很简单,我先介绍一下库的printf吧。
1、首先添加头文件#include2、配置一下串口,但是在串口初始化的时候TI必须为1,否则无法发送。
3、也可以使用中断接收,但是不要再中断里有TI=0;这条语句,否则也发送不成功。
就这么简单,你就可以使用printf(“”,x,x,x)了,嘎嘎!#include#include#define FOSC 11059200L//系统时钟频率#define BAUD 9600 //串口波特率void USART_Init();void Delay100us() //@11.0592MHz{unsigned char i, j;i = 2;j = 15;do{while (--j);} while (--i);}void main(){unsigned int a=99;//定义的数不能是char 或者unsigned charchar table[]="abc";char *abc=table;USART_Init();Delay100us();while(1){printf("%d %c %x %s",a,(char)a,a,table) ;//必须(char)a强制转换一下Delay100us();Delay100us();Delay100us();Delay100us ();Delay100us();Delay100us();Delay100us();Delay100us();}}void USART_Init(void){AUXR=0x40;//定时器1的速度是传统的8051的12倍不分频不可以位寻址TMOD=0x00;//设置定时器1为16位自动重装寄存器不可以位寻址SCON=0x50;//设置为8位波特率可变并允许串口接收使能PCON=0x00;//用定时器1模式0时于PCON无关了TL1=(65536-(FOSC/4/BAUD));TH1=(65536-(FOSC/4/BAUD))>;>;8;TI=1;//用系统自带的printf函数,TI必须等于1,否则无法发送,不能TR1=1;//使能定时器1ES=1; //串口中断使能EA=1; //全局中断使能}void Uart() interrupt 4 using 1{static unsigned char RI_date=0;if(RI)//接收成功RI置位{RI_date=SBUF;RI=0;}if(TI)//发送成功TI置位{//TI=0;//用系统的printf的时候,如果又用到中断的话,那么这句话就得屏蔽,否则无法发送}}还有一种就是自己写printf。
printf在单片机c语言中作用

printf在单片机c语言中作用以printf在单片机c语言中的作用为题,需要详细介绍和解释printf函数在单片机中的作用和使用方法。
首先,我们来了解一下单片机和c语言的基本概念。
单片机是一种集成了微处理器、存储器和各种外设接口的微型计算机系统。
它通常用于控制和管理各种电子设备。
而c语言是一种通用的高级程序设计语言,广泛应用于嵌入式系统开发领域,尤其是在单片机编程中。
在单片机中,printf函数是一个非常重要的输出函数,它可以将格式化的数据打印输出到终端设备或其他输出设备上。
printf函数的语法格式如下:printf("格式控制字符串", 参数列表);其中,格式控制字符串用来定义输出的格式,它可以包含普通字符和格式转换说明符。
参数列表是一个可选项,用来指定要输出的数据。
printf函数可以输出各种类型的数据,如整数、浮点数、字符等。
下面我们通过一些具体的例子来说明printf函数的使用方法。
1. 输出整数型数据:int num = 123;printf("整数:%d\n", num);上述代码将会在终端上输出"整数:123"。
2. 输出浮点型数据:float f = 3.14;printf("浮点数:%f\n", f);上述代码将会在终端上输出"浮点数:3.140000"。
3. 输出字符型数据:char ch = 'A';printf("字符:%c\n", ch);上述代码将会在终端上输出"字符:A"。
4. 输出字符串:char str[] = "Hello World!";printf("字符串:%s\n", str);上述代码将会在终端上输出"字符串:Hello World!"。
c51 printf使用方法

c51 printf使用方法C51是一款高性能的单片机,它具有强大的功能和广泛的应用场景。
在C51编程过程中,printf是一种非常常用的调试方式,可以使程序输出信息在串口终端中显示出来。
但是,printf的使用方法并不是那么显而易见,需要一些技巧和方法才能正确使用。
本文将从步骤上详细介绍C51中的printf使用方法。
1、先定义一个串口进行初始化,因为printf要通过串口发送数据给上位机,先要定义一个串口进行初始化。
UART是一种常见的串口通信方式,在C51的编程中也是最常用的一种。
在初始化串口的时候需要设置一些参数,如波特率、校验位等等,这些参数需要根据实际情况来选择。
2、定义一个函数,这个函数将主要用来将数据发送给串口,因为printf函数需要调用这个函数来发送数据。
这个函数的实现主要包括将要发送的数据保存到缓冲区,然后把缓冲区的数据通过串口发送出去。
需要注意的是,这个函数的设计要尽量简单,不要过于复杂,否则会影响程序的运行效率。
3、定义一个宏,这个宏将起到重要的作用,它将使printf函数输出的信息在屏幕上显示。
这个宏将用来格式化传入的各种参数,在消息传输时起到很大的作用。
宏定义时需要指定一些参数,这些参数需要根据具体的需求来确定。
4、使用printf函数,最后一步是使用printf函数将消息输出到屏幕上。
在使用printf函数时,需要注意传入的参数要根据之前定义的宏来格式化。
如果传入的参数没有被正确格式化,将无法正确地在屏幕上显示。
总之,printf是C51中非常重要的调试方式,它可以帮助程序员查看程序运行状态,了解程序执行情况。
但是,printf的使用方法需要一些技巧和方法才能正确使用。
只有掌握了这些方法,才能在C51编程中更加轻松地使用printf函数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
51中printf使用注意
C51标准串口发送程序(已C8051F120为例,注意C8051F120特殊功能寄存器是分页的)
/***********************************************************
函数名称:send_char_com
函数功能:向串口发送一字节字符
入口参数:unsigned char sendByte 一个字节字符(8 bit)
出口参数:无
备注:
***********************************************************/
void send_char_com(unsigned char sendByte)
{
char SFRPAGE_SA VE = SFRPAGE; //用到TI0(SCON0.1)SFR页:0
SFRPAGE = UART0_PAGE;
SBUF0=sendByte;
while (TI0== 0); //等待发送完毕
TI0= 0; //清发送中断标志TI0
SFRPAGE = SFRPAGE_SA VE;
}
/***********************************************************
函数名称:send_char_com
函数功能:向串口发送一个字符串
入口参数:unsigned char *str 字符串数组首地址
unsigned int strlen 该字符串长度
出口参数:无
备注:
***********************************************************/
void send_string_com( unsigned char *str, unsigned int strlen)
{
unsigned int k= 0 ;
do {
send_char_com(*(str + k));
k++;
}
while (k < strlen);
}
在C51中直接使用printf比自己编个串口发送字符串的函数方便,但有几个问题要注意的。
1. 使用printf之前要先包含stdio.h这个头文件
#include <stdio.h>
具体stdio.h包含的函数见下面网址
/support/man/docs/c51/c51_stdio_h.htm
2.
ES0=0; //禁止串口中断
SFRPAGE_SA VE = SFRPAGE; //c8051f120特殊功能寄存器分页
SFRPAGE = UART0_PAGE;
TI0=1;
printf ("\n\nTest complete.");
TI0=0; //可以省略
SFRPAGE = SFRPAGE_SA VE;
ES0=1; //打开串口中断
printf函数是调用putchar函数,从串口发送字符串的,可以从keil反汇编看出这一点。
在C51程序中printf的位置设一个断点,运行到断点处后,再一步步执行程序,可以看出,跳转到PRINTF执行。
PRINTF有很长一大段汇编,一步步执行。
运行到PUTCHAR处,这个就是串口发送字符串的函数。
可以看到有这么一句“C:0521 JNB TI0,C:0521”
第一次运行到这的时候,如果前面没有TI0=1,那么程序指针PC就一直在这条语句上判断,也就死在这里等待。
所以要使用printf,开头必须要先置TI0(传统51为TI)为1。
那么发送了第一个字节后,发送中断标志位TI0自动置1,再回到“C:0521 JNB TI0,C:0521”,接着发送第二个字节。
因为TI0为中断标志位,但如果程序使用了UAR0中断,那么在printf函数执行过程中就会不断调用中断函数(UART0_Interrupt),所以每次使用printf之前要先禁止串口中断(ES0=0)。
3. 由上面可以看到使用printf非常麻烦,其实可以用sprintf代替printf,只要在前面先定义一个存放字符串的数组。
……
unsigned char PrintChar[15]
……
SFRPAGE_SA VE = SFRPAGE; //C8051F120特殊功能寄存器分页
SFRPAGE = UART0_PAGE; //传统51单片机没有SFR分页
sprintf (PrintChar,"\nTest complete.");
send_string_com(s, 15);
SFRPAGE = SFRPAGE_SA VE;
上面总结得都是经验教训啊,在这个小小的bug上浪费了几天,记录下来,希望对大家有点帮助。
4. 当使用printf循环打印时要注意,下面程序是有问题的
pchar = XRAM_START;
for (i = 0; i < RAM_SIZE; i++)
{
*pchar= 0;
ES0=0;
TI0=1;
printf("writing 0x%04x:%u\n",(unsigned)pchar,(unsigned) *pchar);
ES0=1;
pchar++;
}
sprintf(PrintChar,"Test complete.\n");
send_string_com(PrintChar,15);
串口调试助手接收如下,可以看到第二次打印“write”时少了“w”。
用sprintf打印“Test”少了“T”。
可以重新看一下PUTCHAR处。
第一次发送字符的时候,由于TI0=1,所以在C:0x05B6的位置不会死等,执行C:0x05B9的时候TI0=0,接着A寄存器的值通过SBUF0发送。
由于串口发送的速率是很慢的(波特率才19200kBPS),所以,等在执行一遍上面的代码,回到C:0x05B6的时候,TI0还是为0,在C:0x05B6处等TI0变为1。
当串口发送完了之后,发送中断标志位TI0才被硬件置1。
此时PC机上的串口调试助手才显示刚发送的字符。
当发送最后一个字符时,C:0x05BB,把寄存在A的最后字符的ASCII代码复制给SUBF0后,并没有等待TI0变为1的指令,而是占用了下次for循环发送首字母的C:0x05B6,导致下次for循环首字母没有发送出去。
正确的办法是把TI0=1挪到for循环之后。
“Test”中的“T”没接收到也是同样的问题,最后一次发送的字符,没有等待TI0硬件置位的过程,造成发送的字符丢失。
正确的代码如下:
pchar = XRAM_START;
TI0=1;
for (i = 0; i < RAM_SIZE; i++)
{
*pchar= 0;
ES0=0;
printf("writing 0x%04x:%u\n",(unsigned)pchar,(unsigned) *pchar);
ES0=1;
pchar++;
}
while(TI0==0){};
TI0=0;
sprintf(PrintChar,"Test complete.\n");
send_string_com(PrintChar,15);。