博客專欄

        EEPW首頁(yè) > 博客 > 遇到這種情況 你需要添加這幾行代碼

        遇到這種情況 你需要添加這幾行代碼

        發(fā)布人:12345zhi 時(shí)間:2023-08-10 來(lái)源:工程師 發(fā)布文章

        問(wèn):在STM32上輕松使用printf函數(shù)

        除了點(diǎn)亮LED外,向串行控制臺(tái)發(fā)送打印信息可能是調(diào)試嵌入式項(xiàng)目時(shí)最簡(jiǎn)單、最直接且最常用的技術(shù)。雖然大多數(shù)平臺(tái)都擁有可以在UART總線上傳輸數(shù)據(jù)的API,但它們?cè)诠δ芎推占岸壬隙歼d于printf() 函數(shù)。但在嵌入式C應(yīng)用應(yīng)用中僅僅利用此函數(shù)包含stdio 庫(kù)是遠(yuǎn)遠(yuǎn)不夠的。在STM32項(xiàng)目中,我們還需要額外添加幾行代碼。


        如果你希望在UART總線上 傳輸 和 接收 格式化數(shù)據(jù),請(qǐng)查看附屬文章在STM32上輕松使用scanf !

        步驟

        此程序涵蓋了配置和啟用適當(dāng)?shù)腢ART外設(shè)的預(yù)備步驟、將該UART實(shí)例映射到printf() 函數(shù)的主要步驟,以及用于打印浮點(diǎn)數(shù)的可選輔助步驟。本文適用于使用STM32CubeIDE 20(版本1.11.2)開發(fā)的項(xiàng)目,但也可以展開以用于其他環(huán)境。

        0  建立UART實(shí)例

        為了在接下來(lái)的步驟中正確地使用stdio 庫(kù)中的printf() 函數(shù),我們必須配置一個(gè)UART(或USART)外設(shè)以傳輸格式化字符串。通常情況下,在ST開發(fā)板上操作時(shí),應(yīng)選擇可以連接到ST-LINK編程器/調(diào)試器RX和TX引腳的UART外設(shè)。因?yàn)椋@樣可以通過(guò)ST-LINK的USB虛擬COM端口橋接將字符串發(fā)送到串行控制臺(tái)。幸運(yùn)的是,在STM32CubeIDE或STM32CubeMX中啟動(dòng)新項(xiàng)目時(shí),該UART實(shí)例已默認(rèn)配置完畢!作為程序員,你只需要留意已經(jīng)配置的具體UART,然后繼續(xù)下一步操作即可。

        對(duì)于那些已有項(xiàng)目但未配置UART的用戶,只需打開項(xiàng)目的.ioc 文件,并按照?qǐng)D1所示進(jìn)行修改即可。具體來(lái)說(shuō),

        選擇適當(dāng)?shù)耐庠O(shè)實(shí)例

        設(shè)置模式和配置參數(shù)(通常使用的設(shè)置如圖1所示)

        確保將適當(dāng)?shù)腉PIO引腳配置為UART RX和TX。

        完成后,保存.ioc 文件以生成項(xiàng)目的代碼。

        圖片

        圖 1 : 啟用和配置所需的U(S)ART外設(shè)的示例

        1  重新定向printf() 至UART實(shí)例

        UART準(zhǔn)備就緒后,只需添加幾行代碼即可添加printf() 。

        a. 將#include <stdio.h> 添加到main.c 文件頂部的“包含”部分中(圖2)。

        圖片

        圖2:納入stdio庫(kù)

        b. 在main.c 文件中,將以下代碼復(fù)制并粘貼到main() 函數(shù)前、UART句柄聲明之后的位置。你可以選擇“私有函數(shù)原型”部分,如下圖3所示。請(qǐng)注意,UART句柄必須從&huart?更改為所需UART外設(shè)的句柄(例如 &huart2)。

        #ifdef __GNUC__

        #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)

        #else

        #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

        #endif

        PUTCHAR_PROTOTYPE

        {

        HAL_UART_Transmit(&huart?, (uint8_t *)&ch, 1, HAL_MAX_DELAY);

        return ch;

        }

        圖片

        圖3:將重新定向代碼添加到main.c文件中

        printf() 函數(shù)現(xiàn)在應(yīng)該可以按預(yù)期運(yùn)行了,除了浮點(diǎn)格式說(shuō)明符。要啟用這些格式說(shuō)明符,請(qǐng)繼續(xù)下一步。

        2  啟用浮點(diǎn)支持(可選)

        為了說(shuō)明浮點(diǎn)格式化的問(wèn)題,我們可以使用printf() 參考頁(yè)面提供的示例代碼。

        printf("Characters: %c %cn", 'a', 65);

        printf("Decimals: %d %ldn", 1977, 650000L);

        p rintf("Preceding with blanks: %10dn", 1977);

        printf("Preceding with zeros: %010dn", 1977);

        printf("Some different radices: %d %x %o %#x %#on", 100, 100, 100, 100, 100);

        printf("floats: %4.2f %+.0e %En", 3.1416, 3.1416, 3.1416);

        printf("Width trick: %*dn", 5, 10);

        printf("%sn", "A string");

        在將此代碼添加到項(xiàng)目后,系統(tǒng)會(huì)顯示警告,說(shuō)明“不支持浮點(diǎn)格式化”。如果我們繼續(xù)構(gòu)建并運(yùn)行項(xiàng)目,串行控制臺(tái)上的輸出將確認(rèn)不會(huì)打印浮點(diǎn)數(shù)(圖4)。

        圖片

        圖4:未啟用浮點(diǎn)格式化支持的輸出示例

        如果你的應(yīng)用中未使用浮點(diǎn)數(shù),那這可能就不是什么問(wèn)題。但如果你需要使用浮點(diǎn)數(shù),則可在“項(xiàng)目資源管理器”(Project Explorer)中右鍵單擊項(xiàng)目名稱,并選擇屬性(Properties ) 。在“C / C ++ Build”類別下選擇設(shè)置(Settings ) ,并在工具設(shè)置選項(xiàng)卡下選擇MCU( MCU Settings) 設(shè)置 。勾選“從newlib-nano使用printf的浮點(diǎn)數(shù)”旁邊的復(fù)選框,如下圖5所示。點(diǎn)擊應(yīng)用并關(guān)閉( Apply and Close ) 。

        請(qǐng)注意,啟用printf() 的浮點(diǎn)格式化支持將消耗相當(dāng)數(shù)量的額外內(nèi)存。具體來(lái)說(shuō),除了在未啟用浮點(diǎn)支持時(shí)printf() 函數(shù)所消耗的內(nèi)存之外,啟用后還將消耗約0.35 KB的RAM和10.30 KB的閃存,這對(duì)低端設(shè)備而言已經(jīng)是個(gè)問(wèn)題。

        圖片

        圖5:?jiǎn)⒂酶↑c(diǎn)格式化支持

        現(xiàn)在,在重新構(gòu)建項(xiàng)目并運(yùn)行代碼后,浮點(diǎn)數(shù)值已經(jīng)正確格式化,并如圖6所示。

        圖片

        圖6:?jiǎn)⒂酶↑c(diǎn)格式化支持的輸出示例

        *博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。



        關(guān)鍵詞: STM32 printf

        相關(guān)推薦

        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 喀喇沁旗| 克什克腾旗| 平南县| 龙井市| 株洲县| 合川市| 洮南市| 永兴县| 肥乡县| 汤原县| 长宁县| 开远市| 陇西县| 文化| 石台县| 恩施市| 株洲县| 庆元县| 长子县| 崇义县| 土默特左旗| 孝昌县| 拜泉县| 临洮县| 攀枝花市| 盐城市| 略阳县| 扬州市| 宾阳县| 长海县| 隆安县| 民乐县| 峡江县| 永平县| 化德县| 泰州市| 莲花县| 东平县| 巨野县| 永嘉县| 四子王旗|