微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 单片机使用printf函数的两种办法

单片机使用printf函数的两种办法

时间:11-26 来源:互联网 点击:

T89C51和STC89C52之类的会造成内存不够用、堆栈溢出等等问题,所以以下程序都是基于STC12C5A60S2的,因为它含有内部拓展的1024byte的RAM,可以用来存储大数组

[cpp] view plaincopyprint?

01.//此程序主要用于uart发送(proteus不能仿真,但实际是可以运行的),输入换行符换行

02.#include

03.//stdio.h,stdarg.h用于vsprintf函数原型

04.#include

05.#include

06.

07.void delay(unsigned int z);

08.void uart_init(void);//串行口初始化

09.void sendbyte(unsigned char c);

10.void sendstring(unsigned char *string);

11.void uart_printf(const char *fmt,...);

12.

13.int main(void)

14.{

15. int a=99;

16. uart_init();

17. while(1)

18. {

19. uart_printf("10进制:%d 16进制:%x 字符格式:%c",a,a,a);

20. delay(1000);

21. }

22. return 0;

23.}

24.

25.void uart_init(void)

26.{

27. TMOD=0x20;//即0010 0000,定时器/计数器1,工作方式2

28. TH1=0xf3;//设置波特率为2400

29. TL1=0xf3;

30. TR1=1;//启动定时器/计数器1

31.

32. SCON=0x50; //0101 0000.串口工作方式1,允许串行控制

33. PCON=0x00;//设置SMOD=0

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仿真,但实际是可以工作的。?

注明:这篇文章是我在网上看到的,转载一下,自

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top