新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 單片機(jī)使用printf函數(shù)的兩種辦法

單片機(jī)使用printf函數(shù)的兩種辦法

作者: 時(shí)間:2016-11-26 來(lái)源:網(wǎng)絡(luò) 收藏
今天就簡(jiǎn)單來(lái)說(shuō)說(shuō)怎么在51單片機(jī)中使用"printf"函數(shù):包括使用自帶的printf函數(shù)和自己動(dòng)手寫一個(gè)printf函數(shù),再貼代碼之前先介紹幾個(gè)相關(guān)的知識(shí),主要用于自己寫printf函數(shù)。

①C語(yǔ)言函數(shù):vsprintf,

本文引用地址:http://m.butianyuan.cn/article/201611/321829.htm

其原型為int vsprintf(char *string, char *format, va_list param);,作用為將param按格式format寫入字符串string中,因此他可以用于將任何格式數(shù)據(jù)轉(zhuǎn)化為字符串?dāng)?shù)據(jù),比如把整數(shù)97轉(zhuǎn)化為ASCII碼的97的程序就像下面這樣vsprintf(string,"%d",97),當(dāng)然還有一點(diǎn)需要注意:在keil里面使用sprintf需要包含stdio.h這個(gè)頭文件(當(dāng)然這里也可以使用sprintf,作用完全差不多,只需要稍加修改即可,不多介紹)。說(shuō)到這里,再來(lái)說(shuō)說(shuō)另一個(gè)函數(shù)itoa吧,其實(shí)他比vsprintf更簡(jiǎn)單,其原型為char *itoa(int value, char *string, int radix),作用為將value按radix進(jìn)制寫入到string字符串中,使用時(shí)需要包含頭文件stdlib.h,可是在keil里面卻無(wú)法使用,頭文件里面不包含itoa,即使把VC里面的復(fù)制進(jìn)來(lái)貌似還是不行,呵呵,目前不知道原因。

②可變參數(shù)函數(shù)

具體來(lái)說(shuō)就是stdarg.h里面的這幾個(gè)函數(shù)va_start,va_arg,va_list,va_end,這幾個(gè)參數(shù)用于開(kāi)辟一段內(nèi)存區(qū)域,可以配合vsprintf使用,但是對(duì)內(nèi)存使用較大,需要單片機(jī)具備一定的RAM,否則程序就算能編譯通過(guò)也是無(wú)法運(yùn)行的,用法見(jiàn)這里http://blog.csdn.net/googlemi/article/details/8988567

③內(nèi)部拓展RAM

定義:集成在單片機(jī)內(nèi)部的數(shù)據(jù)存儲(chǔ)器,在物理上是內(nèi)部,但邏輯上是外部,訪問(wèn)時(shí)需要使用MOVX或者xdata訪問(wèn),具體可以看STC8051手冊(cè),如下所示

從這里可以看出,STC12C5A60S2單片機(jī)內(nèi)部含有1024byte=1Kbyte的內(nèi)部拓展RAM,在訪問(wèn)的時(shí)候,使用C語(yǔ)言的時(shí)候,需要加上xdata才可以訪問(wèn),使用匯編的時(shí)候需要用MOVX指令訪問(wèn)。

到這里我們先來(lái)算一算STC12C5A60S2單片機(jī)在不接外部RAM的情況下總的RAM大小,先看一下內(nèi)部的RAM分布圖

:內(nèi)部RAM(256byte)包括三部分:低128byte,高128byte和特殊功能寄存器區(qū),特別注意和51不同,他的特殊功能寄存器和高128byte地址重疊,但是物理上是分開(kāi)的,所有內(nèi)部可用的RAM有256byte,所以到此為止可以得到內(nèi)部RAM大小總共有:256byte+1024byte=1280byte

說(shuō)了這么多,下面不多說(shuō),直接上程序

