0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用printf函数通过串口能否输出彩色的调试信息

CHANBAEK 来源:猿来如此 I See 作者:YJer 2023-05-14 16:16 次阅读

前言

正常情况下,使用 printf 向串口打印调试信息,在串口调试工具界面只能看到一种颜色的字符,且使用不同的串口调试工具,字符默认的颜色都不一样。

如果你在 VSCode 上使用过 ESP-IDF 开发 ESP32 应用程序,你会发现其终端上输出的调试信息是五颜六色的,十分花哨。 而且不同类型的调试信息使用不同的颜色区分,能够快速地定位到程序中的问题,非常便捷实用。

那么我们使用 printf 函数通过串口能否输出彩色的调试信息呢? 答案是肯定的,只是需要一丢丢小技巧罢了。

ANSI 转义序列

在介绍如何打印彩色调试信息之前,我们先来了解一些背景知识 —— ANSI 转义序列。

我们将信息打印到终端上显示时,可以控制信息显示成粗体、斜体、下划线等形式,也可以控制字符显示不同的颜色。

例如执行如下代码,会在终端上显示红色 ---testing---:

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

为什么有些字符会被当做信息显示,有些字符会被当做命令处理? 其实这一切都归功于转义字符。

C语言中,用反斜杠 "" 作为转义字符,正常情况下,"" 和 "n" 都是普通的字符,但是将这两个字符组合起来变成 "\\n" 的字符序列后,就表示换行符了。

在终端中也有类似的用法,只不过终端中的转义字符不是反斜杠 "" ,而是 "ESC"。 终端使用 "ESC" 作为转义字符,而 "ESC" 在 ASCII 表中的序号是 27,也就是 0x1b,因此终端中与 0x1b 组合起来的字符序列就会被转义成命令,不同的字符组合表示不同的终端命令,这些转义规则被规范化以后,就叫做 ANSI 转义序列(ANSI Escape Sequences), 主要用来控制终端上光标位置、颜色及其他选项。

ANSI 转义序列起始标志

ANSI 转义序列起始标志由两个字节组成,第一个字节是终端转义字符 "ESC" 也就是 0x1b,第二个字节的取值范围是0x40–0x5F(即 ASCII:@ A – Z [ \\ ] ^ _),也就是说 ANSI 转义序列的起始标志共有如下几种:

  • x1b@(ESC@)
  • x1bA(扫描)
  • x1b-(电调-)
  • x1bZ(ESCZ)
  • x1b[(ESC[)
  • x1b\\(ESC\\)
  • x1b](ESC])
  • x1b^(ESC^)
  • x1b_(ESC_)

上述那么多种起始标志,常见的起始标志就是 " x1b[ " ,其他的起始标志现在都很少用到了。

控制符起始标志 CSI

当 0x1b 与 "[" 组合时,就叫做控制符起始标志(Control Sequence Introducer),简称为 CSI ,其基本格式如下:

