0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

使用printf函數(shù)通過串口能否輸出彩色的調(diào)試信息

CHANBAEK ? 來源:猿來如此 I See ? 作者:YJer ? 2023-05-14 16:16 ? 次閱讀

前言

正常情況下,使用 printf 向串口打印調(diào)試信息,在串口調(diào)試工具界面只能看到一種顏色的字符,且使用不同的串口調(diào)試工具,字符默認(rèn)的顏色都不一樣。

如果你在 VSCode 上使用過 ESP-IDF 開發(fā) ESP32 應(yīng)用程序,你會發(fā)現(xiàn)其終端上輸出的調(diào)試信息是五顏六色的,十分花哨。 而且不同類型的調(diào)試信息使用不同的顏色區(qū)分,能夠快速地定位到程序中的問題,非常便捷實用。

那么我們使用 printf 函數(shù)通過串口能否輸出彩色的調(diào)試信息呢? 答案是肯定的,只是需要一丟丟小技巧罷了。

ANSI 轉(zhuǎn)義序列

在介紹如何打印彩色調(diào)試信息之前,我們先來了解一些背景知識 —— ANSI 轉(zhuǎn)義序列。

我們將信息打印到終端上顯示時,可以控制信息顯示成粗體、斜體、下劃線等形式,也可以控制字符顯示不同的顏色。

例如執(zhí)行如下代碼,會在終端上顯示紅色 ---testing---:

printf("\\033[31m---testing---\\n");

為什么有些字符會被當(dāng)做信息顯示,有些字符會被當(dāng)做命令處理? 其實這一切都歸功于轉(zhuǎn)義字符。

C語言中,用反斜杠 "" 作為轉(zhuǎn)義字符,正常情況下,"" 和 "n" 都是普通的字符,但是將這兩個字符組合起來變成 "\\n" 的字符序列后,就表示換行符了。

在終端中也有類似的用法,只不過終端中的轉(zhuǎn)義字符不是反斜杠 "" ,而是 "ESC"。 終端使用 "ESC" 作為轉(zhuǎn)義字符,而 "ESC" 在 ASCII 表中的序號是 27,也就是 0x1b,因此終端中與 0x1b 組合起來的字符序列就會被轉(zhuǎn)義成命令,不同的字符組合表示不同的終端命令,這些轉(zhuǎn)義規(guī)則被規(guī)范化以后,就叫做 ANSI 轉(zhuǎn)義序列(ANSI Escape Sequences), 主要用來控制終端上光標(biāo)位置、顏色及其他選項。

ANSI 轉(zhuǎn)義序列起始標(biāo)志

ANSI 轉(zhuǎn)義序列起始標(biāo)志由兩個字節(jié)組成,第一個字節(jié)是終端轉(zhuǎn)義字符 "ESC" 也就是 0x1b,第二個字節(jié)的取值范圍是0x40–0x5F(即 ASCII:@ A – Z [ \\ ] ^ _),也就是說 ANSI 轉(zhuǎn)義序列的起始標(biāo)志共有如下幾種:

  • x1b@(ESC@)
  • x1bA(掃描)
  • x1b-(電調(diào)-)
  • x1bZ(ESCZ)
  • x1b[(ESC[)
  • x1b\\(ESC\\)
  • x1b](ESC])
  • x1b^(ESC^)
  • x1b_(ESC_)

上述那么多種起始標(biāo)志,常見的起始標(biāo)志就是 " x1b[ " ,其他的起始標(biāo)志現(xiàn)在都很少用到了。

控制符起始標(biāo)志 CSI

當(dāng) 0x1b 與 "[" 組合時,就叫做控制符起始標(biāo)志(Control Sequence Introducer),簡稱為 CSI ,其基本格式如下:

