微控制器 printf 移植過程

2021-07-05 23:56:09 字數 2307 閱讀 2843

在網上看到有人在微控制器上使用printf函式,心癢癢,也想用,看了網上的一些方法,

大都是51微控制器的,說的是在51微控制器編譯軟體庫中有自帶printf函式,也有自己實現

乙個自己的printf函式的,但是講的不詳細,看了好幾個部落格,東拼西湊,也在自己的

微控制器上弄出來了。

1,先進行用到的知識講解:

巨集va_start(ap,fmt) 、 va_end(ap) 、va_arg(a,t) 以及型別定義va_list 主要用於獲取 printf() 的引數,因為 printf() 引數數量可變,

// 參考

在我的編譯器安裝路徑中找到檔案 stdarg.h, 裡面有如下定義:

#define va_arg(ap, t)

\((ap) += _bnd(t, _aupbnd), *(t __near *)((ap) - _bnd(t, _adnbnd)))

#define va_end(ap)

(void)0

#define va_start(ap, a)

\(void)((ap) = (char __near *)&(a) + _bnd(a, _aupbnd))

#define _bnd(x, bnd)

(sizeof (x) + (bnd) & ~(bnd))

在另一檔案yvals.h 中找到 #define _aupbnd 1u   // 1u 即 1,後面的u是 unsigned 的意思

因此,可以得到 #define va_arg(ap, t)  ((ap) += sizeof(t), *(t*)((ap) - sizeof(t))

((ap) += sizeof(t), *(t*)((ap) - sizeof(t)) 是乙個逗號表示式,功能是先將指標 ap 指向下乙個引數,然後取出當前的引數資料。

#define va_start(ap, a)

(void)((ap) = (char *)&a + sizeof(a)) 功能是將 ap 指向第二個引數,例如 printf("%s\n", "hello world"); 第乙個引數"%s\n", 第二個引數"hello world"

2,下面貼出**。(只需要確定存在檔案stdarg.h ,實現針對特定晶元的函式 void uart1writebyte(unsigned char databyte),下面的**即可直接使用)

主要參考;

/** stdarg.h 針對特定晶元定義的標頭檔案,主要定義了va_start(ap,fmt);  va_end(ap); va_arg(a,t); 

* 特定晶元是因為有的晶元棧是自下而上,有的相反

*/#include

typedef char *va_list;

/** 將整形數字轉換成字元,如 0 轉換成 '0'

*/char number2char(int num) 

return ch;}/*

* 將整數 ch 按照十進位制/十六進製制轉換成字元, 因為我的微控制器8bit夠用了,所以使用unsigned char ch

*/char * convert_func(char *str, unsigned char ch, int num) 

return pstr;}/*

* 將 const char *fmt 和 va_list args 轉換成乙個字串,指標 buf 指向該字串

* 例如 printf("hello %s\n", "world"); 此函式將 "hello %s\n" 和 "world" 組合成 "hello world\r\n"

* 此函式參考 刪減改寫而成

*/int my_vsprintf(char *buf, const char *fmt, va_list args)

if (*fmt != '%') // 如果不是'%',儲存進str,如果不是,越過取下乙個字元,見switch (*fmt)

fmt++;

switch (*fmt)  // 這樣只能解析%c, %s, %x, %x, %d. 像 %02d 這種可以自己擴充套件

}*str = '\0';

return str-buf;}/*

* 將字串 unsigned char *string 逐個通過串列埠輸出

* 參考:

*/void sendstring(unsigned char *string) 

}  /** printf函式,例如:uart_printf("hello %s\n", "world");

* 參考:

*/void uart_printf(char *fmt,...)

參考:1,

2,3,

4,5,

6,

微控制器移植 UCOS移植 (函式詳解)

1.系統滴答定時器systick static void systickconfig void configure the systick handler priority nvic setpriority systick irqn,0x0 定時器中斷,1ms中斷一次 void systick ha...

微控制器printf的換行問題

因為串列埠軟體是在windows系統中的,而printf是在微控制器中執行的,所以我們平時所認為的換行,是需要 r n兩個符號的連用 r 是回車 return 返回到一行的頭部 和home鍵的效果相同 n是換行 newline 跳到下一行,列位置不變 r n連用,可達到跳到下一行行首的位置 wind...

51微控制器上移植C語言的printf

移植了c語言的printf 函式到51微控制器上,實現了在51微控制器的串列埠類pc端的printf 輸出。在專案工程中新增xxprintf.h和xxprintf.c檔案 在專案中需要使用xxprintf 函式的地方引入標頭檔案xxprintf.h,在xxprintf.h中引入微控制器相關標頭檔案 ...