針對STM32的串口編程,可以通過USART1向計算機的串口調試助手打印數據,或者接收計算機串口調試助手的數據。
下面,我們可以實現STM32工程上的printf()函數了,方便用于程序開發中調試信息的打印。
方法1:使用MicroLIB庫
1.1 KEIL-MDK中的Use MicroLIB選項
在MDK開發環境中,
MicroLib是缺省c庫的備選庫,它可裝入少量內存中,與嵌入式應用程序配合使用,且這些應用程序不在操作系統中運行。MicroLib進行了高度優化以使代碼變得很小,功能比缺省c庫少,不具備某些ISO C特性,部分庫函數的運行速度也比較慢,如內存拷貝函數memcpy()。 MicroLib與缺省C庫之間的主要差異如下:
(1) MicroLib不符合 ISO C庫標準。不支持某些ISO特性,并且其他特性具有的功能也較少。
(2) MicroLib不符合IEEE 754二進制浮點算法標準。
(3) MicroLib進行了高度優化以使代碼變得很小。
(4) 無法對區域設置進行配置。缺省C區域設置是唯一可用的區域設置。
(5) 不能將main() 聲明為使用參數,并且不能返回內容。
(6) 不支持stdio,但未緩沖的stdin、stdout和stderr除外。
(7) MicroLib對C99函數提供有限的支持。 (8) MicroLib不支持操作系統函數。 (9) MicroLib不支持與位置無關的代碼。
(10) MicroLib不提供互斥鎖來防止非線程安全的代碼。 (11) MicroLib不支持寬字符或多字節字符串。
(12) 與stdlib不同,MicroLib不支持可選擇的單或雙區內存模型。MicroLib只提供雙區內存模型,即單獨的堆棧和堆區。
MicroLib提供了一個有限的stdio子系統,它僅支持未緩沖的stdin、stdout和stderr,那么也就是說勾選了Use MicroLib選項后,在代碼工程中就可以使用printf()函數咯?然而事實并非如此,這樣直接使用printf()函數,其打印的字符串最終不知道打印到何處。我們要做的是將調試信息打印到USART1中,所以需要對printf()函數所依賴的打印輸出函數fputc()重定向(MicroLib中的printf()函數打印操作依賴fputc() )。
1.2 重定向fputc函數
在MicroLib的stdio.h中,fputc()函數的原型為:
int fputc(int ch, FILE* stream)
此函數原本是將字符ch打印到文件指針stream所指向的文件流去的,現在我們不需要打印到文件流,而是打印到串口1。基于前面的代碼:
#include注意:需要包含頭文件stdio.h,否則FILE類型未定義。int fputc(int ch, FILE* stream) { //USART_SendData(USART1, (unsigned char) ch); //while (!(USART1->SR & USART_FLAG_TXE)); USART_SendChar(USART1, (uint8_t)ch); return ch; }
勾選了Use MicroLib選項,重定向fputc()函數后,我們就可以在工程代碼中使用printf()函數了:
int main(void) { USART_Configuration(); printf(" stm32f103rct6 "); printf(" Cortex-M3 "); while (1); return 0; }printf()函數的使用方法跟之前一樣,運行結果:
方法2:不使用MicroLIB庫
2.1 半主機模式
半主機模式是ARM的一種機制,實現將來ARM應用程序代碼的輸入/輸出請求傳送至運行著調試器的主機。例如,設置使用半主機模式下的ARM應用程序,可以使用printf()和scanf()來使用主機的顯示器和鍵盤,而不需要在ARM系統上搭配顯示器和鍵盤。
半主機通過一組定義好的軟件指令(如SVC)來實現的,這些指令在程序控制下產生異常,ARM應用程序調用半主機對應的異常處理函數,然后調試代理處理該異常。
第二段話感覺理解起來有點模糊,但是第一段還是懂它在講什么的。一般的ARM應用程序中并不需要半主機操作,在這里為確保ARM應用程序中沒有鏈接MicroLib的半主機相關函數,我們要取消ARM的半主機工作模式。
2.2 實現代碼
在工程中加上如下代碼:
#pragma import(__use_no_semihosting) struct __FILE { int handle; }; FILE __stdout; _sys_exit(int x) { x = x; } int fputc(int ch, FILE *f){ while((USART1->SR&0X40)==0); USART1->DR = (u8) ch; return ch; }上面的代碼摘自正點原子的范例程序,具體每一行的意義目前也不大清楚。這樣操作后,在不使用MicroLib的前提下,仍能使用printf()函數將調試信息打印到USART1上了。
審核編輯:劉清
-
STM32
+關注
關注
2266文章
10876瀏覽量
354928 -
串口調試
+關注
關注
2文章
267瀏覽量
24694 -
printf函數
+關注
關注
0文章
31瀏覽量
5880 -
USART1
+關注
關注
0文章
9瀏覽量
3670
原文標題:使用KEIL-MDK開發STM32時,兩種printf()函數重定向的方法
文章出處:【微信號:雨飛工作室,微信公眾號:雨飛工作室】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論