x1b[<code><tail>

code: 轉(zhuǎn)義序列的具體內(nèi)容,多個內(nèi)容之間使用分號 ";" 隔開

tail : 轉(zhuǎn)義序列結(jié)束標(biāo)志,不同 tail 表示不同功能的序列

以 CSI 開頭的轉(zhuǎn)義序列有很多,不同的序列表示不同的終端指令,大致可以分為如下幾類:

  • 字符渲染指令(SGR)
  • 光標(biāo)移動指令
  • 清屏指令
  • 終端控制指令

字符渲染指令

字符渲指令(Select Graphic Rendition),簡稱為 SGR 。主要用于設(shè)置字符顯示效果,其基本格式如下:

CSI編號

CSI:控制符起始標(biāo)志 " 0x1b[ "

n :取值范圍 0 ~ 107

m :轉(zhuǎn)義序列結(jié)束標(biāo)志,字母 m 作為結(jié)尾,表明是字符渲染序列

示例:

x1b[3m

n 的取值范圍是 0 ~ 107,主要分為如下兩類功能:

  • 字符樣式控制
  • 字符顏色控制

n 的取值及說明:

n 功能 示例
0 重置/正常 x1b[0m 或 x1b[m
1 粗體或增加強度 x1b[1m
2 弱化(降低強度) x1b[2m
3 斜體 x1b[3m
4 下劃線 x1b[4m
5 緩慢閃爍 ......
6 快速閃爍 ......
7 反顯 ......
8 隱藏 ......
9 劃除 ......
10 主要(默認(rèn))字體 ......
11–19 替代字體 ......
20 尖角體 ......
21 關(guān)閉粗體或雙下劃線 ......
22 正常顏色或強度 ......
23 非斜體、非尖角體 ......
24 關(guān)閉下劃線 ......
25 關(guān)閉閃爍 ......
27 關(guān)閉反顯 ......
28 關(guān)閉隱藏 ......
29 關(guān)閉劃除 ......
30–37 設(shè)置前景色 ......
38 設(shè)置前景色 ......
39 默認(rèn)前景色 ......
40–47 設(shè)置背景色 ......
48 設(shè)置背景色 ......
49 默認(rèn)背景色 ......
51 Framed ......
52 Encircled ......
53 上劃線 ......
54 Not framed or encircled ......
55 關(guān)閉上劃線 ......
60 表意文字下劃線或右邊線 ......
61 表意文字雙下劃線或雙右邊線 ......
62 表意文字上劃線或左邊線 ......
63 表意文字雙上劃線或雙左邊線 ......
64 表意文字著重標(biāo)志 ......
65 表意文字屬性關(guān)閉 ......
90–97 設(shè)置明亮的前景色 ......
100–107 設(shè)置明亮的背景色 ......

有了上述這些背景知識,就足夠搞懂串口輸出彩色調(diào)試信息的原理了,關(guān)于 ANSI 轉(zhuǎn)義序列的更多內(nèi)容,感興趣的小伙伴可以自行查閱。

串口輸出彩色調(diào)試信息

在 《單片機 printf 重定向串口輸出調(diào)試信息》這篇文章中介紹了如何使用 printf 通過串口輸出調(diào)試信息,那么現(xiàn)在就在此基礎(chǔ)上,再說說如何將輸出的調(diào)試信息變成彩色的。

通過串口輸出彩色調(diào)試信息有兩個必要條件:

  • printf 參數(shù)列表中添加字符顏色控制相關(guān)的 ANSI轉(zhuǎn)義序列
  • 接收串口數(shù)據(jù)的串口調(diào)試工具支持 ANSI 轉(zhuǎn)義序列解析

回顧一下上面講到的字符渲指令(SGR),其基本格式如下:

CSI n m

CSI:控制符起始標(biāo)志 " 0x1b[ "

n :取值范圍 0 ~ 107

m :轉(zhuǎn)義序列結(jié)束標(biāo)志,字母 m 作為結(jié)尾,表明是字符渲染序列

當(dāng)我們想要輸出不同顏色的字符時,將 n 替換成對應(yīng)的數(shù)字即可,常見的顏色如下:

n 功能 示例
30 黑色 x1b[30m
31 紅色 x1b[31m
32 綠色 x1b[32m
33 黃色 x1b[33m
34 藍色 x1b[34m
35 品紅 x1b[35m
36 青色 x1b[36m

使用 printf 打印 "Hello World" 代碼如下:

printf("Hello World\\n");

打印不同的 "Hello World" 代碼如下:

printf("\\x1b[31m" "Hello World\\n" "\\x1b[0m"); 
printf("\\x1b[32m" "Hello World\\n" "\\x1b[0m"); 
printf("\\x1b[33m" "Hello World\\n" "\\x1b[0m"); 
printf("\\x1b[34m" "Hello World\\n" "\\x1b[0m"); 
printf("\\x1b[35m" "Hello World\\n" "\\x1b[0m");
printf("\\x1b[36m" "Hello World\\n" "\\x1b[0m");

注意事項

如果使用的串口調(diào)試工具不支持 ANSI 轉(zhuǎn)義序列解析,那么接收到的串口數(shù)據(jù)會有部分亂碼,而且只會使用工具默認(rèn)的顏色顯示信息:

支持 ANSI 轉(zhuǎn)義序列解析的串口調(diào)試工具才能正常顯示彩色字符,推薦使用 MobaXterm 。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 調(diào)試
    +關(guān)注

    關(guān)注

    7

    文章

    551

    瀏覽量

    33763
  • 串口
    +關(guān)注

    關(guān)注

    14

    文章

    1533

    瀏覽量

    75463
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4237

    瀏覽量

    61969
  • 命令
    +關(guān)注

    關(guān)注

    5

    文章

    658

    瀏覽量

    21928
  • Printf
    +關(guān)注

    關(guān)注

    0

    文章

    81

    瀏覽量

    13564
收藏 人收藏

    評論

    相關(guān)推薦

    怎樣用printf()函數(shù)實現(xiàn)通過串口打印信息

    在使用STM32調(diào)試時,經(jīng)常使用串口發(fā)送信息,為了方便調(diào)試串口發(fā)送信息,用
    發(fā)表于 08-05 07:07

    不同的串口使用printf函數(shù)輸出對應(yīng)的信息

    這個實驗向我們演示,不同的串口使用printf函數(shù)輸出對應(yīng)的信息。默認(rèn)printf()
    發(fā)表于 08-10 08:01

    stm32在調(diào)試時可以使用printf通過串口輸出當(dāng)前信息

    stm32在調(diào)試時可以使用printf通過串口輸出當(dāng)前信息嗎?
    發(fā)表于 12-02 07:05

    STM8S串口打印調(diào)試信息(不使用printf)

    STM8S串口打印調(diào)試信息(不使用printf),感興趣可以看看。
    發(fā)表于 07-25 18:52 ?51次下載

    基于STM32的printf串口數(shù)據(jù)輸出

    該方法適用于 STM32 ,實現(xiàn)了使用printf等標(biāo)準(zhǔn)C流函數(shù)輸出數(shù)據(jù)的辦法,極大的減少了輸出 串口數(shù)據(jù) 時所需要做的數(shù)據(jù)處理。 實現(xiàn)原理
    發(fā)表于 06-21 07:51 ?2w次閱讀
    基于STM32的<b class='flag-5'>printf</b><b class='flag-5'>串口</b>數(shù)據(jù)<b class='flag-5'>輸出</b>

    基于STM32中調(diào)試串口之間的信息傳輸

    問題:在使用STM32調(diào)試時,經(jīng)常使用串口發(fā)送信息,為了方便調(diào)試串口發(fā)送信息,用
    發(fā)表于 06-21 07:53 ?6423次閱讀

    Keil C51重定向printf串口的程序免費下載

    進行C/C++開發(fā)的時候我們都會需要打印調(diào)試信息,打印調(diào)試信息時我們習(xí)慣使用printf函數(shù),但
    發(fā)表于 07-19 17:38 ?11次下載
    Keil C51重定向<b class='flag-5'>printf</b>到<b class='flag-5'>串口</b>的程序免費下載

    51單片機串口通信調(diào)試printf函數(shù)重定向輸出打印

    51單片機串口通信以及printf調(diào)試串行通信1.串口初始化串口工作方式波特率設(shè)置通過軟件直接生
    發(fā)表于 11-20 16:36 ?16次下載
    51單片機<b class='flag-5'>串口</b>通信<b class='flag-5'>調(diào)試</b><b class='flag-5'>printf</b><b class='flag-5'>函數(shù)</b>重定向<b class='flag-5'>輸出</b>打印

    printf通過串口輸出在MCU上的實現(xiàn)

    對mcu的開發(fā)調(diào)試過程中,通過串口打印運行過程中的一些信息,有時候比調(diào)試器好用。以及在產(chǎn)品使用中,通過
    發(fā)表于 12-07 15:21 ?4次下載
    <b class='flag-5'>printf</b><b class='flag-5'>通過</b><b class='flag-5'>串口</b><b class='flag-5'>輸出</b>在MCU上的實現(xiàn)

    STM32使用串口重定向系統(tǒng)printf函數(shù)輸出時出現(xiàn)一初始化或使用printf函數(shù)系統(tǒng)卡死的原因及解決辦法

    STM32使用串口重定向系統(tǒng)printf函數(shù)輸出時出現(xiàn)一初始化或使用printf函數(shù)系統(tǒng)卡死的原
    發(fā)表于 12-09 10:06 ?13次下載
    STM32使用<b class='flag-5'>串口</b>重定向系統(tǒng)<b class='flag-5'>printf</b><b class='flag-5'>函數(shù)</b><b class='flag-5'>輸出</b>時出現(xiàn)一初始化或使用<b class='flag-5'>printf</b><b class='flag-5'>函數(shù)</b>系統(tǒng)卡死的原因及解決辦法

    STM32單片機基礎(chǔ)09——重定向printf函數(shù)串口輸出的多種方法

    本文詳細的介紹了如何重定向printf輸出串口輸出的多種方法,包括調(diào)用MDK微庫(MicroLib)的方法,調(diào)用標(biāo)準(zhǔn)庫的方法,以及適用于 GNUC 系列編譯器的方法。1.
    發(fā)表于 12-27 19:22 ?8次下載
    STM32單片機基礎(chǔ)09——重定向<b class='flag-5'>printf</b><b class='flag-5'>函數(shù)</b>到<b class='flag-5'>串口</b><b class='flag-5'>輸出</b>的多種方法

    stm32printf函數(shù)串口輸出代碼

    stm32f103串口一與串口printf函數(shù)輸出、本人是萌新,因項目需要特意配置了該段代碼,不喜勿噴,純屬個人筆記。對于
    發(fā)表于 12-28 19:10 ?13次下載
    stm32<b class='flag-5'>printf</b><b class='flag-5'>函數(shù)</b>的<b class='flag-5'>串口</b><b class='flag-5'>輸出</b>代碼

    通過串口利用printf函數(shù)輸出數(shù)據(jù)

    一。printf函數(shù)格式printf函數(shù)具有強大的輸出功能%表示格式化字符串輸出目前
    發(fā)表于 12-28 19:11 ?11次下載
    <b class='flag-5'>通過</b><b class='flag-5'>串口</b>利用<b class='flag-5'>printf</b><b class='flag-5'>函數(shù)</b><b class='flag-5'>輸出</b>數(shù)據(jù)

    【RT-Thread學(xué)習(xí)筆記】多彩的printf日志輸出

    如何使用printf輸出彩色的日志信息?
    的頭像 發(fā)表于 07-30 14:05 ?2517次閱讀
    【RT-Thread學(xué)習(xí)筆記】多彩的<b class='flag-5'>printf</b>日志<b class='flag-5'>輸出</b>

    printf輸出重定向的方法

    在 PC 上運行 C 語言時,prinf 輸出的內(nèi)容會打印在電腦顯示器上,這是因為 prinf 默認(rèn)的輸出設(shè)備就是顯示器。而當(dāng)我們在單片機上,需要通過 printf
    的頭像 發(fā)表于 05-14 16:22 ?4855次閱讀
    <b class='flag-5'>printf</b><b class='flag-5'>輸出</b>重定向的方法