前言
在 PC 上運行 C 語言時,prinf 輸出的內容會打印在電腦顯示器上,這是因為 prinf 默認的輸出設備就是顯示器。 而當我們在單片機上,需要通過 printf 函數將信息打印到串口,就要對 printf 函數的輸出進行重定向。
printf 輸出重定向的方法
printf 函數聲明如下:
int printf(const char *format, ...);
printf 函數根據 format 字符串給出的格式打印輸出到 stdout(標準輸出)中,當然,printf 函數是不會一個字符一個字符去輸出,它會調用更底層的 I/O 函數去逐個字符打印。
printf 是庫函數,不同編譯器對 C庫的底層實現機制是不同的,因此 printf 中調用了哪個底層 I/O 函數來輸出字符,需要根據當前使用的編譯器來確定。
我們實現 printf 輸出重定向的方法就是找到當前使用的編譯器中,printf 調用了哪個底層 I/O 函數來輸出字符,再改寫該函數,將字符通過串口輸出。
如何確定輸出字符的底層 I/O 函數?
以 Keil 為例,點擊菜單欄 Help ==> μVision Help 選項,打開幫助文檔。
如果你是51單片機項目,那么使用的編譯器是 Keil C51,打開的就是 C51 的幫助文檔; 如果你是 ARM 單片機項目,那么使用的編譯器是 Keil MDK,打開的就是 ARM 的幫助文檔。
查找 printf 關鍵字,可以看到 C51 的 printf 底層是調用 putchar 函數實現字符輸出的:
而 ARM 的 printf 函數底層是調用 fputc函數實現字符輸出的:
從上述的結果可知,要想通過 printf 向串口打印調試信息,C51 單片機需要改寫 putchar( ) 函數,而 ARM 單片機則需要改寫 fputc( ) 函數。
C51 和 ARM 項目中,printf 輸出重定向的方法是不一樣的,這就是有些人把 STM32 的 printf 搬到 C51 中會出錯的原因之一。
C51 重定向 printf 輸出的注意事項
C51 重定向 printf 函數的輸出到串口,需要改寫 putchar 函數,偽代碼如下:
char putchar (char ch)
{
SBUF0 = ch;
while( !(SCON0 & (1<<1)));
SCON0 &=~(1<<1);
return 0;
}
使用 printf 函數前,需要包含
51單片機重定向 printf 函數后,如果直接像 PC機或者是 32位單片機那樣使用 %d 占位符打印數值,輸出的數值可能是錯誤的,例如下面的代碼輸出結果可能就是不正確:
int i = 10;
printf("%d", i);
Keil 中擴展了 b、h、l 來設置字節寬度:
- b - 8位
- h - 16bit (默認)
- l - 32位
在 Keil C51中,用 printf 輸出一個單字節變量時,要使用%bd,例如:
unsigned char x = 'A';
printf("x: %bd\\n", x);
這些內容在 Keil C51 幫助文檔關于 printf 的章節中有提到:
擴展知識
不知道有沒小伙伴發現,如果項目中沒有重寫 putchar 或 fputc 函數,直接調用 printf 也不會報錯,只是 printf 打印的內容不知道輸出到哪里罷了。
printf 函數里面調用了更加底層的 putchar 或 fputc 函數而沒有報錯,說明在 C庫里面已經實現了 putchar 或 fputc 函數,那為什么我們在 C庫外重新實現 putchar 或 fputc 函數時,編譯器沒有報重復定義的錯誤呢?
這是因為在 C庫里,putchar 或 fputc 函數被定義成了弱函數(weak),當你定義了 putchar 或 fputc 函數,那么編譯時就使用你定義的函數,否則就使用 C庫中的 putchar 或 fputc 函數。
關于 C語言的弱函數相關內容,這里不再展開來講,感興趣的小伙伴可自行查閱相關資料。
-
單片機
+關注
關注
6067文章
44973瀏覽量
649539 -
顯示器
+關注
關注
22文章
5071瀏覽量
141675 -
C語言
+關注
關注
180文章
7631瀏覽量
141234 -
串口
+關注
關注
15文章
1587瀏覽量
79717 -
函數
+關注
關注
3文章
4379瀏覽量
64675
發布評論請先 登錄
stm32系列單片機之printf重定向
重定向printf() 函數
實現重定向printf()和scanf() 函數案例分析

51單片機printf重定向

單片機printf( )重定向到串口

【STM32Cube_09】重定向printf函數到串口輸出的多種方法

Keil下使用STlink重定向printf的配置

STM32單片機基礎09——重定向printf函數到串口輸出的多種方法

如何實現Printf()接口重定向到UART

評論