嵌入式开发三:STM32初体验

      本节主要向大家介绍如何开发过程中的基本操作,如编译、串口下载、仿真器下载、仿真调试程序,体验一下 STM32 的开发流程,并介绍 MDK5 的一些使用技巧,通过本节的学习,将对 STM32 的开发流程和 MDK5 使用有个大概了解,为后续深入学习打好基础,这节内容丰富,从零入门,认真学习,边学边实践。

目录

一、 使用 MDK5 编译例程

二、使用串口下载程序

2.1 串口下载程序须知

2.2 STM32下载方式介绍 

2.3 利用串口给STM32下载程序的步骤 

2.3.1  串口下载硬件连接简易图

2.3.2  串口下载硬件连接事物图

2.3.3 配置下载串口下载程序工具/软件(ATK-XISP.exe)

2.3.4 STM32的启动模式分析(M3、M4)

2.3.5 串口下载一键电路(了解)

三、 使用 DAP 下载与调试程序

3.1使用DAP下载程序

3.1.1 DAP下载程序硬件连接

3.1.2 在MDK上配置DAP

3.2使用DAP仿真调试程序(掌握)

3.2.1 仿真界面简单介绍

3.2.2 具体展示调试过程

3.3仿真调试注意事项

四、 MDK5 使用技巧

4.1文本美化

4.2语法检测&代码提示(掌握)

4.3代码编辑技巧(掌握)

4.3.1 TAB键的妙用

4.3.2 快速跳到函数/变量被定义的地方

4.3.3 快速注释与快速取消注释

4.4 查找替换技巧

4.4.1 快速打开头文件

4.4.2 查找替换功能

4.4.3 跨文件查找功能

五、工程编译问题定位

六、窗口视图管理

一、 使用 MDK5 编译例程

     我们在编写完代码以后,需要对代码进行编译,编译成功以后,才能下载到开发板进行验证、调试等操作。记住一句话:从底层讲,我们是通过对寄存器进行配置(向寄存器写入数据或者读取寄存器的数据),从而实现对外部电路的控制,进而实现不同的功能。

STM32的编程方式主要有以下3种:

(1)基于寄存器(2)基于标准库(固件库)(3)基于HAL库;

1. 基于寄存器:基于寄存器是学习单片机的基础,直接操作配置寄存器,从而实现选择不同的功能,比如8位的51单片机,32位的stm32单片机;

2. 基于标准库:STM32有非常多的寄存器,因此直接通过寄存器导致开发困难,所以ST公司就为每款芯片都编写了一份库文件,也就是工程文件里的stm32F4xx...之类的。在这些.c和.h文件中,主要包括一些常用量的宏定义,把对应的每个外设的寄存器封装成结构体来,如GPIO口时钟等。所以我们只需要配置结构体变量成员就可以修改外设的配置寄存器,从而选择不同的功能。也是目前最多人使用的方式,也是学习STM32接触最多的一种开发方式,我便是基于这种标准库的方式。

3. 基于HAL库:HAL 库是ST公司目前主力推的开发方式,全称就是Hardware Abstraction
Layer (抽象印象层)。库如其名,很抽象,一眼看上去不太容易知道他的作用是什么。它的出现比标准库要晚,但其实和标准库一样,都是为了节省程序开发的时期,而且HAL库尤其的有效。

打开我们提前创建好的工程,如下图所示:


关于这里面的文件夹的作用是什么,主要包括哪些,后续会专门详细介绍,双击project.uvprojx项目文件,便可打开整个工程!进入 MDK IDE 界面,如图所示:

① 是部分编译按钮,表示编译当前工程项目文件,如果之前已经编译过了,则只会编译有改动的文件。所以一般第一次会比较耗时间,后续因为只编译改动文件,从而大大缩短了编译时 间。该按钮可以通过 F7 快捷键进行操作。

② 是重新编译当前工程所有文件按钮(全局编译),工程代码较多时全部重新编译会耗费比较多的时间, 建议少用。 按①处的按钮,编译当前项目,在编译完成后,可以看到如图所示的编译提示信息: 

图中:

Code:表示代码大小,占用 1412 字节。

RO-Data:表示只读数据所占的空间大小,一般是指 const 修饰的数据大小。

RW-Data:表示有初值(且非 0)的可读写数据所占的空间大小,它同时占用 FLASH(存 放其初始值)和 RAM 空间。

ZI-Data:表示初始化为 0 的可读写数据所占空间大小,它只占用 RAM 空间。

       因此图的提示信息表示:代码总大小(Program Size)为:FLASH 占用 1820 字节(Code+ RO + RW),SRAM 占用 1632字节(RW + ZI);成功创建了 Hex 文件(可执行文件,放在 Objects目录下);编译 0 错误,0 警告;编译耗时 1 秒钟。 编译完成以后,会生成 Hex 可执行文件,默认输出在 Objects文件夹下,如图 所示: 

注意:必须编译成功,才会生成 Hex 可执行文件,否则是不会有这个文件的 !! Objects 文件夹下除了.hex 文件还有很多其他文件(.axf、.htm、.dep、.lnp、.o、.d、.crf 等), 这些文件是编译过程所产生的中间文件,我们将在后续的.map 文件分析给大家详细介绍这些文件的作用。至此,例程编译完成。简单总结如下:

