当今的嵌入式体系开发领域中,高效的调试东西关于工程师来说至关重要。它们能够极大地减少开发周期中的过错追踪时刻,并加速产品的上市时刻。MDK作为业界领先的嵌入式开发东西之一,其内置的调试功用被广大开发者所赞誉。这些功用不只供给了对代码履行的深化洞悉,还允许开发者在实时环境中监控和修正体系行为。经过本文,咱们将一起探索 MDK 的调试功用怎么成为嵌入式开发者的得力助手,以及它怎么助力咱们构建愈加安稳、高效的嵌入式应用。
1. 源码下载及前置阅览
- STM32F103C8T6模板工程
链接:pan.baidu.com/s/1n7XHCaMY… 提取码:lw59
- MDK5安装包
链接:pan.baidu.com/s/1j7USS7-r… 提取码:5q3s
- 芯片固件包
链接:pan.baidu.com/s/1Td21MOEs… 提取码:86uh
假如你是个零根底的小白,连 STM32 都没见过,我也给你预备了一个保姆级教程,手把手教你搭建好 STM32 开发环境,并教你怎么下载程序,简直业界良心!
零根底快速上手STM32开发(手把手保姆级教程):www.lxlinux.net/e/stm32/stm…
假如你连代码都不知道怎么烧录到 STM32 的,能够参阅下文,供给了 5 种代码烧录方法:
STM32下载程序的五种方法:www.lxlinux.net/e/stm32/fiv…
新手小白假如连 MDK 的运用都不熟悉,那么能够经过下文先熟悉一下 MDK 的运用:
一文教你运用MDK开发东西:www.lxlinux.net/e/stm32/mdk…
2. MDK仿真调试装备
在 MDK 仿真前,咱们需求对其进行环境装备。
- 翻开 Keil5 软件,翻开或许新建一个工程。
- 点击 Options for Target,也就是咱们俗称的魔法棒。
- 挑选 C/C++ 选项卡,在进行仿真时,咱们需求将 MDK 的优化调成 Level 0 等级。
- 点击 Debug 选项卡,把「Load Application at Startup」和「Run to main」勾上,
Load Application at Startup 是在发动调试时是否加载应用程序,假如此选项去掉则不会主动将程序下载到单片机,直接调试。假如此选项打勾则每次进入调试前先下载应用程序,然后进入调试。
Run to main() 能够使程序履行到 main() 函数。进入调试形式后,程序主动运转到 main 函数处。
- 翻开 Settings ,能够看到关于仿真器的设置,能够在这儿装备仿真器。默许情况下,大部分都是主动装备好的,无需额外修正。
-
我这儿运用的是 ST-Link ,所以选的是 ST-Link 。假如你的 ST-Link 正常且插在电脑上了,右边 SW Device 会正常显现,表明仿真器与开发板衔接成功了。
Debug Adapter 是你下载器的类型,这儿要挑选你运用的下载器类型。
Serial 是指仿真器的序列号,当你挑选完仿真器之后,Serial 才会显现你下载器的序列号。
在下面的 Version:FW 是下载器的版本号,本文运用的下载器是 ST-Link V2 所以显现的 HW 是 V2 。
Port 是挑选仿真器的调试形式,ARM 芯片有两种调试形式,分别是 SW 和 JTAG 。
相关于 JTAG 形式,SW 占用更少的信号线,而且功用相同支持代码下载与调试,所以强烈推荐运用 SW 调试形式。
假如 ST-Link 没有插上或设备异常,则会提示 No ST-Link detected。
- 最终翻开 Utilities 选项卡将 Use Debug Driver 打勾,再点击 OK 确认一下,MDK 仿真的调试装备就完成了。
3. 各个调试按钮的效果
接着咱们编译一下代码。再点击这个像放大镜相同的按钮就能够开端仿真了(这个按钮一起也能够退出仿真)。
进入仿真之后的界面如下图示。
界面左面显现寄存器的地址和程序运转时刻,上方是汇编语言窗口,需求必定的汇编根底才干看得懂。界面左下方是指令窗口,这个窗口会显现一些打印信息,也能够在这个窗口输入一些指令。右下角的窗口是关于函数及变量在内存中的地址信息。
在左上方有一排关于调试的小按钮:
它们的功用从左到右分别是:复位、全速运转、中止、进入函数、履行过此函数、跳出函数、履行到光标处、显现下一个将运转的代码
- 复位:从头履行程序;
- 全速运转:开端履行程序;(快捷键为 F5 )
- 中止:中止履行程序;
- 进入函数:进入当时行代码中;(快捷键为 F11 )
- 履行过此函数:履行当行代码;(快捷键为 F10 )
- 跳出函数:跳出当时程序代码;(快捷键为 Ctrl+F11 )
- 履行到光标处:主动履行代码至蓝色光标处;(快捷键为 Ctrl+F10 )
- Show Next Statement:显现下一行即行将履行的程序。
这儿我以流水灯作为案例来具体的阐明一下各个按钮的运用方法,运用的单片机类型为 STM32F103C8T6 最小体系板。衔接 ST-Link 上电,接线图如下:
ST-Link V2 | STM32 |
---|---|
SWCLK | SWCLK |
SWDIO | SWDIO |
GND | GND |
3.3V | 3V3 |
在 STM32F103C8T6 最小体系板上有个自带的小灯,这颗 LED 灯衔接在 PC13 管脚上。
首要咱们需求写一个小灯的初始化程序,这儿能够不用封装,直接写在 main.c 里边。
#define LED_CLK() __HAL_RCC_GPIOC_CLK_ENABLE()
#define LED_GPIO GPIOC
#define LED_PIN GPIO_PIN_13
void led_init(void)
{
GPIO_InitTypeDef gpio_initstruct;
LED_CLK(); /* IO口时钟使能 */
gpio_initstruct.Pin = LED_PIN; /* LED0引脚 */
gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
gpio_initstruct.Pull = GPIO_PULLUP; /* 上拉 */
gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
HAL_GPIO_Init(LED_GPIO, &gpio_initstruct); /* 初始化LED0引脚 */
}
主函数代码如下:
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
led_init(); /* LED初始化 */
while(1)
{
HAL_GPIO_WritePin(LED_GPIO,LED_PIN,GPIO_PIN_SET); /*使LED灭掉*/
delay_ms(500);
HAL_GPIO_WritePin(LED_GPIO,LED_PIN,GPIO_PIN_RESET);/*使LED亮起*/
delay_ms(500);
}
}
点击放大镜进入仿真界面,然后再点击左上角的开端按钮(或许运用快捷键 F5 )开端履行代码。
能够看到 STM32F103C8T6 最小体系板上的 PC13 小灯在不断闪烁。这时分咱们在 19 行打上一个断点,再点击全速运转按钮:
能够看到当时程序运转到了第 19 行然后暂停了,STM32F103C8T6 最小体系板上的 PC13 小灯则会保持长亮。
(需求留意的是,调试停在中断处的时分,内核会中止,但是外设将会持续运转)
接着咱们在 21 行再打上一个断点,然后再点击全速运转按钮。
会发现代码履行到了 21 行就停下了,这时 STM32F103C8T6 最小体系板上的 PC13 小灯展灭掉。
咱们点击右上角复位的按钮,然后选中 led_init(); 这行代码,点击履行到光标处按钮(或许快捷键 Ctrl+F10 ),将代码履行至这一行。
(需求留意必需求退出调试形式再从头进入调试形式,否则代码会一直在死循环傍边履行,导致代码无法履行到你想要履行的那行)
这时分咱们点击进入函数按钮(或许快捷键 F11 ),则进入到 LED 的初始化函数傍边。
咱们能够看到当时程序履行到了 LED 的初始化函数中。这时,点击「履行过此函数按钮」(或许快捷键 F10 ),如下图示。
点击一下上图按钮,程序将履行一行代码。而且,假如当时行是函数,将不进入此函数内部代码,直接履行完函数代码并进入到下一行。
假如你不想检查 led_init() 函数里的代码了,你能够点击「跳出函数按钮」(或许快捷键 Ctrl+F11 ),能够按钮能够直接跳出当时代码程序,预备履行下一行。
(跳出函数的话会默许履行完当时程序代码,然后跳到下一行)
4. 检查程序段/函数履行的时刻
在代码中,咱们常常会运用延时函数。那么,咱们怎么确认延时函数真的延时了咱们所设置的时刻呢(比如 500ms)?
咱们能够经过代码调试功用来确认延时时刻的精确性。
首要翻开魔法棒,在 Debug 中翻开 Settings 选项。
再点击 Trace 选项卡,能够找到时钟频率。
默许情况下的时钟频率是 8MHz ,这儿咱们改成 72MHz 。
咱们选中 20 行,然后运用「履行到光标处按钮」(快捷键为 Ctrl+F10 )运转至 20 行。如下:
在左下方的 Sec 表明程序运转了多久,单位是秒( s ),咱们运用「履行过此函数」(快捷键为 F10 )履行一下延时函数,看看延时函数是否精确。结果如下:
运用此结果减去初始的时刻,能够看到大约延时了 0.5s 左右,也就是 500ms ,能够以为延时函数的时刻是十分精确的。
5. 东西栏常用窗口按钮介绍
在调试按钮的左面有一排窗口按钮,用于翻开各种调试窗口(也能够经过菜单栏的 View 翻开)。
- 第一个 Command Window 按钮,能够翻开 Command 窗口,这个窗口能够显现一些打印的信息,还能输入指令。
- 第二个按钮是 Disassembly Window ,这个窗口显现了汇编语言。你或许需求一些汇编语言的根底才干看得懂,这个窗口显现的光标表明下一条行将运转的汇编语言是什么。
- 第三个按钮是 Symbols Window ,这是符号窗口,用于检查一些符号类型。本文暂时不对这个窗口进行深化学习。
- 第四个按钮是 Registers Window ,这是一个寄存器窗口。这个窗口能够直观的检查一些内核的寄存器,还有程序运转时刻等等。
- 第五个按钮是 Call Stack Window ,它是用于检查函数调用联系 & 局部变量。本文学习的是仿真东西一些根底的运用,所以不对这个窗口进行深化学习。
- 第六个按钮是 Watch Windows ,用于检查函数首地址以及变量的值。
Watch 窗口还能够设置变量在被读或写后主动中止运转,关于代码调试十分有帮助。能够界说一个函数,将该函数的称号输入到窗口中,然后向函数传入一个数,在这个窗口你能够看到该函数的寄存器首地址,传完数之后你能够看到该数的类型是什么。
点击该按钮,弹出的界面如下:
举个栗子来演示一下这个过程。例如,在程序中界说一个全局变量 int temp;
,在 while 循环中履行 temp++ 。右击 temp ,挑选 Add “temp” to… 添加到 Wacth 1 。
在左下方的 Watch 1 窗口就能够看到 temp 的首地址和界说类型了。如下图:
这儿咱们运用「履行过此函数按钮」(快捷键为 F10 ),履行一遍程序,会发现 temp 的值发生了改动,履行了一次 temp++ 。如下图:
Wacth 窗口不止这些功用,Wacth 窗口还能够设置变量在被读或写后会主动中止运转。这个功用在调试行数比较多的项目十分有用,因为在许多场景下,有个变量有或许在几十上百处被修正,假如没有这个功用,排查变量被修正将变得十分困难。
那么怎么设置这个功用呢?
首要右击 temp ,会出现一个列表,点击 Set Access Breakpoint at “temp” 。如下图:
这时分会弹出一个窗口,在这个窗口你能够设置函数是否要在被读或许被写的主动中止运转。设置完之后点击 Define 就行了。
Wacth 窗口关于咱们代码调试还是有十分大的效果,咱们能够好好掌握。
- 第七个按钮是 Memory Windows ,可用于检查内存的地址与值。界面如下图示:
同样的,咱们举一个比如。
首要咱们在程序中界说一个 uint8_t 类型的数值 temp[10] ,然后给数组的前五个数赋值 {1,2,3,4,15} ,其他元素默许值为 0 。在循环中咱们进行 temp[0]++ ,只对第一个元素自增。
编译一下,翻开仿真东西,再翻开Memory 窗口,在窗口中输入 temp ,这样咱们就能够看到 temp 数组在内存中的地址与值。前面咱们给数组赋值 {1,2,3,4,15} ,在 Memory 窗口能够看到 temp 数组被十六进制表明出来 “01 02 03 04 0F” 。如下图:
(留意,M3/M4/M7内核是小端形式,内存的值要倒着读)
Memory 窗口能够帮助咱们快速的检查变量在内存中的地址和值,便于咱们调试程序。
- 第八个按钮是 Serial Windows ,这是用于检查串口的窗口。
-
下面这个按钮是 Peripheral 窗口,于检查寄存器的值。Core Peripherals 是内核寄存器,其他的都是外设寄存器。如下图:
翻开之后是这个姿态的(我这儿翻开的是 GPIOC )。如下图:
在这儿你能够看到一些寄存器的值,假如你想看某个值,你能够点击左面的 + 号,在 + 号中有更具体的信息。
经过这个窗口,能够检查到自己装备寄存器是否正确,确保外设能依照你的预期运转。
6. 小结
总的来说,想要将单片机学的更好,MDK 仿真东西就必不可少。MDK 仿真东西不只功用强大,而且操作起来的难度也不高,对新手也十分的友好,最重要的是它能够帮助咱们更好地理解和调试程序代码,学好运用 MDK 仿真东西,能够让你的技术更上一层楼。
别的,想进大厂的同学,必定要好好学算法,这是面试必备的。这儿预备了一份 BAT 大佬总结的 LeetCode 刷题宝典,许多人靠它们进了大厂。
刷题 | LeetCode算法刷题神器,看完 BAT 随你挑!
有收成?期望老铁们来个三连击,给更多的人看到这篇文章
推荐阅览:
欢迎关注我的博客:良许嵌入式教程网,满满都是干货!