完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>
1)实验平台:ALIENTEK NANOSTM32F411 V1开发板
2)摘自《正点原子STM32F4 开发指南(HAL 库版》关注官方微信号公众号,获取更多资料:正点原子 3.3.2.3 Msp 回调函数执行过程解读 大家先打开我们前面新建的工程模板,搜索 MspInit 字符串可以发现,在我们的工程模板文件中,有 70 多个文件定义或者调用了函数名字中包含 MspInit 字符串的函数,而且函数名字基本基本遵循 HAL_PPP_MspInit 格式(PPP 代表任意外设)。那么这些函数是怎么被程序调用, 又是什么作用呢?下面我们以串口为例进行讲解。 大家打开我们的工程模板 SYSTEM 分组下面的 usart.c 文件可以看到,内部我们定义了两个函数 uart_init 和 HAL_UART_MspInit。我们先来大致看看这两个函数的定义(基于篇幅考虑我们省略部分非关键代码行): void uart_init(u32 bound) { //UART 初始化设置 UART1_Handler.Instance=USART1; //USART1 UART1_Handler.Init.BaudRate=bound; //波特率 ...//此处省略部分串口 1 参数设置代码 UART1_Handler.Init.Mode=UART_MODE_TX_RX; //收发模式 HAL_UART_Init(&UART1_Handler); //HAL_UART_Init()会使能 UART1 ...//此处省略部分串口 1 参数设置代码 } //UART 底层初始化,时钟使能,引脚配置,中断配置 void HAL_UART_MspInit(UART_HandleTypeDef *huart) { ...//此处省略部分代码 GPIO_Initure.Pin=GPIO_PIN_9; //PA9 GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速 HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化 PA9 GPIO_Initure.Pin=GPIO_PIN_10; //PA10 GPIO_Initure.Mode=GPIO_MODE_AF_INPUT;//模式要设置为复用输入模式! HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化 PA10 ...//此处省略部分代码 } 用户函数 uart_init 主要作用是设置串口 1 相关参数,包括波特率,停止位,奇偶校验位等, 并且最终是通过调用 HAL_UART_Init 函数进行参数设置。而函数 HAL_UART_MspInit 则主要 进行串口 GPIO 引脚初始化设置。接下来我们打开 usart_init 函数内部调用的 UART 初始化函数 HAL_UART_Init 可以看到代码如下: HAL_StatusTypeDefHAL_UART_Init(UART_HandleTypedef*huart) { ...//此处省略部分代码 if(huart->State == HAL_UART_STATE_RESET)//如果串口没有进行过初始化 { huart->Lock = HAL_UNLOCKED; HAL_UART_MspInit(huart); } ...//此处省略部分代码 Return HAL_OK; } 在函数 HAL_UART_Init 内部,通过判断逻辑判断如果串口还没有进行初始化,那么会调用 函 数 HAL_UART_MspInit 进 行 相 关 初 始 化 设 置 。 同 时 , 我 们 可 以 看 到 , 在 文 件stm32f4xx_hal_uart.c 内部,有定义一个弱函数 HAL_UART_MspInit,内容如下: __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart) { UNUSED(huart); } 这里定义的弱函数 HAL_UART_MspInit 是一个空函数,没有任何实际的控制逻辑。根据前面的讲解可知,__weak 修饰符定义的弱函数如果用户自己重新定义了这个函数,那么会优先执行用户定义函数。所以,实际上在函数 HAL_UART_Init 内部调用的 HAL_UART_MspInit()函数, 最终执行的是用户在 usart.c 中自定义的 HAL_UART_MspInit()函数。 那 么 整 个 串 口 初 始 化 的 过 程 为 : 用 户 函 数 usart_init-> HAL_UART_Init->HAL_UART_MspInit。学到这里的同学会问,为什么串口相关初始化不在HAL_UART_Init 函数内部一次初始化而还要调用函数 HAL_UART_MspInit()呢?这实际就是 HAL 库的一个优点,他通过开放一个回调函数 HAL_UART_MspInit(),让用户自己去编写与串口相关的 MCU 级别的硬件初始化,而与 MCU 无关的串口参数相关的通用配置则放在 HAL_UART_Init。 我们要初始化一个串口,首先要设置和 MCU 无关的东西,例如波特率,奇偶校验,停止位等,这些参数设置和 MCU 没有任何关系,可以使用 STM32F1,也可以是 STM32F2/F3/F4/F7 上的串口。而一个串口设备它需要一个 MCU 的承载,例如用 STM32F4 来做承载,PA9 做为发 送,PA10 做为接收,MSP 就是要初始化 STM32F4 的 PA9,PA10,配置这两个引脚。所以 HAL 驱动方式的初始化流程就是:HAL_USART_Init()->HAL_USART_MspInit(),先初始化与 MCU 无 关 的 串 口 协 议 , 再 初 始 化 与 MCU 相 关 的 串 口 引 脚 。 在 STM32 的 HAL 驱 动 中 HAL_PPP_MspInit()作为回调,被 HAL_PPP_Init()函数调用。当我们需要移植程序到 STM32F1平台的时候,我们只需要修改 HAL_PPP_MspInit 函数内容而不需要修改 HAL_PPP_Init 入口参数内容。 在 STM32 的 HAL 库中,大部分外设都有回调函数 HAL_MspInit,通过对本小节学习,大家对这些回调函数的作用和调用过程会非常熟悉,这里我们就不做一一列举。 3.3.2.4 程序执行流程图 经过前面的讲解,大家对工程模板以及关键文件有了比较详细的了解。接下来我们看看程序执行流程如下图 3.3.2.4.1 所示:
图 3.3.2.4.1 程序执行流程
从该流程图可以非常清晰的理解整个程序执行流程,这里我们略微讲解一下。启动文件 startup_stm32f411xe.s 中 Rest_Handler 部分会引导先执行 SystemInit 函数,然后再进入 main 函 数。在 main 函数内部,一般情况下,我们会把 HAL 初始化函数 HAL_Init 放在最开头部分,然 后再进行时钟初始化设置。这些设置完成之后,接下来便是调用外设初始化函数 HAL_PPP_Init 进行外设参数初始化设置,同时重写回调函数 HAL_PPP_MspInit 进行外设 MCU 相关的参数设 置。最后编写我们的控制逻辑。关于程序执行流程我们就给大家介绍到这里。 3.4 程序下载与调试 上一节,我们学会了如何在 MDK 下创建 STM32F4 工程。本节,我们将向读者介绍 STM32F4 的代码下载以及调试。包括了程序下载、软件 仿真和硬件调试(在线调试)。通过本章的学习, 你将了解到:1、STM32F4 程序下载;2、STM32F4 硬件调试; 3.4.1 ST_LINK 仿真器驱动安装 STM32F411 的程序下载有多种方法:USB、串口、JTAG、SWD 等,这几种方式,都可以 用来给 STM32F4 下载代码。NANO 板板载了 ST_LINK V2.1 版的仿真器,不用外接仿真器即 可下载仿真使用,十分的方便。 本节,我们将向大家介绍,板载的 ST_LINK 仿真器驱动的安装。 仿真器的 USB 口在 USB_JTAG 口,连接好 USB 口,首次上电,会提示安装 ST_LINK 驱 动,如图 3.4.2.1 所示:
图 3.4.1.1 安装驱动
若之前电脑是没有安装过 ST_LINK 驱动,这时,会提示安装失败,如图 3.4.2.2 所示:
图 3.4.1.2 驱动安装失败
打开光盘资料找到 5,软件资料->1,软件-> ST LINK 驱动及教程->ST LINK 驱动,解压 ST-LINK 官方驱动压缩包,打开后如图 3.4.2.3 所示:
图 3.4.1.3 官方驱动
根据自己的电脑是 32 位、还是 64 位,选择对应驱动的安装。 点击驱动安装,会弹出框,我们选择“下一步”,这时会提示是否安装驱动,我们点击安 装,如图 3.4.1.4 所示:
图 3.4.1.4 安装驱动
安装过程会有点久,请耐性等待。安装完成后,会弹出框提示安装成功,如图 3.4.1.5 所示:
图 3.4.1.5 安装完成
安装成功后,我们重新上电 NANO 板,这时任务栏弹出 ST_LINK 成功安装好驱动,如图 3.4.1.6-1 所示,设备管理器显示,如图 3.4.1.6-2 所示
图 3.4.1.6-2 设备管理器显示 STLink dongle
图 3.4.1.6-2 设备管理器显示 STLink dongle
细心的你会发现,当我们 USB 连接 USB_JTAG 口,无论 SW1 选择开关往“左拨”或“右 拨”(SW1 开关在后面会讲解),首次上电时,电脑会识别到 U 盘,如图 3.4.1.7 所示:
图 3.4.1.7 U 盘识别
我们往 U 盘存放文件是不行的,识别出 U 盘是 ST_LINK 的固件功能,我们无需管它,直 接正常使用就可以了。在前面我们也有介绍过,该仿真器除了有下载和仿真的功能外,还能支持虚拟串口的功能, 这里我们打开 XCOM 2.0 串口调试助手(XCOM V2.0,在光盘5,软件资料软件串口调 试助手里面),串口助手会识别到仿真器的虚拟串口,如图 3.4.1.8 所示:
图 3.4.1.8 虚拟串口识别
在设备管理器会显示已安装虚拟串口驱动,如图 3.4.1.9 所示:
图 3.4.1.9 USB 虚拟串口
在图 3.4.1.9 中可以看到,我们的 USB 虚拟串口被识别为 COM56,这里需要注意的是:不 同电脑可能不一样,你的可能是 COM4、COM5 等,但是 STLink Virtual COM Port,这个一定 是一样的。 仿真器的虚拟串口 TXD 和 RXD,是通过开发板的 P3 座子跳线帽短接 PA10 和 PA9,与 STM32F411RCT6 串口 通信时,P3 必须短接好,以免造成串口通信不正常,P3 座子如图 3.4.1.10 所示:
图 3.4.1.10 P3 座子
SW1 选择开关是用作切换仿真器的内部或外部使用,往左拨(INS)则对 STM32F411RCT6 芯片进行使用,往右拨(EXT)则对外部使用。 注意: SW1 开关必须在上电前选择好。SW1 开关如图 3.4.1.11 所示:
图 3.4.1.11 SW1 开关
当 SW1 开关往右拨(EXT),使用开发板留出的 P4 排针连接外部的 MCU 就可以使用了, P4 排针 5P 的 SWD 接口如图 3.4.1.12 所示:
图 3.4.1.12 SWD 接口
3.4.2 STM32F4 程序下载和调试 上一节,我们讲解了开发板的 ST_LINK 驱动的安装,这节中我们将讲解,STM32 下载代码和硬件调试。 1)STM32 下载代码 打开刚刚软件仿真的工程,点击 ,打开 Op tions for Target 选项卡,在 Dubeg 栏选择仿真 工具为 Use:ST-Link Debugger,如图 3.4.3.1 所示:
图 3.4.3.1 Dubeg 选项卡设置
然后我们点击 Setting,在 Debug Adapter 的 Unit 选项中会看到 ST-LINK 的版本号,若电脑同时插了 ST_LINK V2.0 和 V2.1 版本的仿真器时,下拉框会显示两个版本,这里我们需选择ST-LINK/V2-1 选项,由于仿真器是 SWD 模式,在 ort 选项中选择“SW”,最大速度 Max 设 置为 4Mhz,如图 3.4.3.2 所示:
图 3.4.3.2 ST_LINK 模式设置
点击确定,完成此部分配置,接下来我们还需要在 Utilities 选项卡里面设置下载时的目标编程器,如图 3.4.3.3 所示:
图 3.4.3.3 FLASH 编程器选择
图 3.4.3.3 中,我们直接勾选 Use Debug Driver,选择 ST_LINK V2.1 来给目标器件的 FLASH 编程,然后点击 Settings,进入 FLASH 算法设置,设置如图 3.4.3.4 所示:
图 3.4.3.4 FLASH 算法设置
这里 MDK5 会根据我们新建工程时选择的目标器件,自动设置 flash 算法。我们使用的是STM32F411RCT6,FLASH 容量为 256K 字节,所以 Programming Algorithm 里面默认会有 256K 型号的 STM32F4xx 256KB Flash 算法。另外,如果这里没有 flash 算法,大家可以点击 Add 按钮,自行添加即可。最后,选中 Reset and Run 选项,以实现在编程后自动运行,其他默认设置 即可。设置完成之后,如图 3.4.3.4 所示。 在设置完之后,点击确定,然后再点击 OK,回到 IDE 界面,编译一下工程。然后点击:(下载按钮),这时 IDE 会提示正在下载,左下角会显示下载进度,如图 3.4.3.5 所示:
图 3.4.3.5 程序正在下载
下载完成后,我们打开刚刚说的 XCOM 串口调试助手,选择 COM56 虚拟串口(得根据你的实际情况选择),设置波特率为:115200,会发现从 ALIENTEK NANO STM32F411 发回来 的信息,如图 3.4.3.6 所示:
图 3.4.3.6 程序开始运行
接收到的数据和我们期望的是一样的,证明程序没有问题。至此,说明我们下载代码成功了,并且从硬件上验证了我们代码的正确性。 2)STM32 硬件仿真 刚刚我们介绍了如何通过利用 ST-LINK 给 STM32 下载代码,并在 ALIENTEK NANOSTM32F4 上验证了我们程序的正确性。这个代码比较简单,所以不需要硬件调试,我们直接就一次成功了。可是,如果你的代码工程比较大,难免存在一些 bug,这时,就有必要通过在线 调试来解决问题了。下面我们将讲解下使用 ST-LINK 给 STM32 软件在线硬件仿真:点击,打开 Options for Target 选项卡,点击 Dubug 界面,在这页面中除了之前提到的设 置,这里我们勾选 Run to main(),该选项选中后,只要点击仿真就会直接运行到 main 函数,如果没选择这个选项,则会先执行 startup_stm32f411xe.s 文件的 Reset_Handler,再跳到 main 函数。 在设置完之后,点击确定,然后再点击 OK,回到 IDE 界面,编译一下工程。然后点击: (开始/停止仿真按钮),开始仿真(如果开发板的代码没被更新过,则会先更新代码(即下载 代码),再仿真,你也可以通过按 ,只下载代码,而不进入仿真。特别注意:开发板上的 B0 要设置到 GND,否则代码下载后不会自动运行的!),如图 3.4.2.1 所示:
图 3.4.2.1 开始仿真
因为我们之前勾选了 Run to main()选项,所以,程序直接就运行到了 main 函数的入口处。 另外,此时 MDK 多出了一个工具条,这就是 Debug 工具条,这个工具条在我们仿真的时 候是非常有用的,下面简单介绍一下 Debug 工具条相关按钮的功能。Debug 工具条部分按钮的 功能如图 3.4.2.2 所示:
图 3.4.2.2 Debug 工具条
复位:其功能等同于硬件上按复位按钮。相当于实现了一次硬复位。按下该按钮之后,代码会重新从头开始执行。 执行到断点处:该按钮用来快速执行到断点处,有时候你并不需要观看每步是怎么执行的,而是想快速的执行到程序的某个地方看结果,这个按钮就可以实现这样的功能,前提是你在查看的地方设置了断点。 停止运行:此按钮在程序一直执行的时候会变为有效,通过按该按钮,就可以使程序停止下来,进入到单步调试状态。 执行进去:该按钮用来实现执行到某个函数里面去的功能,在没有函数的情况下,是等同于执行过去按钮的。 执行过去:在碰到有函数的地方,通过该按钮就可以单步执行过这个函数,而不进入这个函数单步执行。 执行出去:该按钮是在进入了函数单步调试的时候,有时候你可能不必再执行该函数的剩 余部分了,通过该按钮就直接一步执行完函数余下的部分,并跳出函数,回到函数被调用的位 置。 执行到光标处:该按钮可以迅速的使程序运行到光标处,其实是挺像执行到断点处按钮功能,但是两者是有区别的,断点可以有多个,但是光标所在处只有一个。 汇编窗口:通过该按钮,就可以查看汇编代码,这对分析程序很有用。 堆栈局部变量窗口:通过该按钮,显示 Call Stack+Locals 窗口,显示当前函数的局部变量及其值,方便查看。 观察窗口:MDK5 提供 2 个观察窗口(下拉选择),该按钮按下,会弹出一个显示变量的窗口,输入你所想要观察的变量/表达式,即可查看其值,是很常用的一个调试窗口。 内存查看窗口:MDK5 提供 4 个内存查看窗口(下拉选择),该按钮按下,会弹出一个内存查看窗口,可以在里面输入你要查看的内存地址,然后观察这一片内存的变化情况。是很常 用的一个调试窗口 串口打印窗口:MDK5 提供 4 个串口打印窗口(下拉选择),该按钮按下,会弹出一个类 似串口调试助手界面的窗口,用来显示从串口打印出来的内容。 逻辑分析窗口:该图标下面有 3 个选项(下拉选择),我们一般用第一个,也就是逻辑分 析窗口(Logic Analyzer),点击即可调出该窗口,通过 SETUP 按钮新建一些 IO 口,就可以观察 这些 IO 口的电平变化情况,以多种形式显示出来,比较直观。 系统查看窗口:该按钮可以提供各种外设寄存器的查看窗口(通过下拉选择),选择对应 外设,即可调出该外设的相关寄存器表,并显示这些寄存器的值,方便查看设置的是否正确。 Debug 工具条上的其他几个按钮用的比较少,我们这里就不介绍了。以上介绍的是比较常 用的,当然也不是每次都用得着这么多,具体看你程序调试的时候有没有必要观看这些东西, 来决定要不要看。 特别注意:串口打印窗口和逻辑分析窗口仅在软件仿真的时候可用,而 MDK5 对 STM32F4 的软件仿真,基本上不支持(故本教程直接没有对软件仿真进行介绍了),所以,基本上这两 个窗口用不着。但是对 STM32F1 的软件仿真,MDK5 是支持的,在 F1 开发的时候,可以用到。 这样,我们在上面的仿真界面里面调出:堆栈局部变量窗口。如图 3.4.2.3 所示:
图 3.4.2.3 堆栈局部变量查看窗口
我们把光标放到 test.c 的第 11 行左侧的灰色区域,然后按下鼠标左键,即可放置一个断点 (红色的实心点,也可以通过鼠标右键弹出菜单来加入),再次单击则取消,然后点击 ,执行到该断点处,如图 3.4.2.4 所示:
图 3.4.2.4 执行到断点处
现在先不忙着往下执行,点击菜单栏的 Peripherals->System Viewer->USART->USART1。 可以看到,有很多外设可以查看,这里我们查看的是串口 1 的情况。如图 3.4.2.5 所示:
图 3.4.2.5 查看串口 1 相关寄存器
单击 USART1 后会在 IDE 右侧出现一个如图 3.4.2.6(a)所示的界面:
图 3.4.2.6 串口 1 各寄存器初始化前后对比
图 4.2.2.6(a)是 STM32 的串口 1 的默认设置状态,从中可以看到所有的串口相关的寄存 器全部在这上面表示出来了。我们接着单击一下 ,执行完串口初始化函数,得到了如图 4.2.2.6 (b)所示的串口信息。大家可以对比一下这两个图的区别,就知道在 uart_init(115200);这个函 数里面大概执行了哪些操作。 通过图 4.2.2.6(b),我们可以查看串口 1 的各个寄存器设置的状态,从而判断我们写的代 码是否有问题,只有这里的设置正确了之后,才有可能在硬件上正确的执行。同样这样的方法 也可以适用于很多其他外设,这个读者慢慢体会吧!这一方法不论是在排错还是在编写代码的 时候,都是非常有用的。 此时,我们先打开串口调试助手(XCOM V2.0,在光盘->6,软件资料->软件->串口调试助手) 设置好串口号和波特率,然后我们继续单击 按钮,一步步执行,此时在堆栈局部变量窗口可 以看到 t 的值变化,同时在串口调试助手中,也可以看到打印 t 的值,如图 3.2.2.7 和 3.2.2.8 所示:
图 3.2.2.7 堆栈局部变量窗口查看 t 的值
图 3.2.2.8 串口调试助手收到的数据
关于 STM32F4 的硬件调试,我们就介绍到这里,这仅仅是一个简单的 demo 演示,在实际 使用中硬件调试更是大有用处,所以大家一定要好好掌握。 3.5 MDK5 使用技巧 通过前面的学习,我们已经了解了如何在 MDK5 里面建立属于自己的工程。下面,我们将 向大家介绍 MDK5 软件的一些使用技巧,这些技巧在代码编辑和编写方面会非常有用,希望大 家好好掌握,最好实际操作一下,加深印象。 3.5.1 文本美化 文本美化,主要是设置一些关键字、注释、数字等的颜色和字体。MDK 提供了我们自定 义字体颜色的功能。我们可以在工具条上点击 (配置对话框)弹出如图 3.5.1.1 所示界面:
图 3.5.1.1 置对话框
在该对话框中,先设置 Encoding 为:Chinese GB2312(Simplified),然后设置 Tab size 为:4。 以更好的支持简体中文(否则,拷贝到其他地方的时候,中文可能是一堆的问号),同时 TAB 间隔设置为 4 个单位。然后,选择:Colors&Fonts 选项卡,在该选项卡内,我们就可以设置自 己的代码的子体和颜色了。由于我们使用的是 C 语言,故在 Window 下面选择:C/C++ Editor Files 在右边就可以看到相应的元素了。如图 3.5.1.2 示:
图 3.5.1.2 Colors&Fonts 选项卡
然后点击各个元素修改为你喜欢的颜色(注意双击,且有时候可能需要设置多次才生效,MDK 的 bug),当然也可以在 Font 栏设置你字体的类型,以及字体的大小等。设置成之后,点击 OK,就可以在主界面看到你所修改后的结果,例如我修改后的代码显示效果如图 3.5.1.3 示,代码中的数字全部修改为红色:
图 3.5.1.3 设置完后显示效果
这就比开始的效果好看一些了。字体大小,则可以直接按住:ctrl+鼠标滚轮,进行放大或者缩小,或者也可以在刚刚的配置界面设置字体大小。 细心的读者可能会发现,上面的代码里面有一个 u8,还是黑色的,这是一个用户自定义的关键字,为什么不显示蓝色(假定刚刚已经设置了用户自定义关键字颜色为蓝色)呢?这就又要回到我们刚刚的配置对话框了,单这次我们要选择 User Keywords 选项卡,同样选择:C/C++ Editor Files,在右边的 User Keywords 对话框下面输入你自己定义的关键字,如图 3.5.1.4 示:
图 3.5.1.4 用户自定义关键字
图 3.5.1.4 中我定义了 u8、u16、u32 等 3 个关键字,这样在以后的代码编辑里面只要出现这三个关键字,肯定就会变成蓝色。点击 OK,再回到主界面,可以看到 u8 变成了蓝色了,如图 3.5.1.5 示:
图 3.5.1.5 设置完后显示效果
其实这个编辑配置对话框里面,还可以对其他很多功能进行设置,比如动态语法检测等, 我们将 3.5.2 节介绍。 3.5.2 语法检测&代码提示 MDK4.70 以上的版本,新增了代码提示与动态语法检测功能,使得 MDK 的编辑器越来越好用了,这里我们简单说一下如何设置,同样,点击 ,打开配置对话框,选择 Text Completion 选项卡,如图 3.5.2.1 所示
图 3.5.2.1 Text Completion 选项卡设置
Strut/Class Members,用于开启结构体/类成员提示功能。 Function Parameters,用于开启函数参数提示功能。 Symbols after xx characters,用于开启代码提示功能,即在输入多少个字符以后,提示匹配 的内容(比如函数名字、结构体名字、变量名字等),这里默认设置 3 个字符以后,就开始提 示。如图 3.5.2.2 所示:
图 3.5.2.2 代码提示
Dynamic Syntax Checking,则用于开启动态语法检测,比如编写的代码存在语法错误的时 候,会在对应行前面出现 图标,如出现警告,则会出现 图标,将鼠标光标放图标上面,则 会提示产生的错误/警告的原因,如图 3.5.2.3 所示:
图 3.5.2.3 语法动态检测功能
这几个功能,对我们编写代码很有帮助,可以加快代码编写速度,并且及时发现各种问题。 不过这里要提醒大家,语法动态检测这个功能, 有的时候会误报(比如 sys.c 里面,就有很多 误报),大家可以不用理会,只要能编译通过(0 错误,0 警告),这样的语法误报,一般直 接忽略即可。 3.5.3 代码编辑技巧 这里给大家介绍几个我常用的技巧,这些小技巧能给我们的代码编辑带来很大的方便,相 信对你的代码编写一定会有所帮助。 1)TAB 键的妙用 首先要介绍的就是 TAB 键的使用,这个键在很多编译器里面都是用来空位的,每按一下移空几个位。如果你是经常编写程序的对这个键一定再熟悉不过了。但是 MDK 的 TAB 键和一般编译器的 TAB 键有不同的地方,和 C++的 TAB 键差不多。MDK 的 TAB 键支持块操作。也就是可以让一片代码整体右移固定的几个位,也可以通过 SHIFT+TAB 键整体左移固定的几个位。 假设我们前面的串口 1 中断响应函数如图 3. 5.3.1 所示:
图 3.5.3.1 头大的代码
图 3.5.3.1 中这样的代码大家肯定不会喜欢,这还只是短短的 30 来行代码,如果你的代码有几千行,全部是这个样子,不头大才怪。看到这样的代码我们就可以通过 TAB 键的妙用来快速修改为比较规范的代码格式。 选中一块然后按 TAB 键,你可以看到整块代码都跟着右移了一定距离,如图 3.5.3.2 所示:
图 3.5.3.2 代码整体偏移
接下来我们就是要多选几次,然后多按几次 TAB 键就可以达到迅速使代码规范化的目的,最终效果如图 3.5.3.3 所示
图 3.5.3.3 修改后的代码
图 3.5.3.3 中的代码相对于图 3. 5.3.1 中的要好看多了,经过这样的整理之后,整个代码一 下就变得有条理多了,看起来很舒服。 2) 快速定位函数/变量被定义的地方 上一节,我们介绍了 TAB 键的功能,接下来我们介绍一下如何快速查看一个函数或者变量所定义的地方。 大家在调试代码或编写代码的时候,一定有想看看某个函数是在那个地方定义的,具体里面的内容是怎么样的,也可能想看看某个变量或数组是在哪个地方定义的等。尤其在调试代码 或者看别人代码的时候,如果编译器没有快速定位的功能的时候,你只能慢慢的自己找,代码量比较少还好,如果代码量一大,那就郁闷了,有时候要花很久的时间来找这个函数到底在哪里。型号 MDK 提供了这样的快速定位的功能(顺便说一下 CVAVR 的 2.0 以后的版本也有这个 功能)。只要你把光标放到这个函数/变量(xxx)的上面(xxx 为你想要查看的函数或变量的名字),然后右键,弹出如图 3.5.3.4 所示的菜单栏 :
图 3.5.3.4 快速定位
在图 3.5.3.4 中,我们找到 Go to Definition Of‘delay_init’ 这个地方,然后单击左键就可以快速跳到 delay_init 函数的定义处(注意要先在 Options for Target 的 Output 选项卡里面勾选 Browse Information 选项,再编译,再定位,否则无法定位!)。如图 3.5.3.5 所示:
图 3.5.3.5 定位结果
对于变量,我们也可以按这样的操作快速来定位这个变量被定义的地方,大大缩短了你查 找代码的时间。细心的大家会发现上面还有一个类似的选项,就是 Go to Reference To ‘delay_init’,这个是快速跳到该函数被声明的地方,有时候也会用到,但不如前者使用得多。 很多时候,我们利用 Go to Definition/ Reference 看完函数/变量的定义/申明后,又想返回之前的代码继续看,此时我们可以通过 IDE 上的 按钮(Back to previous position)快速的返回 之前的位置,这个按钮非常好用! 3) 快速注释与快速消注释 接下来,我们介绍一下快速注释与快速消注释的方法。在调试代码的时候,你可能会想注 释某一片的代码,来看看执行的情况,MDK 提供了这样的快速注释/消注释块代码的功能。也 是通过右键实现的。这个操作比较简单,就是先选中你要注释的代码区,然后右键,选择 Advanced->Comment Selection 就可以了。 以 delay_init 函数为例,比如我要注释掉下图中所选中区域的代码,如图 3.5.3.6 所示:
图 3.5.3.6 选中要注释的区域
我们只要在选中了之后,选择右键,再选择 Advanced->Comment Selection 就可以把这段代码注释掉了。执行这个操作以后的结果如图 3.5.3.7 所示:
图 3.5.3.7 注释完毕
这样就快速的注释掉了一片代码,而在某些时候,我们又希望这段注释的代码能快速的取消注释,MDK 也提供了这个功能。与注释类似,先选中被注释掉的地方,然后通过右键 ->Advanced,不过这里选择的是 Uncomment Selection。 3.5.4 其他小技巧 除了前面介绍的几个比较常用的技巧,这里还介绍几个其他的小技巧,希望能让你的代码编写如虎添翼。 第一个是快速打开头文件。在将光标放到要打开的引用头文件上,然后右键选择 Open Document“XXX”,就可以快速打开这个文件了(XXX 是你要打开的头文件名字)。如图 3.5.4.1 所示
图 3.5.4.1 快速打开头文件
第二个小技巧是查找替换功能。这个和 WORD 等很多文档操作的替换功能是差不多的, 在 MDK 里面查找替换的快捷键是“CTRL+H”,只要你按下该按钮就会调出如图 3.5.4.2 所示界面
图 3.5.4.2 替换文本
这个替换的功能在有的时候是很有用的,它的用法与其他编辑工具或编译器的差不多,相信各位都不陌生了,这里就不在啰唆了。 第三个小技巧是跨文件查找功能,先双击你要找的函数/变量名(这里我们还是以系统时钟初始化函数:delay_init 为例),然后再点击 IDE 上面的,弹出如图 3.5.4.3 所示对话框:
图 3.5.4.3 跨文件查找
点击 Find All,MDK 就会帮你找出所有含有 delay_init 字段的文件并列出其所在位置,如图 3.5.4.4 所示:
图 3.5.4.4 查找结果
该方法可以很方便的查找各种函数/变量,而且可以限定搜索范围(比如只查找.c 文件和.h文件等),是非常实用的一个技巧。 |
|
相关推荐
|
|
使用stm32l451片子,对ad7606进行3通道100k采样值跳动问题?
1027 浏览1 评论
STM32进行DMA数据转运,为什么只有A组最后一位数据被转运到B组去?
1516 浏览2 评论
1828 浏览3 评论
1421 浏览0 评论
嵌入式开发 Win11安装ST-Link 提示 设备描述符请求失败 怎么处理?
1557 浏览0 评论
小黑屋|手机版|Archiver|德赢Vwin官网(湘ICP备2023018690号)
GMT+8, 2024-8-24 12:50, Processed in 0.377029 second(s), Total 35, Slave 28 queries .
Powered by德赢Vwin官网 网
© 2015bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号