二、使用串口下载程序

2.1 串口下载程序须知

1.  M3、M4、M7开发板支持串口下载程序,但是ATK-XISP.exe软件只支持下载到内部
FL ASH。
2.  STM32的ISP下载,常用串口1下载程序。
3   因为使用USB虚拟串口,所以事先得安装CH340 USB虚拟串口驱动。

2.2 STM32下载方式介绍 

       经过以上对比,因此我们推荐使用 SWD下载,强烈推荐大家购买一个仿真器(如ST LINK、 CMSIS DAP 等),可以极大的方便学习和开发。不推荐使用串口下载(速度慢、无法仿真和调 试)和 JTAG 下载(占用 IO 多)。

2.3 利用串口给STM32下载程序的步骤 

      接下来,我们将向大家介绍,如何利用串口给 STM32 下载代码。 STM32 通过串口 1 实现程序下载,开发板通过自带的 USB 转串口来实现串口下载。看起来像是 USB 下载(只需一根 USB 线,并不需要串口线)的,实际上,是通过 USB 转成串口, 然后再下载的。

2.3.1  串口下载硬件连接简易图

2.3.2  串口下载硬件连接事物图

      下面,我们就一步步教大家如何在实验平台上利用 USB 串口来下载代码。 首先确保开发板接线正确,并成功上电,默认的出厂设置如图所示:

a) ①处的 USB_UART 通过 USB 线连接电脑,实现 USB 转串口,同时支持给开发板供电。 b) 确保电源灯②亮起(蓝色),如果不亮检查供电和电源开关③是否按下? 

c) 确保 P4 端子的 RXD 和 PA9(STM32 的 TXD),TXD 和 PA10(STM32 的 RXD)通过 跳线帽连接起来(标号④),这样我们就把 CH340C 和 STM32 的串口 1 连接上了。

d) ⑤处的 BOOT 设置为 BOOT0(简称 B0)和 BOOT1(简称 B1)都接 GND(一键下载 电路自动控制,待会介绍)。

由下表STM32启动模式可知,使用串口下载 STM32 程序需要修改 BOOT 的设置,四个步骤如下: 1.  把 B0 接 V3.3    2.  保持 B1 接 GND   3.按一下复位按键     4.使用上位机软件下载代码 。

       通过这几个步骤,我们就可以通过串口下载代码了,下载完成之后,如果没有设置从0X08000000 开始运行,则代码不会立即运行,此时,你还需要把 B0 接回 GND,然后再按一次 复位,才会开始运行你刚刚下载的代码。所以整个过程,你得跳动 2 次跳线帽,还得按 2 次复 位,比较繁琐。而我们的一键下载电路,则利用串口的 DTR 和 RTS 信号,分别控制 STM32 的 复位和 B0,配合正点原子团队研发的上位机软件 ATK-XISP,设置:DTR 的低电平复位,RTS 高电平进 BootLoader,这样,B0 和 STM32 的复位,完全可以由下载软件自动控制(B0 和 B1 使用一键下载电路后从始至终只需接 GND 即可),从而实现一键下载。

2.3.3 配置下载串口下载程序工具/软件(ATK-XISP.exe)

       串口程序下载需要用到:ATK-XISP 这个上位机软件。这个软件可以实现对 STM32F1 到 STM32H7 等系列芯片的串口编程。STM32 串口下载软件(ATK-XISP),如图所示:

双击打开 ATK-XISP,进行如图所示的设置: 

配置过程主要为以下四个:

① 搜索串口选择 CH340 虚拟的串口(我的是 COM23,不同电脑可能不同,需要根据实际情 况选择对应的串口),然后波特率我们推荐设置为 76800,速度过快可能会导 致下载失败。

② 选择 编译生成的 hex 文件(在 Objects文件夹)

③ 勾选校验和编程后执行两项,可以保证下载代码的正确性,并下载完后自动运行,省去按复位的麻烦。注意:千万不要勾选:使用 RamIsp 和连续烧录模式!否则下载失败!

④ 选择 DTR 的低电平复位,RTS 高电平进 BootLoader(别选错!),以匹配一键下载电路, 实现一键下载代码,省去设置 BOOT0、按复位的麻烦。

       设置好之后,我们就可以通过按开始编程(P)这个按钮,一键下载代码到 STM32 上,下 载成功后如图 所示: 

      图中,我们圈出了 ATK-XISP 对一键下载电路的控制过程,先是获取芯片信息,然后 对全片擦除,还显示了文件的首地址以及文件大小等。 另外,下载成功后,会有“共写入 xxxxKB,进度 100%,耗时 xxxx 毫秒”的提示,并且从 0X80000000 处开始运行了。此时表示代码下载完成,并已经成功运行了,我们查看开发板就可以看到 DS0(红灯)、DS1(绿灯)开始交替闪烁了,如图所示: 

至此,STM32 使用串口下载程序完成。 