《一》直接使用系統(tǒng)自帶的printf函數(shù):特別注意需要置位TI=1,否則是無(wú)法發(fā)送的,程序如下:

[cpp] view plaincopyprint?

01.//此程序主要用于uart發(fā)送(proteus終端不能顯示漢字,但串口助手可以),輸入換行符換行

02.#include

03.//stdio.h,string.h用于printf函數(shù)原型

04.#include

05.

06.

07.void delay(unsigned int z);

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

09.

10.int main(void)

11.{

12. int a=99;

13. char *string="abde";

14. uart_init();

15. while(1)

16. {

17. printf("%d %x %c %s %p",a,a,(char)a,string,string);

18. delay(1000);

19. }

20. return 0;

21.}

22.

23.void uart_init(void)

24.{

25. TMOD=0x20;//即0010 0000,定時(shí)器/計(jì)數(shù)器1,工作方式2

26. TH1=0xfd;//設(shè)置波特率為9600

27. TL1=0xfd;

28. TR1=1;//啟動(dòng)定時(shí)器/計(jì)數(shù)器1

29.

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

31. PCON=0x00;//設(shè)置SMOD=0

32. IE=0x90; //CPU允許中斷,串行允許中斷

33.

34. TI=1;//直接使用printf必須加入此句才能實(shí)現(xiàn)發(fā)送

35.}

36.

37.void delay(unsigned int z)

38.{

39. unsigned int x,y;

40. for(x=z;x>0;x--)

41. for(y=110;y>0;y--);

42.}

//此程序主要用于uart發(fā)送(proteus終端不能顯示漢字,但串口助手可以),輸入換行符換行

#include

//stdio.h,string.h用于printf函數(shù)原型

#include

void delay(unsigned int z);

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

int main(void)

{

int a=99;

char *string="abde";

uart_init();

while(1)

{

printf("%d %x %c %s %p",a,a,(char)a,string,string);

delay(1000);

}

return 0;

}

void uart_init(void)

{

TMOD=0x20;//即0010 0000,定時(shí)器/計(jì)數(shù)器1,工作方式2

TH1=0xfd;//設(shè)置波特率為9600

TL1=0xfd;

TR1=1;//啟動(dòng)定時(shí)器/計(jì)數(shù)器1

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

PCON=0x00;//設(shè)置SMOD=0

IE=0x90; //CPU允許中斷,串行允許中斷

TI=1;//直接使用printf必須加入此句才能實(shí)現(xiàn)發(fā)送

}

void delay(unsigned int z)

{

unsigned int x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

《二》自己動(dòng)手寫一個(gè)類似printf的函數(shù):uart_printf

但是這種情況占用RAM較多,因?yàn)樾枰_(kāi)辟大數(shù)組,所以需要使用拓展型的51單片機(jī),普通的AT89C51和STC89C52之類的會(huì)造成內(nèi)存不夠用、堆棧溢出等等問(wèn)題,所以以下程序都是基于STC12C5A60S2的,因?yàn)樗袃?nèi)部拓展的1024byte的RAM,可以用來(lái)存儲(chǔ)大數(shù)組

[cpp] view plaincopyprint?

01.//此程序主要用于uart發(fā)送(proteus不能仿真,但實(shí)際是可以運(yùn)行的),輸入換行符換行

02.#include

03.//stdio.h,stdarg.h用于vsprintf函數(shù)原型

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進(jìn)制:%d 16進(jìn)制:%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,定時(shí)器/計(jì)數(shù)器1,工作方式2

28. TH1=0xf3;//設(shè)置波特率為2400

29. TL1=0xf3;

30. TR1=1;//啟動(dòng)定時(shí)器/計(jì)數(shù)器1

31.

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

33. PCON=0x00;//設(shè)置SMOD=0


上一頁(yè) 1 2 下一頁(yè)

關(guān)鍵詞: 單片機(jī)printf函

評(píng)論


技術(shù)專區(qū)

關(guān)閉