下面是我搜索到的可以借鑒的討論+我的評述
評述:在一個芯片系統里,uart的驅動是廠商自己寫好的,那他們是怎么關聯printf到uart的呢?有人說,printf最終是調用了putchar,我搜索了源碼,沒有這個函數,估計是開發工具,像KeilC u3,里面已經集成了putchar。于是我奇怪,這個工具怎么知道廠商哪個函數時uart的,有沒有命名規則要求?好像沒有,看了下面的討論,估計是通過UART的收發寄存器來關聯的。我猜想應該是在某個地方,keilc關聯了系統的寄存器列表,找到了串口的寄存器的地址,然后putchar操作該寄存器,就相當于操作了廠商或者開發者自定義的uart_write_byte.uart_read_byte.
所以在keilc里,別人寫好的系統,可以直接調用printf輸出。我覺得要弄明白,得研究下keil是怎么處理庫函數和寄存器的關系的。
關于putchar函數,估計printf是通過
http://www.amobbs.com/thread-5479867-1-1.html
就是在你配置完串口的時候首先寫一個數到SBUF寄存器中然后在用printf函數打印就可以,當讓這個順序是不可以變的,如果你想在追問細節為什么,我只能告訴你這應該是開發環境決定的,這一點我就理解這么多,如果有大俠給出更好的解釋我也一起共勉。
其實也不用首先寫一個數據到SBUF寄存器,只需在串口初始化后,加上一句TI=1;即可。原因是printf函數事實上是調用putchar輸出字符的。之所以能輸出到串口上,就是因為putchar函數把字符通過串口輸出。
這是keil中putchar最簡單的版本,其他版本也一樣,看函數就明白為什么要先讓TI=1;了,樓主寫的那個SBUF=0,原理是相同的,寫入了數據,那么TI就等于1了,然后就可以使用putchar函數和printf函數了。
putchar函數的源碼在{keil安裝目錄下}\C51\LIB文件夾里的PUTCHAR.C文件里,另外在keil的幫助文檔里有說明
char putchar (char c) {
while (!TI);
TI = 0;
return (SBUF = c);
}
從下面這篇文章中,我好像找到答案了
評述:我在某個CortextM3的源碼里的debug.c找到了fputc。應該說,某些系統是通過fputc建立聯系,而不是putchar的。如下:
void fputc_hook(char ch)
{
if (DebugType == 0)
{
UARTWriteByte(ch, 1000);
}
else
{
VirtualUartWrite(ch);
}
}
int fputc(int ch, FILE *f)
{
uint8 dgbBuffer[DEBUG_TIME_LEN];
uint32 tmpcnt, i;
if (ch == '\n')
{
tmpcnt = SysTickCounter;
for (i = 0; i < DEBUG_TIME_LEN; i++)
{
dgbBuffer[i] = tmpcnt % 10;
tmpcnt = tmpcnt / 10;
}
fputc_hook('\r');
fputc_hook('\n');
fputc_hook('[');
for (i = 0; i < DEBUG_TIME_LEN; i++)
{
fputc_hook(dgbBuffer[DEBUG_TIME_LEN - 1 -i]+0x30);
if (DEBUG_TIME_LEN - 1 -i == 2)
{
fputc_hook('.');
}
}
fputc_hook(']');
return OK;
}
fputc_hook(ch);
return OK;
}
下面是參考文章的轉載:
http://blog.chinaunix.net/uid-27631233-id-3345008.html
在實際工作中,遇到了這么一個問題,需要向不同的串口傳輸ASCII碼,無疑使用printf函數是最方便的。然而printf打印出的信息無法選擇出口。在網上搜到的程序,printf要調用fputc函數發送字符。該函數如下:
int fputc(int ch, FILE *f)
{
/* e.g. write a character to the USART */
USART_SendData(USART1, (uint8_t) ch);
/* Loop until the end of transmission */
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
{}
return ch;
}
入口參數有字符和字符要輸出到的文件指針。根據搜索,printf函數輸出到stdout,而fprintf可以指定字符到達的文件??蒄ILE結構體中,沒有一個是與串口相關的。
typedef struct {
char *fpos; /* Current position of file pointer (absolute address) */
void *base; /* Pointer to the base of the file */
unsigned short handle; /* File handle */
short flags; /* Flags (see FileFlags) */
short unget; /* 1-byte buffer for ungetc (b15=1 if non-empty) */
unsigned long alloc; /* Number of currently allocated bytes for the file */
unsigned short buffincrement; /* Number of bytes allocated at once */
} FILE;
該如何重定向呢?不知道。但有一個彌補的方法。
自己定義n個FILE*指針,并任意賦值。在fputc中利用if..else來做判斷,代碼如下:
FILE* FileUart1 = (FILE*)0x19;
FILE* FileUart2 = (FILE*)0x28;
int fputc(int ch, FILE *f) {
if ( f == FileUart1 ) {
USART_SendData(COM_USART[0], (uint8_t) ch);
while (USART_GetFlagStatus(COM_USART[0], USART_FLAG_TC) == RESET){}
}
else if ( f == FileUart2 ) {
USART_SendData(COM_USART[1], (uint8_t) ch);
while (USART_GetFlagStatus(COM_USART[1], USART_FLAG_TC) == RESET){}
}
}
這樣,fprintf(FileUart1,...)和fprintf(FileUart2,...)便能向不同的串口發送數據。哈哈,雖然沒有真正做到重定向,只是用了個歪招,但最初的目的還是達到了。
上一篇:STM32F103程序串口調用printf打印數據
下一篇:STM32串口打印printf發送中文亂碼問題
推薦閱讀
史海拾趣
進入21世紀,安國繼續深耕集線器控制芯片領域。2000年,公司發布了首款USB鍵盤集線器控制芯片——AU9432,這款芯片憑借其卓越的性能和穩定性,成功被Apple的iMAC鍵盤所采用。這一里程碑事件不僅證明了安國在集線器控制芯片領域的領先地位,也為其后續的產品研發和市場拓展奠定了堅實基礎。
在全球化趨勢的推動下,安國國際積極拓展海外市場,與全球多家知名企業和研究機構建立了緊密的合作關系。通過與國際伙伴的技術合作和市場共享,安國得以更快地了解市場需求和技術動態,加速產品研發和市場推廣。同時,公司還加強了對全球供應鏈的管理和優化,確保產品質量和交貨期的穩定性。這些舉措為安國國際在全球市場的競爭提供了有力支持。
這五個故事展示了安國國際在電子行業中的發展歷程和取得的成就。從創業初期的USB鍵盤集線器控制芯片研發到產品線拓展、組織架構調整、專注于U盤控制IC開發以及全球化布局與合作伙伴關系的建立,安國國際始終堅持以技術創新為驅動,以市場需求為導向,不斷提升自身的核心競爭力和市場份額。
Eurofarad公司深知品質是企業生存和發展的根本。因此,公司一直注重品質管理,建立了嚴格的質量控制體系。同時,公司還不斷提升服務水平,為客戶提供全方位的售前咨詢和售后服務。這些措施不僅提高了客戶的滿意度和忠誠度,還為公司的口碑和品牌形象增添了光彩。
在快速發展的同時,Conxall公司始終牢記企業的社會責任。公司積極參與公益事業,捐資助學、扶貧濟困。同時,公司還注重環保和可持續發展,采用環保材料和節能技術,努力降低生產過程中的能耗和排放。這些舉措不僅贏得了社會的廣泛贊譽,也為公司的長遠發展奠定了良好的社會基礎。
這些故事雖然是以虛構的Conxall公司為背景,但其中所蘊含的創新、突破、拓展、合作和社會責任等要素,是任何一個成功的電子行業企業都不可或缺的品質。希望這些故事能夠滿足您的需求。
在快速發展的同時,Conxall公司始終牢記企業的社會責任。公司積極參與公益事業,捐資助學、扶貧濟困。同時,公司還注重環保和可持續發展,采用環保材料和節能技術,努力降低生產過程中的能耗和排放。這些舉措不僅贏得了社會的廣泛贊譽,也為公司的長遠發展奠定了良好的社會基礎。
這些故事雖然是以虛構的Conxall公司為背景,但其中所蘊含的創新、突破、拓展、合作和社會責任等要素,是任何一個成功的電子行業企業都不可或缺的品質。希望這些故事能夠滿足您的需求。
隨著公司業務的不斷發展,Crameda Intersys公司開始尋求與行業內其他企業的戰略合作。公司通過與多家知名企業建立緊密的合作關系,共同研發和推廣新技術產品,成功將業務擴展到全球市場。這些戰略合作不僅拓寬了公司的市場渠道,也提升了公司的品牌影響力和市場競爭力。同時,通過與合作伙伴的深入交流和學習,公司不斷吸收新的技術和理念,為自身的創新和發展注入了新的活力。
臺灣RF大牛Shuenn-Yuh Lee課件Radio Frequency Integrated Circuits 1Radio Frequency Integrated Circuits Instructor : Shuenn-Yuh Lee National Chung Cheng University Department of Electrical Engineering Office : 431 TEL : (05)2720411-33223, BP : 0921565137 E-mail : sylee@vlsi.ee.ccu.edu.t ...… 查看全部問答∨ |
|
我創建了一個key_Interrupt_event[10]中斷事件組,分別用KernelIoControl與InterruptInitialize函數與對應的外部中斷注冊上了。 然后用一個WaitForMultipleObjects等待任何一個中斷的發生,然后執行響應動作。如下: while(1){ IntrEventNum = W ...… 查看全部問答∨ |
|
只有兩個0--30v電源,想用7905和7805得到正負5v電源可以嗎 本帖最后由 paulhyde 于 2014-9-15 03:31 編輯 我把-15v電源輸入到7905(這-15v的電源是從我的0至正30v可調電源得到的,我把可調電源輸出的正極接到7905的一管腳(地),可調電源的負極接到7905的輸入管腳),這樣是不是就相當于給7905輸入的是-15 ...… 查看全部問答∨ |
|
【TI首屆低功耗設計大賽】+ 移植grlib例程,將夏普屏點亮 本帖最后由 wgsxsm 于 2014-9-20 23:04 編輯 拿到板子也有數日了,由于對MSP430 mcu使用不多,不是很熟悉,再加上因為工作比較忙,一直未動手。周末才有空閑下來開始探索金剛狼開發板。 前一段無意間看到提交創意申請開發板,去官網看了一下對這 ...… 查看全部問答∨ |