2.3.4 STM32的启动模式分析(M3、M4)

      从上面可以看出,整个过程,你得跳动 2 次跳线帽,还得按 2 次复 位,比较繁琐。而我们的一键下载电路,则利用串口的 DTR 和 RTS 信号,分别控制 STM32 的 复位和 B0,配合正点原子团队研发的上位机软件 ATK-XISP,设置:DTR 的低电平复位,RTS 高电平进 BootLoader,这样,B0 和 STM32 的复位,完全可以由下载软件自动控制(B0 和 B1 使用一键下载电路后从始至终只需接 GND 即可),从而实现一键下载。

2.3.5 串口下载一键电路(了解)

      一键下载电路,是利用串口的DTR和RTS信号,分别控制STM32的复位和BOOTO
引脚,配合ATK-XISP.exe软件,设置: DTR低电平复位,RTS高电平进BootLoader,
这样,BOOTO和STM32的复位引脚,完全由下载软件自动控制,从而实现一键下载。

三、 使用 DAP 下载与调试程序

3.1使用DAP下载程序

        上一节我们使用串口给 STM32 下载程序,但是串口下载并不能仿真调试代码,只能下载后 观看运行结果,所以在调试代码 bug 的时候,最好还是用仿真器进行下载调试,本节我们将给 大家介绍如何使用仿真器给 STM32 下载代码,并调试代码。 这里我们以 DAP 仿真器为例给大家进行讲解,如果你用的是其他仿真器,基本上也是一样 的用法,只是选择仿真器的时候,选择对应的型号即可。

3.1.1 DAP下载程序硬件连接

      DAP 与开发板连接如图所示:

a) DAP 通过 USB 线连接电脑,且仿真器①处的蓝灯常亮。

b) DAP 通过 20P 灰排线连接开发板。

c) 确保开发板已经正常供电(可经由图中的⑤⑥给开发板供电,但我们建议使用⑤处的电源插座+开发板适配的 DC 直流电源,以避免部分需要用到大电流的例程运行不正常), 供电后确保⑦处的开关是按下的状态,这里蓝色电源灯亮起表示开发板已经正常供电。

d) B0,B1 都接 GND。 

3.1.2 在MDK上配置DAP

      打开 MDK IDE 界面,点击魔术棒按钮,在 Debug 栏选择仿真工具为 use:CMSIS-DAP Debugger,如图所示:

① 选择使用 CMSIS-DAP Debugger 仿真器仿真调试代码。如果你使用的是其他仿真器, 比如 STLINK、JLINK 等,请在这里选择对应的仿真器型号。

② 该选项选中后,只要点击仿真就会直接运行到 main 函数,如果没选择这个选项,则会先执行启动文件 startup_stm32f407xx.s 文件的 Reset_Handler,再跳到 main 函数。 然后我们点击 Settings,设置 DAP 的一些参数,如图所示:

① 表示 MDK 找到了 ATK CMSIS-DAP 仿真器,如果这里显示为空,则表示没有仿真器被找到,请检查你的电脑是否接了仿真器?并安装了对应的驱动(DAP不需要安装驱动)?

② 设置接口方式,这里选择 SW(比 JTAG 省 IO),通信速度设置为 10Mhz(实际上大概 只有 4M 的速度,MDK 会自动匹配)。

③ 表示 MDK 通过仿真器的 SW 接口找到了目标芯片,ID 为:0x1BA01477。如果这里显 示:No target connected,则表示没找到任何器件,请检查仿真器和开发板连接是否正常?开发板是否供电了? 其他部分使用默认设置,设置完成以后单击“确定”按钮,完成此部分设置。

接下来我们还需要在 Utilities 选项卡里面设置下载时的目标编程器,如图所示:

上图中,我们直接勾选 Use Debug Driver,即和调试一样,选择 DAP 来给目标器件的 FLASH 编程,然后点击 Settings,进入 FLASH 算法设置,设置如图所示: 

       这里 MDK5 会根据我们新建工程时选择的目标器件,自动设置 flash 算法。我们使用的是 STM32F407ZGT6,FLASH 容量为 1M 字节,所以 Programming Algorithm 里面默认会有 1M 型 号的 STM32F4xx Flash 算法。另外,如果这里没有 flash 算法,大家可以点击 Add 按钮,自行添加即可。最后,选中 Reset and Run 选项以实现在编程后自动运行,其他默认设置即可。 在设置完之后,点击“确定”,然后再点击“OK”,回到 IDE 界面,编译(可按 F7 快捷键) 一下工程,编译完成以后(0 错误,0 警告),我们按Load下载按钮(快捷键:F8)这个按钮,就可以将代码通过仿真器下载到开发板上,在 IDE 下方的 Build Output 窗口会提示相关信息,如下图所示:

下载完后,就可以看到 DS0 和 DS1 交替闪烁了,说明代码下载成功。

3.2使用DAP仿真调试程序(掌握)

 说在前面:

    1. 仿真调试找 bug 是一个软件工程师必备的基本技能。MDK 提供了很多工具和窗口来辅 助我们找问题,只要多使用,多练习,肯定就可以把仿真调试学好。这对我们后续的独立开发 项目,非常有帮助。因此极力推荐大家多练习使用仿真器查找代码 bug,学会这个基本技能。

   2.调试代码不要浅尝辄止,要想尽办法找问题,具体的思路:先根据代码运行的实际现象 分析问题,确定最可能出问题的地方,然后在相应的位置放置断点,查看变量,查看寄存器, 分析运行状态和预期结果是否一致?从而找到问题原因,解决 bug。特别提醒:一定不要浅尝 辄止,很多朋友只跟踪到最上一级函数,就说死机了,不会跟踪进去找问题!所以一定要一层 层进入各种函数,越是底层(甚至汇编级别),越好找到问题原因。