x1b[<code><tail>

code: 转义序列的具体内容,多个内容之间使用分号 ";" 隔开

tail : 转义序列结束标志,不同 tail 表示不同功能的序列

以 CSI 开头的转义序列有很多,不同的序列表示不同的终端指令,大致可以分为如下几类:

  • 字符渲染指令(SGR)
  • 光标移动指令
  • 清屏指令
  • 终端控制指令

字符渲染指令

字符渲指令(Select Graphic Rendition),简称为 SGR 。主要用于设置字符显示效果,其基本格式如下:

CSI编号

CSI:控制符起始标志 " 0x1b[ "

n :取值范围 0 ~ 107

m :转义序列结束标志,字母 m 作为结尾,表明是字符渲染序列

示例:

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 主要(默认)字体 ......
11–19 替代字体 ......
20 尖角体 ......
21 关闭粗体或双下划线 ......
22 正常颜色或强度 ......
23 非斜体、非尖角体 ......
24 关闭下划线 ......
25 关闭闪烁 ......
27 关闭反显 ......
28 关闭隐藏 ......
29 关闭划除 ......
30–37 设置前景色 ......
38 设置前景色 ......
39 默认前景色 ......
40–47 设置背景色 ......
48 设置背景色 ......
49 默认背景色 ......
51 Framed ......
52 Encircled ......
53 上划线 ......
54 Not framed or encircled ......
55 关闭上划线 ......
60 表意文字下划线或右边线 ......
61 表意文字双下划线或双右边线 ......
62 表意文字上划线或左边线 ......
63 表意文字双上划线或双左边线 ......
64 表意文字着重标志 ......
65 表意文字属性关闭 ......
90–97 设置明亮的前景色 ......
100–107 设置明亮的背景色 ......

有了上述这些背景知识,就足够搞懂串口输出彩色调试信息的原理了,关于 ANSI 转义序列的更多内容,感兴趣的小伙伴可以自行查阅。

串口输出彩色调试信息

在 《单片机 printf 重定向串口输出调试信息》这篇文章中介绍了如何使用 printf 通过串口输出调试信息,那么现在就在此基础上,再说说如何将输出的调试信息变成彩色的。

通过串口输出彩色调试信息有两个必要条件:

  • printf 参数列表中添加字符颜色控制相关的 ANSI转义序列
  • 接收串口数据的串口调试工具支持 ANSI 转义序列解析

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

CSI n m

CSI:控制符起始标志 " 0x1b[ "

n :取值范围 0 ~ 107

m :转义序列结束标志,字母 m 作为结尾,表明是字符渲染序列

当我们想要输出不同颜色的字符时,将 n 替换成对应的数字即可,常见的颜色如下:

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");

注意事项

如果使用的串口调试工具不支持 ANSI 转义序列解析,那么接收到的串口数据会有部分乱码,而且只会使用工具默认的颜色显示信息:

支持 ANSI 转义序列解析的串口调试工具才能正常显示彩色字符,推荐使用 MobaXterm 。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 调试
    +关注

    关注

    7

    文章

    527

    浏览量

    33625
  • 串口
    +关注

    关注

    14

    文章

    1483

    浏览量

    74514
  • 函数
    +关注

    关注

    3

    文章

    3882

    浏览量

    61310
  • 命令
    +关注

    关注

    5

    文章

    638

    浏览量

    21849
  • Printf
    +关注

    关注

    0

    文章

    79

    浏览量

    13479
收藏 人收藏

    评论

    相关推荐

    怎样用printf()函数实现通过串口打印信息

    在使用STM32调试时,经常使用串口发送信息,为了方便调试串口发送信息,用
    发表于 08-05 07:07

    不同的串口使用printf函数输出对应的信息

    这个实验向我们演示,不同的串口使用printf函数输出对应的信息。默认printf()
    发表于 08-10 08:01

    stm32在调试时可以使用printf通过串口输出当前信息

    stm32在调试时可以使用printf通过串口输出当前信息吗?
    发表于 12-02 07:05

    STM8S串口打印调试信息(不使用printf)

    STM8S串口打印调试信息(不使用printf),感兴趣可以看看。
    发表于 07-25 18:52 51次下载

    基于STM32的printf串口数据输出

    该方法适用于 STM32 ,实现了使用printf等标准C流函数输出数据的办法,极大的减少了输出 串口数据 时所需要做的数据处理。 实现原理
    发表于 06-21 07:51 2w次阅读
    基于STM32的<b class='flag-5'>printf</b><b class='flag-5'>串口</b>数据<b class='flag-5'>输出</b>

    基于STM32中调试串口之间的信息传输

    问题:在使用STM32调试时,经常使用串口发送信息,为了方便调试串口发送信息,用
    发表于 06-21 07:53 6283次阅读

    Keil C51重定向printf串口的程序免费下载

    进行C/C++开发的时候我们都会需要打印调试信息,打印调试信息时我们习惯使用printf函数,但
    发表于 07-19 17:38 11次下载
    Keil C51重定向<b class='flag-5'>printf</b>到<b class='flag-5'>串口</b>的程序免费下载

    51单片机串口通信调试printf函数重定向输出打印

    51单片机串口通信以及printf调试串行通信1.串口初始化串口工作方式波特率设置通过软件直接生
    发表于 11-20 16:36 16次下载
    51单片机<b class='flag-5'>串口</b>通信<b class='flag-5'>调试</b><b class='flag-5'>printf</b><b class='flag-5'>函数</b>重定向<b class='flag-5'>输出</b>打印

    printf通过串口输出在MCU上的实现

    对mcu的开发调试过程中,通过串口打印运行过程中的一些信息,有时候比调试器好用。以及在产品使用中,通过
    发表于 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上的实现

    STM32使用串口重定向系统printf函数输出时出现一初始化或使用printf函数系统卡死的原因及解决办法

    STM32使用串口重定向系统printf函数输出时出现一初始化或使用printf函数系统卡死的原
    发表于 12-09 10:06 12次下载
    STM32使用<b class='flag-5'>串口</b>重定向系统<b class='flag-5'>printf</b><b class='flag-5'>函数</b><b class='flag-5'>输出</b>时出现一初始化或使用<b class='flag-5'>printf</b><b class='flag-5'>函数</b>系统卡死的原因及解决办法

    STM32F103串口1 printf函数的实现

    要怎么使用呢?能不能将这个函数串口1对应起来,当然是有方法的。  下面就通过代码来演示一下如何在串口1上使用printf()
    发表于 12-20 19:37 1次下载
    STM32F103<b class='flag-5'>串口</b>1 <b class='flag-5'>printf</b><b class='flag-5'>函数</b>的实现

    stm32单片机串口使用printf及u3_printf

    外部设备与单片机连接的时候使用的是串口(通常物联网用到的ESP8266,SIM9600等都是通过串口发送AT指令进行模式的配置的),但是printf
    发表于 12-27 19:24 1次下载
    stm32单片机<b class='flag-5'>串口</b>使用<b class='flag-5'>printf</b>及u3_<b class='flag-5'>printf</b>

    stm32printf函数串口输出代码

    stm32f103串口一与串口printf函数输出、本人是萌新,因项目需要特意配置了该段代码,不喜勿喷,纯属个人笔记。对于
    发表于 12-28 19:10 13次下载
    stm32<b class='flag-5'>printf</b><b class='flag-5'>函数</b>的<b class='flag-5'>串口</b><b class='flag-5'>输出</b>代码

    通过串口利用printf函数输出数据

    一。printf函数格式printf函数具有强大的输出功能%表示格式化字符串输出目前
    发表于 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'>函数</b><b class='flag-5'>输出</b>数据

    【RT-Thread学习笔记】多彩的printf日志输出

    如何使用printf输出彩色的日志信息
    的头像 发表于 07-30 14:05 2080次阅读
    【RT-Thread学习笔记】多彩的<b class='flag-5'>printf</b>日志<b class='flag-5'>输出</b>