下面是我搜尋到的可以借鑑的討論+我的評述
評述:在乙個晶元系統裡,uart的驅動是廠商自己寫好的,那他們是怎麼關聯printf到uart的呢?有人說,printf最終是呼叫了putchar,我搜尋了原始碼,沒有這個函式,估計是開發工具,像keilc u3,裡面已經整合了putchar。於是我奇怪,這個工具怎麼知道廠商哪個函式時uart的,有沒有命名規則要求?好像沒有,看了下面的討論,估計是通過uart的收發暫存器來關聯的。我猜想應該是在某個地方,keilc關聯了系統的暫存器列表,找到了串列埠的暫存器的位址,然後putchar操作該暫存器,就相當於操作了廠商或者開發者自定義的uart_write_byte.uart_read_byte.
所以在keilc裡,別人寫好的系統,可以直接呼叫printf輸出。我覺得要弄明白,得研究下keil是怎麼處理庫函式和暫存器的關係的。
關於putchar函式,估計printf是通過
就是在你配置完串列埠的時候首先寫乙個數到sbuf暫存器中然後在用printf函式列印就可以,當讓這個順序是不可以變的,如果你想在追問細節為什麼,我只能告訴你這應該是開發環境決定的,這一點我就理解這麼多,如果有大俠給出更好的解釋我也一起共勉。
其實也不用首先寫乙個資料到sbuf暫存器,只需在串列埠初始化後,加上一句ti=1;即可。原因是printf函式事實上是呼叫putchar輸出字元的。之所以能輸出到串列埠上,就是因為putchar函式把字元通過串列埠輸出。
這是keil中putchar最簡單的版本,其他版本也一樣,看函式就明白為什麼要先讓ti=1;了,樓主寫的那個sbuf=0,原理是相同的,寫入了資料,那麼ti就等於1了,然後就可以使用putchar函式和printf函式了。
putchar函式的原始碼在\c51\lib資料夾裡的putchar.c檔案裡,另外在keil的幫助文件裡有說明
char putchar (char c)
評述:我在某個cortextm3的原始碼裡的debug.c找到了fputc。應該說,某些系統是通過fputc建立聯絡,而不是putchar的。如下:
void fputc_hook(char ch)
else
}int fputc(int ch, file *f)
fputc_hook('\r');
fputc_hook('\n');
fputc_hook('[');
for (i = 0; i < debug_time_len; i++)
}fputc_hook(']');
return ok;
}fputc_hook(ch);
return ok;
}
在實際工作中,遇到了這麼乙個問題,需要向不同的串列埠傳輸ascii碼,無疑使用printf函式是最方便的。然而printf列印出的資訊無法選擇出口。在網上搜到的程式,printf要呼叫fputc函式傳送字元。該函式如下:
int fputc(int ch, file *f)
return ch; }
入口引數有字元和字元要輸出到的檔案指標。根據搜尋,printf函式輸出到stdout,而fprintf可以指定字元到達的檔案。可file結構體中,沒有乙個是與串列埠相關的。
typedef struct file;
該如何重定向呢?不知道。但有乙個彌補的方法。
自己定義n個file*指標,並任意賦值。在fputc中利用if..else來做判斷,**如下:
file* fileuart1 = (file*)0x19;
file* fileuart2 = (file*)0x28;
int fputc(int ch, file *f) }
else if ( f == fileuart2 ) }
}這樣,fprintf(fileuart1,...)和fprintf(fileuart2,...)便能向不同的串列埠傳送資料。哈哈,雖然沒有真正做到重定向,只是用了個歪招,但最初的目的還是達到了。
如果哪位牛人能告知如何真正重定向,感激感激~~~~
還要請問,如何使用__debug__巨集定義才能使fprintf("val is %d", val)或fprintf("val1 is %d, val2 is %d", val1, val2)在程式中任意被編譯上或編譯掉。當然,不包括#ifdef..#endif方法。不這麼做就是為了**清晰一些,便於閱讀。謝謝啊~~
重定向printf到串列埠
參考鏈結 stm32 hal庫學習 三 adc取樣以及printf的使用 stm32cubeide 二 printf重定向設定 stm32cubeide實現printf重定向輸出到串列埠 在main.c檔案中插入如下 user code begin 0 include stdio.h ifdef g...
VC程式重定向printf到console視窗
本方法簡單易用,適用於vc6 vc.net2003 假定你建立的vc應用程式叫做imagefilter,那麼只需新增如下 即可 1 開啟imagefilter.cpp檔案,增加 include include allocconsole hcrt open osfhandle long getstdh...
COIDE下重定向printf
在stm32下,可能需要重定向printf到串列埠,而coide下提供了重定向printf的元件,使用起來是相當方便的。先add這個元件,然後在printf.c下稍加修改即可使用了。先新增串列埠的標頭檔案。然後,修改printchar函式,讓它使用串列埠傳送資料。此外,還需要注釋這一句,否則鏈結時會...