3.2.1 仿真界面简单介绍

       在正常编译完例程以后(0 错误,0 警告),点击:(开始/停止仿真按钮),开始仿真(如 果开发板的代码没被更新过,则会先更新代码(即下载代码),再仿真),如图所示:开始仿真的默认窗口,我们就给大家介绍这几个,实际上还有一些其他的窗口,比如 Watch、 Memory、外设寄存器等也是很常用的,可以根据实际使用选择调用合适的窗口来查看对应的数据。

 ① Register寄存器窗口,显示了 Cortex M4 内核寄存器 R0~R15 的值,还显示了内部的线程模式(处理者模式、线程模式)及特权级别(用户级、特权级),并且还显示了当前程序的运行时间(Sec),该选项卡一般用于查看程序运行时间,或者比较高级的 bug 查找(涉及 到分析 R0~R14 数据是否异常了)。

② Disassembly反汇编窗口,将 C 语言代码和汇编对比显示(指令存放地址,指令代码,指 令,具体操作),方便从汇编级别查看程序运行状态,同样也属于比较高级别的 bug 查找。

③ 代码窗口,在左侧有黄绿色三角形,黄色的三角形表示将要执行的代码,绿色的三角形表 示当前光标所在代码(C 代码 或 当前汇编行代码对应的 C 代码)。一般情况下,这两个三 角形是同步的,只有在点击光标查看代码的时候,才可能不同步。

④ Call Stack + Locals调用关系&局部变量窗口,通过该窗口可以查看函数调用关系,以及函数的局部变量,在仿真调试的时候,是非常有用的。

图中,还有一个很重要的工具条:Debug 工具条,其内容和作用如图所示:

      各个按钮的作用如下所示:

1.复位:其功能等同于硬件上按复位按钮。相当于实现了一次硬复位。按下该按钮之后,代 码会重新从头开始执行。

2.执行到断点处:该按钮用来快速执行到断点处,有时候你并不需要观看每步是怎么执行的, 而是想快速的执行到程序的某个地方看结果,这个按钮就可以实现这样的功能,前提是你在查看的地方设置了断点。

3.停止运行:此按钮在程序一直执行的时候会变为有效,通过按该按钮,就可以使程序停止 下来,进入到单步调试状态。

4.执行进去:该按钮用来实现执行到某个函数里面去的功能,在没有函数的情况下,是等同 于执行过去按钮的。

5.执行过去:在碰到有函数的地方,通过该按钮就可以单步执行过这个函数,而不进入这个 函数单步执行。

6.执行出去:该按钮是在进入了函数单步调试的时候,有时候可能不必再执行该函数的剩余 部分了,通过该按钮就可以一步执行完该函数的余部分,并跳出函数,回到函数被调用的位置。

7.执行到光标处:该按钮可以迅速的使程序运行到光标处,其实是挺像执行到断点处按钮功 能,但是两者是有区别的,断点可以有多个,但是光标所在处只有一个。

8.反汇编窗口:通过该按钮,就可以查看汇编代码,这对分析程序很有用。

9.Call STACK 窗口:通过该按钮,显示调用关系&局部变量窗口,显示当前函数的调用关系 和局部变量,方便查看,对分析程序非常有用。

10.观察窗口:MDK5 提供 2 个观察窗口(下拉选择),该按钮按下,会弹出一个显示变量的窗口,输入你所想要观察的变量/表达式,即可查看其值,是很常用的一个调试窗口

11.内存查看窗口:MDK5 提供 4 个内存查看窗口(下拉选择),该按钮按下,会弹出一个内存查看窗口,可以在里面输入你要查看的内存地址,然后观察这一片内存的变化情况。是很常用的一个调试窗口

12.串口打印窗口:MDK5 提供 4 个串口打印窗口(下拉选择),该按钮按下,会弹出一个类似串口调试助手界面的窗口,用来显示从串口打印出来的内容。

13.系统分析窗口:该图标下面有 6 个选项(下拉选择),我们一般用第一个,也就是逻辑分析窗口(Logic Analyzer),点击即可调出该窗口,通过 SETUP 按钮新建一些 IO 口,就可以观察这些 IO 口的电平变化情况,以多种形式显示出来,比较直观。

14.系统查看窗口:该按钮可以提供各种外设寄存器的查看窗口(通过下拉选择),选择对应外设,即可调出该外设的相关寄存器表,并显示这些寄存器的值,方便查看设置的是否正确。

     Debug 工具条上的其他几个按钮用的比较少,我们这里就不介绍了。以上介绍的是比较常用的,当然也不是每次都用得着这么多,具体看你程序调试的时候有没有必要观看这些东西, 来决定要不要看。 

