針對(duì)STM32的串口編程,可以通過(guò)USART1向計(jì)算機(jī)的串口調(diào)試助手打印數(shù)據(jù),或者接收計(jì)算機(jī)串口調(diào)試助手的數(shù)據(jù)。
下面,我們可以實(shí)現(xiàn)STM32工程上的printf()函數(shù)了,方便用于程序開(kāi)發(fā)中調(diào)試信息的打印。
方法1:使用MicroLIB庫(kù)
1.1 KEIL-MDK中的Use MicroLIB選項(xiàng)
在MDK開(kāi)發(fā)環(huán)境中,
MicroLib是缺省c庫(kù)的備選庫(kù),它可裝入少量?jī)?nèi)存中,與嵌入式應(yīng)用程序配合使用,且這些應(yīng)用程序不在操作系統(tǒng)中運(yùn)行。MicroLib進(jìn)行了高度優(yōu)化以使代碼變得很小,功能比缺省c庫(kù)少,不具備某些ISO C特性,部分庫(kù)函數(shù)的運(yùn)行速度也比較慢,如內(nèi)存拷貝函數(shù)memcpy()。 MicroLib與缺省C庫(kù)之間的主要差異如下:
(1) MicroLib不符合 ISO C庫(kù)標(biāo)準(zhǔn)。不支持某些ISO特性,并且其他特性具有的功能也較少。
(2) MicroLib不符合IEEE 754二進(jìn)制浮點(diǎn)算法標(biāo)準(zhǔn)。
(3) MicroLib進(jìn)行了高度優(yōu)化以使代碼變得很小。
(4) 無(wú)法對(duì)區(qū)域設(shè)置進(jìn)行配置。缺省C區(qū)域設(shè)置是唯一可用的區(qū)域設(shè)置。
(5) 不能將main() 聲明為使用參數(shù),并且不能返回內(nèi)容。
(6) 不支持stdio,但未緩沖的stdin、stdout和stderr除外。
(7) MicroLib對(duì)C99函數(shù)提供有限的支持。 (8) MicroLib不支持操作系統(tǒng)函數(shù)。 (9) MicroLib不支持與位置無(wú)關(guān)的代碼。
(10) MicroLib不提供互斥鎖來(lái)防止非線程安全的代碼。 (11) MicroLib不支持寬字符或多字節(jié)字符串。
(12) 與stdlib不同,MicroLib不支持可選擇的單或雙區(qū)內(nèi)存模型。MicroLib只提供雙區(qū)內(nèi)存模型,即單獨(dú)的堆棧和堆區(qū)。
MicroLib提供了一個(gè)有限的stdio子系統(tǒng),它僅支持未緩沖的stdin、stdout和stderr,那么也就是說(shuō)勾選了Use MicroLib選項(xiàng)后,在代碼工程中就可以使用printf()函數(shù)咯?然而事實(shí)并非如此,這樣直接使用printf()函數(shù),其打印的字符串最終不知道打印到何處。我們要做的是將調(diào)試信息打印到USART1中,所以需要對(duì)printf()函數(shù)所依賴的打印輸出函數(shù)fputc()重定向(MicroLib中的printf()函數(shù)打印操作依賴fputc() )。
1.2 重定向fputc函數(shù)
在MicroLib的stdio.h中,fputc()函數(shù)的原型為:
int fputc(int ch, FILE* stream)
此函數(shù)原本是將字符ch打印到文件指針stream所指向的文件流去的,現(xiàn)在我們不需要打印到文件流,而是打印到串口1?;谇懊娴拇a:
#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選項(xiàng),重定向fputc()函數(shù)后,我們就可以在工程代碼中使用printf()函數(shù)了:
int main(void)
{
USART_Configuration();
printf("
stm32f103rct6
");
printf("
Cortex-M3
");
while (1);
return 0;
}
printf()函數(shù)的使用方法跟之前一樣,運(yùn)行結(jié)果:
方法2:不使用MicroLIB庫(kù)
2.1 半主機(jī)模式
半主機(jī)模式是ARM的一種機(jī)制,實(shí)現(xiàn)將來(lái)ARM應(yīng)用程序代碼的輸入/輸出請(qǐng)求傳送至運(yùn)行著調(diào)試器的主機(jī)。例如,設(shè)置使用半主機(jī)模式下的ARM應(yīng)用程序,可以使用printf()和scanf()來(lái)使用主機(jī)的顯示器和鍵盤(pán),而不需要在ARM系統(tǒng)上搭配顯示器和鍵盤(pán)。
半主機(jī)通過(guò)一組定義好的軟件指令(如SVC)來(lái)實(shí)現(xiàn)的,這些指令在程序控制下產(chǎn)生異常,ARM應(yīng)用程序調(diào)用半主機(jī)對(duì)應(yīng)的異常處理函數(shù),然后調(diào)試代理處理該異常。
第二段話感覺(jué)理解起來(lái)有點(diǎn)模糊,但是第一段還是懂它在講什么的。一般的ARM應(yīng)用程序中并不需要半主機(jī)操作,在這里為確保ARM應(yīng)用程序中沒(méi)有鏈接MicroLib的半主機(jī)相關(guān)函數(shù),我們要取消ARM的半主機(jī)工作模式。
2.2 實(shí)現(xiàn)代碼
在工程中加上如下代碼:
#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;
}
上面的代碼摘自正點(diǎn)原子的范例程序,具體每一行的意義目前也不大清楚。這樣操作后,在不使用MicroLib的前提下,仍能使用printf()函數(shù)將調(diào)試信息打印到USART1上了。
審核編輯:劉清
-
STM32
+關(guān)注
關(guān)注
2305文章
11118瀏覽量
370956 -
串口調(diào)試
+關(guān)注
關(guān)注
2文章
271瀏覽量
25458 -
printf函數(shù)
+關(guān)注
關(guān)注
0文章
31瀏覽量
6221 -
USART1
+關(guān)注
關(guān)注
0文章
10瀏覽量
4019
原文標(biāo)題:使用KEIL-MDK開(kāi)發(fā)STM32時(shí),兩種printf()函數(shù)重定向的方法
文章出處:【微信號(hào):雨飛工作室,微信公眾號(hào):雨飛工作室】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
實(shí)現(xiàn)STM32工程上的printf()函數(shù)
如何實(shí)現(xiàn)STM32工程上的printf()函數(shù)?
STM32 Printf函數(shù)利用標(biāo)準(zhǔn)庫(kù)實(shí)現(xiàn)方法是什么?
基于STM32的printf串口數(shù)據(jù)輸出
實(shí)現(xiàn)重定向printf()和scanf() 函數(shù)案例分析
STM32中使用printf打印串口數(shù)據(jù)的實(shí)現(xiàn)原理及方法
STM32單片機(jī)IAR環(huán)境下重定向printf函數(shù)
STM32使用串口重定向系統(tǒng)printf函數(shù)輸出時(shí)出現(xiàn)一初始化或使用printf函數(shù)系統(tǒng)卡死的原因及解決辦法
STM32單片機(jī)基礎(chǔ)09——重定向printf函數(shù)到串口輸出的多種方法
stm32printf函數(shù)的串口輸出代碼
STM32中串行通訊中printf函數(shù)的使用
stm32使用printf實(shí)現(xiàn)串口打印原理
STM32的printf函數(shù)重定向方法

STM32工程上printf()函數(shù)的方法實(shí)現(xiàn)
評(píng)論