STM软件仿真
MDK的一个强大的功能就是提供软件仿真,通过仿真软件,我们可以发现很多将要出现的问题,避免下载到 STM32 里面来检查这些错误。
这样最大的好处就是能方便的检查程序存在的问题,因为在 MDK 的仿真下面,你可以查看很多硬件相关的寄存器,通过观察这些寄存器,你可以知道代码是不是真正有效。
另外一个优点是不必频繁的刷机,从而延长了 STM32的 FLASH 寿命(STM32 的 FLASH 寿命≥1W 次)。当然,软件仿真不是万能的,很多问题还是要到在线调试才能发现,接下来我们开始进行软件仿真。
1.上一篇MDK软件入门中,我们创立了一个工程模板,下边将学习如何在 MDK5 的软件环境下仿真这个工程,以验证我们代码的正确性。首先工程模板中 main.c 中代码修如下:
#include "delay.h"
#include "usart.h"
int main(void)
{
u8 t=0;
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init(115200);
while(1)
{
printf("t:%d\n",t);
delay_ms(500);
t++;
}
}
2.在开始仿真之前,先检查配置是不是正确,点击魔法棒,如下图进行操作:
确定了芯片以及外部晶振频率(8.0MHz)之后,基本上就确定了 MDK5.14 软件仿真的硬件环境了。
3.接下来,我们再点击 Debug 选项卡,设置如下:
选择:Use Simulator,即使用软件仿真。选择:Run to main(),即跳过汇编代码,直接跳转到 main 函数开始仿真。设置下方的:Dialog DLL 分别为:DARMSTM.DLL和TARMSTM.DLL,Parameter 均为:-pSTM32F103ZE,用于设置支持 STM32F103ZE 的软硬件仿真(即可以通过 Peripherals 选择对应外设的对话框观察仿真结果)。最后点击 OK,完成设置。
4.接下来,我们点击下图图标(开始/停止仿真按钮),开始仿真。
可以发现多出来一个工具条,这就是 Debug 工具条,这个工具条在我们仿真时是非常有用的,下边是 Debug 工具相关按钮的功能:
复位:其功能等同于硬件上按复位按钮。相当于实现了一次硬复位。按下该按钮之后,代码会重新从头开始执行。
执行到断点处:该按钮用来快速执行到断点处,有时候你并不需要观看每步是怎么执行的,而是想快速的执行到程序的某个地方看结果,这个按钮就可以实现这样的功能,前提是你在查看的地方设置了断点。
挂起:此按钮在程序一直执行的时候会变为有效,通过按该按钮,就可以使程序停止下来,进入到单步调试状态。
执行进去:该按钮用来实现执行到某个函数里面去的功能,在没有函数的情况下,是等同于执行过去按钮的。
执行过去:在碰到有函数的地方,通过该按钮就可以单步执行过这个函数,而不进入这个函数单步执行。
执行出去:该按钮是在进入了函数单步调试的时候,有时候你可能不必再执行该函数的剩余部分了,通过该按钮就直接一步执行完函数余下的部分,并跳出函数,回到函数被调用的位置。
执行到光标处:该按钮可以迅速的使程序运行到光标处,其实是挺像执行到断点处按钮功能,但是两者是有区别的,断点可以有多个,但是光标所在处只有一个。
汇编窗口:通过该按钮,就可以查看汇编代码,这对分析程序很有用。
观看变量/堆栈窗口:该按钮按下,会弹出一个显示变量的窗口,在里面可以查看各种你想要看的变量值,也是很常用的一个调试窗口。
串口打印窗口:该按钮按下,会弹出一个类似串口调试助手界面的窗口,用来显示从串口打印出来的内容。
内存查看窗口:该按钮按下,会弹出一个内存查看窗口,可以在里面输入你要查看的内存地址,然后观察这一片内存的变化情况。是很常用的一个调试窗口性能分析窗口:按下该按钮,会弹出一个观看各个函数执行时间和所占百分比的窗口,用来分析函数的性能是比较有用的。
逻辑分析窗口:按下该按钮会弹出一个逻辑分析窗口,通过 SETUP 按钮新建一些 IO 口,就可以观察这些 IO 口的电平变化情况,以多种形式显示出来,比较直观。
5.接着我们在上面的仿真界面里面选内存查看窗口、串口打印窗口。然后调节一下这两个窗口的位置:
6.我们把光标放到 main.c 的 12 行的空白处,然后鼠标单击灰色区域,可以看到在 12 行的左边出现了一个红点,即表示设置了一个断点(也可以通过鼠标右键弹出菜单来加入),再次点击则取消。 然后我们点击“执行断点到此处” ,执行到该断点处。
7.我们现在先不忙着往下执行,点击菜单栏的 Peripherals->USARTs->USART 1。可以看到,有很多外设可以查看,这里我们查看的是串口 1 的情况。
点击 USART1 后会在 IDE 之外出现一个界面:
这是 STM32 的串口 1 的默认设置状态,从中可以看到所有与串口相关的寄存器全部在这上面表示出来了,而且有当前串口的波特率等信息的显示。接着单击“执行出去”:
与上图对比,就知道在 uart_init(115200)这个函数里面大概执行了哪些操作。
8.然后我们继续单击“执行出去”按钮,一步步执行,最后就会看到在 USART #1 中打印出相关的信息:
图中红色方框内的数据是串口 1 打印出来的,证明我们的仿真是通过的,代码运行时会在串口 1 不停的输出 t 的值,每 0.5s 执行一次。软件仿真的时间可以在 IDE 的最下面(右下角)观看到:
并且t自增,与我们预期的一致,再次去按下仿真按钮,结束仿真。