3.2.2 具体展示调试过程

       在图仿真界面的基础上:关闭反汇编窗口(Disassembly)、添加观察窗口 1(Watch1)。 然后调节一下窗口位置,然后将全局变量:g_fac_us (在 delay.c 里面定义)加入 Watch1 窗口 (方法:双击 Enter expression 添加/直接拖动变量 t 到 Watch1 窗口即可),如图所示:

    此时可以看到 Watch1 窗口的 g_fac_us 的值提示:无法计算,我们把鼠标光标放在第 32 行 左侧的灰色区域,然后按下鼠标左键,即可放置一个断点(红色的实心点,也可以通过鼠标右 键弹出菜单来加入),这样就在 delay_init 函数处放置一个断点,然后点击执行到断点处图标,执行到该断点处,然后再点击执行进去图标,执行进入 delay_init 函数,如图所示:

       此时,可以看到 g_fac_us 的值已经显示出来了,默认是 0(全局变量如果没有赋初值,一 般默认都是 0),然后继续单击执行进去图标 ,单步运行代码到 g_fac_us = sysclk; 这一行,再把鼠标光 标放在 sysclk 上停留一会,就可以看到 MDK 自动提示 sysclk(delay_init 的输入参数)的值为: 0X00A8,即 168,如图所示:

然后再单步执行过去这一行,就可以在 Watch1 窗口中看到 g_fac_us 的值变成 0X000000A8 了,如图 所示: 

       由此可知,某些全局变量,我们在程序还没运行到其所在文件的时候,MDK 仿真时可能不 会显示其值(如提示:cannot evaluate),当我们运行到其所在文件,并实际使用到的时候,此时 就会显示其值出来了!

       然后,我们再回到 main.c,在第一个 LED0(0)处放置一个断点,运行到断点处,如图 所示:

       此时,我们点击执行过去图标 ,执行过这一行代码,就可以看到开发板上的 DS0(红灯)亮起来了, 以此继续点击执行过去图标  ,依次可以看到:DS0 灭→DS1 亮→DS0 亮→DS1 灭→DS0 灭→DS1 亮……, 一直循环。这样如果全速运行,就可以看到 DS0,DS1 交替亮灭,不过全速运行的时候,一般是看不出 DS0 和 DS1 全亮的情况的,而通过仿真,我们就可以很容易知道有 DS0 和 DS1 同时亮的情况!

最后,我们在 delay.c 文件的 delay_us 函数,第二行处设置一个断点,然后运行到断点处, 如图 所示:

       此时,我们可以从 Call Stack + Locals 窗口看到函数的调用关系,其原则是:从下往上看, 即下一个函数调用了上一个函数,因此,其关系为:main 函数调用了 delay_ms 函数,然后 delay_ms 函数调用了 delay_us 函数。这样在一些复杂的代码里面(尤其是第三方代码),可以 很容易捋出函数调用关系并查看其局部变量的值,有助于我们分析代码解决问题。 关于 DAP 的仿真调试,我们暂时就讲这么多。 

3.3仿真调试注意事项

 1.由于 MDK5.23 以后对中文支持不是很好,具体现象是:在仿真的时候,当有断点未清 除时点击 开始/停止仿真按钮结束仿真,会出现如图所示的报错:


此时我们点击确定,是无法关闭 MDK 的,只能到电脑的任务管理器里面强制结束 MDK, 才可以将其关闭,比较麻烦。 该错误就是由于 MDK5.23 以后的版本对中文支持不太好导致的,这里提供 2 个解决办法:

a,仿真结束前将所有设置的断点都清除掉,可以使用 File 工具栏的:清除所有断点按钮,快速清除当前 工程的所有断点,然后再结束仿真,就不会报错;

b,将工程路径改浅,并改成全英文路径。注意:例程名字一般可以不用改英文,因为只要整个路径不超过 10 个汉字,一般就不会报错了,如果还报错就再减少汉字数量)。

        通过这两个方法,可以避免仿真结束报错的问题。我们推荐大家使用第二种方法,因为这样就不用每次都全部清除所有断点,下回仿真又得重设的麻烦。

2、关于 STM32 软件仿真,由于其限制较多(只支持部分 F1 型号),而且仿真器越来越便宜,硬件仿真更符合实际调试需求,调试效果更好。所以后续我们只介绍硬件仿真,不再推荐大家使用软件仿真了! 

四、 MDK5 使用技巧

       本节,我们将向大家介绍 MDK5 软件的一些使用技巧,这些技巧在代码编辑和编写方面会 非常有用,希望大家好好掌握,最好实际操作一下,加深印象。

4.1文本美化

      文本美化,主要是设置一些关键字、注释、数字等的颜色和字体。如果你刚装 MDK,没进 行字体颜色配置,以跑马灯例程为例,你的界面效果如图所示:

        上图是 MDK 默认的设置,可以看到其中的关键字和注释等字体的颜色不是很漂亮,而 MDK 提供了我们自定义字体颜色的功能。我们可以在工具条上点击扳手按钮(配置对话框)弹出如图 所示界面。

① 设置代码编辑器字体使用:Chinese GB2312(Simplified),以更好的支持中文。

