单片机使用printf函数的两种办法
34. IE=0x00; //由于是查询方式,故需要禁止中断,CPU不允许中断,串行不允许中断
35.
36.}
37.
38.void delay(unsigned int z)
39.{
40. unsigned int x,y;
41. for(x=z;x>0;x--)
42. for(y=110;y>0;y--);
43.}
44.
45.void sendbyte(unsigned char c)
46.{
47. if(c==)//如果遇到就换行
48. {
49. //发送CR(carriage return)
50. SBUF=0x0D;
51. while(!TI);//等待发送完成
52. TI=0;
53.
54. //发送 LF(NL line feed,new line)
55. SBUF=0x0A;
56. while(!TI);//等待发送完成
57. TI=0;
58. }
59. else
60. {
61. SBUF=c;
62. while(!TI);//等待发送完成
63. TI=0;
64. }
65.}
66.
67.void sendstring(unsigned char *string)//此处*string相当于数组
68.{
69. while(*string!= )//判断是否到字符串末尾
70. {
71. sendbyte(*string);
72. string++;
73. }
74.}
75.
76.void uart_printf(const char *fmt,...)
77.{
78. va_list ap;
79. char xdata string[1024];//访问内部拓展RAM,非访问外部RAM,不能超过内部拓展RAM大小(此处为1024)
80.
81. va_start(ap,fmt);
82. vsprintf(string,fmt,ap);//此处也可以使用sprintf函数,用法差不多,稍加修改即可,此处略去
83. sendstring(string);
84. va_end(ap);
85.}
//此程序主要用于uart发送(proteus不能仿真,但实际是可以运行的),输入换行符换行
#include
//stdio.h,stdarg.h用于vsprintf函数原型
#include
#include
void delay(unsigned int z);
void uart_init(void);//串行口初始化
void sendbyte(unsigned char c);
void sendstring(unsigned char *string);
void uart_printf(const char *fmt,...);
int main(void)
{
int a=99;
uart_init();
while(1)
{
uart_printf("10进制:%d 16进制:%x 字符格式:%c",a,a,a);
delay(1000);
}
return 0;
}
void uart_init(void)
{
TMOD=0x20;//即0010 0000,定时器/计数器1,工作方式2
TH1=0xf3;//设置波特率为2400
TL1=0xf3;
TR1=1;//启动定时器/计数器1
SCON=0x50; //0101 0000.串口工作方式1,允许串行控制
PCON=0x00;//设置SMOD=0
IE=0x00; //由于是查询方式,故需要禁止中断,CPU不允许中断,串行不允许中断
}
void delay(unsigned int z)
{
unsigned int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void sendbyte(unsigned char c)
{
if(c==)//如果遇到就换行
{
//发送CR(carriage return)
SBUF=0x0D;
while(!TI);//等待发送完成
TI=0;
//发送 LF(NL line feed,new line)
SBUF=0x0A;
while(!TI);//等待发送完成
TI=0;
}
else
{
SBUF=c;
while(!TI);//等待发送完成
TI=0;
}
}
void sendstring(unsigned char *string)//此处*string相当于数组
{
while(*string!= )//判断是否到字符串末尾
{
sendbyte(*string);
string++;
}
}
void uart_printf(const char *fmt,...)
{
va_list ap;
char xdata string[1024];//访问内部拓展RAM,非访问外部RAM,不能超过内部拓展RAM大小(此处为1024)
va_start(ap,fmt);
vsprintf(string,fmt,ap);//此处也可以使用sprintf函数,用法差不多,稍加修改即可,此处略去
sendstring(string);
va_end(ap);
}
最后简单总结 :其中第一种方法用于中断方式工作会有问题,因为其底层是调用putchar函数实现的,工作方式为中断,但是比较简单,可以通过proteus仿真;第二种方法更完善,不过程序比较复杂,不能使用proteus仿真,但实际是可以工作的。
注明:这篇文章是我在网上看到的,转载一下,自己做个备份,同时也希望更多的人看到它,学习到更多的东西。技术源于积累,以此共勉。
评论