② 设置编辑器的空格可见:View White Space,所有空格使用“.”替代,TAB 使用“→”替代, 这样可以方便我们对代码进行对齐操作。同时,我们推荐所有的对齐都用空格来替代, 这样在不同软件之间查看源代码,就不会引起由于 TAB 键大小不一样导致代码不对齐 的问题,方便使用不同软件查看和编辑代码。也可以不用,根据自己实际情况。

③ 设置 C/C++文件,TAB 键的大小为 4 个字符,且字符使用空格替代(Insert spaces for tabs)。这样我们在使用 TAB 键进行代码对齐操作的时候,都会用空格替代,保证不同 软件使用代码都可以对齐。 

        然后,选择:Colors & Fonts 选项卡,在该选项卡内,我们就可以设置自己的代码的字体和 颜色了。由于我们使用的是 C 语言,故在 Window 下面选择:C/C++ Editor Files 在右边就可以 看到相应的元素了。如图所示: 然后点击各个元素(Element)修改为你喜欢的颜色(注意双击,且有时候可能需要设置多次才生效,MDK 的 bug),当然也可以在 Font 栏设置你字体的类型,以及字体的大小等。

     然后,点击 User Keywords 选项卡,设置用户定义关键字,以便用户自定义关键字也显示 对应的颜色(对应上图中的 User Keyword/Lable 颜色)。在 User Keywords 选项卡对话框下面输入你自己定义的关键字,如图 所示:

这里我们设置了 uint8_t、uint16_t 和 uint32_t 等三个用户自定义关键字,相当于 unsigned char、unsigned short 和 unsigned int。如果你还有其他自定义关键字,在这里添加即可。设置成 之后,点击 OK,就可以在主界面看到你所修改后的结果,例如我修改后的代码显示效果如图所示:

      这就比开始的效果好看一些了。字体大小,则可以直接按住:ctrl+鼠标滚轮,进行放大或 者缩小,或者也可以在刚刚的配置界面设置字体大小。 同时,上图中可以看到空白处有很淡的一些……显示,这就是我们勾选了 View White Space 选项后体现出来的效果,可以方便我们对代码进行规范对齐整理。一开始看的时候可能有点不习惯,看多了就习惯了,大家慢慢适应就好了。  

4.2语法检测&代码提示(掌握)

      MDK4.70 以上的版本,新增了代码提示与动态语法检测功能,使得 MDK 的编辑器越来越好用了,这里我们简单说一下如何设置,同样点击扳手按钮 ,打开配置对话框,选择 Text Completion 选项卡,如图所示:

Strut / Class Members,用于开启结构体/类成员提示功能。

Function Parameters,用于开启函数参数提示功能。

Symbols after xx characters,用于开启代码提示功能,即在输入多少个字符以后,提示匹配 的内容(比如函数名字、结构体名字、变量名字等),这里默认设置 3 个字符以后,就开始提示。 如图所示: 

ENTER/TAB as fill-up character,使用回车和 TAB 键填充字符。 Dynamic Syntax Checking,则用于开启动态语法检测,比如编写的代码存在语法错误的时候,会在对应行前面出现红色叉图标,如出现警告,则会出现黄色警告图标,将鼠标光标放图标上面,则会提示产生的错误/警告的原因,如图所示:

总结:

       这几个功能,对我们编写代码很有帮助,可以加快代码编写速度,并且及时发现各种问题。 不过这里要提醒大家,语法动态检测这个功能,有的时候会误报(比如 sys.c 里面,就有误报), 大家可以不用理会,只要能编译通过(0 错误,0 警告),这样的语法误报,一般直接忽略即可。 

4.3代码编辑技巧(掌握)

      这里给大家介绍几个我常用的技巧,这些小技巧能给我们的代码编辑带来很大的方便,相 信对你的代码编写一定会有所帮助。

4.3.1 TAB键的妙用

        首先要介绍的就是 TAB 键的使用,这个键在很多编译器里面都是用来空位的,每按一下移 空几个位。如果你是经常编写程序的对这个键一定再熟悉不过了。但是 MDK 的 TAB 键和一般编译器的 TAB 键有不同的地方,和 C++的 TAB 键差不多。MDK 的 TAB 键支持块操作。也就是可以让一片代码整体右移固定的几个位,也可以通过SHIFT+TAB键整体左移固定的几个位。假设我们前面的串口 1 中断回调函数如图所示:

    上图的代码很不规范,这还只是短短的 30 来行代码,如果你的代码有几千行,全部是这个样子,不头大才怪。这时我们就可以通过 TAB 键的妙用来快速修改为比较规范的代码格式。选中一块然后按 TAB 键,你可以看到整块代码都跟着右移了一定距离,如图所示:

接下来我们就是要多选几次,然后多按几次 TAB 键就可以达到迅速使代码规范化的目的, 最终效果如图 所示: 

 上图中的代码好看多了,经过这样的整理之后,整个代码一下就变得有条理多了,看起来很舒服。

4.3.2 快速跳到函数/变量被定义的地方

     上一节,我们介绍了 TAB 键的功能,接下来我们介绍一下如何快速查看一个函数或者变量所定义的地方。 大家在调试代码或编写代码的时候,一定有想看看某个函数是在那个地方定义的,具体里 面的内容是怎么样的,也可能想看看某个变量或数组是在哪个地方定义的等。尤其在调试代码 或者看别人代码的时候,如果编译器没有快速定位的功能的时候,你只能慢慢的自己找,代码 量比较少还好,如果代码量一大,那就郁闷了,有时候要花很久的时间来找这个函数到底在哪 里。型号 MDK 提供了这样的快速定位的功能。具体操作方法如下只要你把光标放到这个函数/变量(xxx)的上面 (xxx 为你想要查看的函数或变量的名字),然后右键,可以看到如下图所示的菜单栏。 在下图中,我们找到 Go to Definition Of‘sys_stm32_clock_init’ 这个地方,然后单击 左键就可以快速跳到 sys_stm32_clock_init 函数的定义处。

 

注意:要先在 Options for Target 的 Output 选项卡里面勾选 Browse Information 选项,再编译,再定位,否则无法定位!)。如图所示:

        对于变量,我们也可以按这样的操作快速来定位这个变量被定义的地方,大大缩短了你查 找代码的时间。 很多时候,我们利用 Go to Definition 看完函数/变量的定义后,又想返回之前的代码继续看,此时我们可以通过 IDE 上的方向向左的箭头按钮(Back to previous position)快速的返回之前的位置, 这个按钮非常好用!


4.3.3 快速注释与快速取消注释

       接下来,我们介绍一下快速注释与快速消注释的方法。在调试代码的时候,你可能会想注 释某一片的代码,来看看执行的情况,MDK 提供了这样的快速注释/消注释块代码的功能。也 是通过右键实现的。这个操作比较简单,就是先选中你要注释的代码区,然后右键,选择Advanced→Comment Selection 就可以了。以 led_init 函数为例,比如我要注释掉下图中所选中区域的代码,如图所示:

     我们只要在选中了之后,选择右键,再选择 Advanced→Comment Selection 就可以把这段代 码注释掉了。执行这个操作以后的结果如图 所示:

      这样就快速的注释掉了一片代码,而在某些时候,我们又希望这段注释的代码能快速的取 消注释,MDK 也提供了这个功能。与注释类似,先选中被注释掉的地方,然后通过右键 →Advanced,不过这里选择的是 Uncomment Selection。 

4.4 查找替换技巧

4.4.1 快速打开头文件

        第一个是快速打开头文件。在将光标放到要打开的引用头文件上,然后右键选择 Open Document“XXX”,就可以快速打开这个文件了(XXX 是你要打开的头文件名字)。如图所示:

4.4.2 查找替换功能

       第二个小技巧是查找替换功能。这个和 WORD 等很多文档操作的替换功能是差不多的,在 MDK 里面查找替换的快捷键是“CTRL+H,只要你按下该按钮就会调出如图 4.4.4.2 所示界面:

     

这个替换的功能在有的时候是很有用的,它的用法与其他编辑工具或编译器的差不多,相 信各位都不陌生了,这里就不啰嗦了。

4.4.3 跨文件查找功能

       第三个小技巧是跨文件查找功能,先双击你要找的函数/变量名(这里以系统时钟初始化函 数:sys_stm32_clock_init 为例),然后再点击 IDE 上面的文件按钮 ,弹出如图所示对话框:

 

 

     点击 Find All,MDK 就会帮你找出所有含有 Stm32_Clock_Init 字段的文件并列出其所在位 置,如图所示:

该方法可以很方便的查找各种函数/变量,而且可以限定搜索范围(比如只查找.c 文件和.h 文件等),是非常实用的一个技巧。

五、工程编译问题定位

在Build Output窗口,可以双击error/warning,可定位问题所在位置
解决error/warning,  建议的顺序是:从上往下

六、窗口视图管理

窗口视图恢复默认状态的方法: window→Reset View to Defaults + Reset

     以上便是STM32初体验的全部内容,涵盖了方方面面,从0开始入门,可谓是网上最全教程,后面会逐步介绍每个外设的固件库使用方法,如有兴趣,感谢点赞、关注、收藏,若有不正地方,还请各位大佬多多指教!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/5943.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安装部署大语言模型 | 通义千问

下载安装 进入ollama的仓库下载 「 qwen 7b 」 libraryGet up and running with large language models.https://ollama.com/library查找阿里的 「 qwen 」 根据自己的电脑配置情况,选择合适的模型 总体来说,模型是越大,效果越好&#xff0c…

019、Python+fastapi,第一个Python项目走向第19步:windows 11 下的pycharm远程连接ubuntu 24.04 服务器

一、说明 欲善其事,必先利其器,先把环境整好,我开发的环境是ubuntu是没有gui的服务器版本,所以必须远程搞才行,今天就是安装一下,链接连接,网上有很多文章,能成功,不过我也弄了一个…

SQL——高级教程【菜鸟教程】

SQL连接 左连接:SQL LEFT JOIN 关键字 左表相当于主表,不管与右表匹不匹配都会显示所有数据 右表就只会显示和左表匹配的内容。 //例显示:左表的name,有表的总数,时间 SELECT Websites.name, access_log.count, acc…

GitHub Copilot Workspace:欢迎进入原生Copilot开发环境

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

Vue 组件的三大组成部分

Vue 组件通常由三大组成部分构成:模板(Template)、脚本(Script)、样式(Style) 模板部分是组件的 HTML 结构,它定义了组件的外观和布局。Vue 使用基于 HTML 的模板语法来声明组件的模…

【Vulhub靶场】Nginx 漏洞复现

Nginx 漏洞复现 一、Nginx 文件名逻辑漏洞(CVE-2013-4547)1、影响版本2、漏洞原理3、漏洞复现 二、Nginx 解析漏洞1、版本信息:2、漏洞详情3、漏洞复现 一、Nginx 文件名逻辑漏洞(CVE-2013-4547) 1、影响版本 Nginx …

网际协议IP

一、概念导入 网际协议IP是TCP/IP体系中最重要的协议之一。与IP协议配套使用的还有三个协议: 地址解析协议ARP网际控制报文协议ICMP网际组管理协议IGMP 二、虚拟互联网络 (1)定义 现实世界中,不同网络的主机进行通信&#xf…

Centos7.9系统MySQL5.7.32升级为5.7.44(生成环境操作)

1.背景 由于客户进行等保漏扫和渗透,生成环境mysql数据库被扫描出了 高危漏洞。 如图:部分漏洞 查看漏洞详细信息,建议升级到指定版本解决: 说明: 本文仅适合使用当前数据库为 RPM 安装方式 2.升级前准备 查看环…

nginx的前世今生(三)

高手对决:武林盟主之路 1.不败之地,高可用江湖 技术角度讲,高可用(High Availability, HA)是指系统或服务能够在预定的时间内,以极高的概率持续提供服务的能力。具体来说,这通常涉及到系统的架…

32.Docker认识

Docker介绍 Docker是一个快速交付应用,运行应用的技术。 1.可以将程序、依赖、运行环境一起打包为一个镜像,可以迁移到任意Linux操作系统。 2.运行时利用沙箱机制行程隔离容器,各个应用互不干扰。 3.启动、移除都可以通过一行命令完成&am…

I2C接口18路LED呼吸灯驱动IS31FL3218互相替代SN3218替换HTR3218

I2C接口18路LED呼吸灯控制电路IC 该型号IC为QFN24接口,属于小众产品,IS31FL3218、SN3218、HTR3218S管脚兼容,需要注意的是HTR3218管脚与其他型号不兼容。 I2C接口可实现多个LED灯的呼吸灯控制,可实现单色控制18个LED灯&#xff0…

Kubernetes - Dashboard 配置用户名密码方式登录

Kubernetes - Dashboard 配置用户名密码方式登录 前言: 为了 K8s 集群安全,默认情况下 Dashboard 以 Token的形式登录的,那如果我们想以用户名/密码的方式登录该怎么操作呢?其实只需要我们创建用户并进行 ClusterRoleBinding绑定即…

Educational Codeforces Round 165 (Rated for Div. 2 ABCDE 题)视频讲解

A. Two Friends Problem Statement Monocarp wants to throw a party. He has n n n friends, and he wants to have at least 2 2 2 of them at his party. The i i i-th friend’s best friend is p i p_i pi​. All p i p_i pi​ are distinct, and for every i ∈…

并发编程之线程池的设计和原理

一、线程池 提前创建一系列的线程,保存在这个线程池中,有任务要执行的时候,从线程池中取出线程来执行。没有任务的时候,线程池放回去。 二、为什么要使用线程池 线程使用上的问题: 线程的频繁创建 和 销毁 线程的数量过多&…

政安晨:【Keras机器学习示例演绎】(二十六)—— 图像相似性搜索的度量学习

目录 概述 设置 数据集 嵌入模型 测试 政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正! 本文…

基于Pytorch深度学习——多层感知机

本文章来源于对李沐动手深度学习代码以及原理的理解,并且由于李沐老师的代码能力很强,以及视频中讲解代码的部分较少,所以这里将代码进行尽量逐行详细解释 并且由于pytorch的语法有些小伙伴可能并不熟悉,所以我们会采用逐行解释小…

Word域代码学习(简单使用)-【SEQ】

Word域代码学习(简单使用)-【SEQ】 快捷键 序号快捷键操作1 Ctrl F9 插入域代码花括号2 F9 显示域代码结果3 Shift F9 切换为域代码4 Windows Alt F9 切换全部域代码 域代码说明 域代码不区分大小写在word中,依次选择插入➡文档部件➡域即可选择插入…

Linux 学习 --- 编辑 vi 命令

1、vi 基本概念(了解) 基本上 vi 可以分为三种状态,分别是命令模式 (command mode)、插入模式 (Insert mode) 和底行模式 (last line mode),各模式的功能区分如下: 命令行模式 command mode)  控制屏幕光标的移动&a…

PotatoPie 4.0 实验教程(31) —— FPGA实现摄像头图像高斯滤波

什么是高斯滤波 高斯滤波是一种常见的图像处理技术,用于去除图像中的噪声和平滑图像。它的原理基于统计学中的高斯分布(也称为正态分布)。 在高斯滤波中,一个二维的高斯核函数被用来对图像中的每个像素进行加权平均。这个高斯核…

jvm 马士兵 01

01.JVM是什么 JVM是一个跨平台的标准 JVM只识别class文件,符合JVM规范的class文件都可以被识别