当前位置: 首页 > web >正文

STM32F1软件调试详解

通过本章的学习,你将了解到:

  1. STM32F1 软件仿真;
  2. STM32F1 程序下载;
  3. STM32F1 硬件调试;

本章将分为如下 3 个小节:4.1STM32F1 软件仿真;4.2STM32F1 程序下载;4.3STM32F1 硬件调试

4.1 STM32F1 软件仿真

MDK 的一个强大的功能就是提供软件仿真(注意:STM32F4 不支持软件仿真),通过软件仿真,我们可以发现很多将要出现的问题,避免了下载到 STM32 里面来查这些错误,这样最大的好处是能很方便的检查程序存在的问题,因为在 MDK 的仿真下面, 你可以查看很多硬件相关的寄存器,通过观察这些寄存器, 你可以知道代码是不是真正有效。另外一个优点是不必频繁的刷机,从而延长了 STM32 FLASH 寿命(STM32 FLASH 寿命≥1W 次)。当然,软件仿真不是万能的,很多问题还是要到在线调试才能发现。上一章,我们创立了一个测试 STM32 串口 1 的工程,本节我们将教大家如何在 MDK5.14的软件环境下仿真这个工程,以验证我们代码的正确性。在开始软件仿真之前,先检查一下配置是不是正确, 在 IDE 里面点击 ,确定 Target 选项卡内容如图 4.1.1 所示(主要检查芯片型号和晶振频率,其他的一般默认就可以)

确认了芯片以及外部晶振频率(8.0Mhz) 之后,基本上就确定了 MDK5.14 软件仿真的硬件环境了,接下来,我们再点击 Debug 选项卡,设置为如图 4.1.2 所示:

在图 4.1.2 中,选择: Use Simulator,即使用软件仿真。选择: Run to main(),即跳过汇编代码,直接跳转到 main 函数开始仿真。设置下方的: Dialog DLL 分别为: DARMSTM.DLL TARMSTM.DLLParameter 均为: -pSTM32F103ZE,用于设置支持 STM32F103ZE 的软硬件仿真(即可以通过 Peripherals 选择对应外设的对话框观察仿真结果)。最后点击 OK,完成设置。接下来,我们点击 (开始/停止仿真按钮),开始仿真,出现如图 4.1.3 所示界面:

可以发现,多出了一个工具条, 这就是 Debug 工具条,这个工具条在我们仿真的时候是非常有用的,下面简单介绍一下 Debug 工具条相关按钮的功能。 Debug 工具条部分按钮的功能如图 4.1.4 所示:

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

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

停止运行:此按钮在程序一直执行的时候会变为有效,通过按该按钮,就可以使程序停止下来,进入到单步调试状态。执行进去:该按钮用来实现执行到某个函数里面去的功能,在没有函数的情况下,是等同于执行过去按钮的。

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

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

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

汇编窗口:通过该按钮,就可以查看汇编代码,这对分析程序很有用。堆栈局部变量窗口:通过该按钮, 显示 Call Stack+Locals 窗口,显示当前函数的局部变量及其值,方便查看。

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

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

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

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

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

Debug 工具条上的其他几个按钮用的比较少, 我们这里就不介绍了。 以上介绍的是比较常用的,当然也不是每次都用得着这么多,具体看你程序调试的时候有没有必要观看这些东西,来决定要不要看。这样,我们在上面的仿真界面里面选择: 观察窗口 1Watch1)、串口打印窗口(UART#1)。然后调节一下这两个窗口的位置, 然后将变量 t 加入 Watch1 窗口(方法:双击 Enter expression添加/直接拖动变量 t Watch1 窗口即可), 如图 4.1.5 所示:

我们把光标放到 test.c 的第 9 行左侧的灰色区域,然后按下鼠标左键, 即可放置一个断点(红色的实心点, 也可以通过鼠标右键弹出菜单来加入),再次单击则取消。 然后点击 ,执行到该断点处,如图 4.1.6 所示:

我们现在先不忙着往下执行, 点击菜单栏的 PeripheralsàUSARTsàUSART 1。可以看到,有很多外设可以查看,这里我们查看的是串口 1 的情况。如图 4.1.7 所示:

单击 USART1 后会在 IDE 之外出现一个如图 4.1.8a)所示的界面:

4.1.8a) 是 STM32 的串口 1 的默认设置状态, 从中可以看到所有与串口相关的寄存器全部在这上面表示出来了,而且有当前串口的波特率等信息的显示。我们接着单击一下 ,执行完串口初始化函数,得到了如图 4.1.8b)所示的串口信息。大家可以对比一下这两个图的区别,就知道在 uart_init(72,115200);这个函数里面大概执行了哪些操作。通过图 4.1.8b),我们可以查看串口 1 的各个寄存器设置状态,从而判断我们写的代码是否有问题,只有这里的设置正确了之后,才有可能在硬件上正确的执行。 同样这样的方法也可以适用于很多其他外设,这个读者慢慢体会吧!这一方法不论是在排错还是在编写代码的时候,都是非常有用的。然后我们继续单击 按钮,一步步执行,最后就会看到在 USART #1中打印出相关的信息,如图 4.1.9 所示:

图中黑色方框内的数据是串口 1 打印出来的, 证明我们的仿真是通过的,代码运行时会在串口 1 不停的输出 t 的值,每 0.5s 执行一次。软件仿真的时间可以在 IDE 的最下面(窗口最大化后, 右下角)观看到,如图 4.1.10 所示。 并且 t 自增, 与我们预期的一致。再次按下 结束仿真

至此,我们软件仿真就结束了, 通过软件仿真,我们在 MDK5.14 中验证了代码的正确性,接下来我们下载代码到硬件上来真正验证一下我们的代码是否在硬件上也是可行的。

4.2 STM32F1 程序下载

STM32F103 的程序下载有多种方法: USB、串口、 JTAGSWD 等,这几种方式,都可以用来给 STM32F103 下载代码。不过,最简单也是最经济的,就是通过串口给 STM32F103 下载代码。本节,我们将向大家介绍,如何利用串口给 STM32F103(以下简称 STM32) 下载代码。STM32 的串口下载一般是通过串口 1 下载的, 本手册的实验平台 ALIENTEK 精英STM32F103,不是通过 RS232 串口下载的,而是通过自带的 USB 串口来下载。看起来像是 USB下载(只需一根 USB 线,并不需要串口线)的,实际上,是通过 USB 转成串口,然后再下载的。下面,我们就一步步教大家如何在实验平台上利用 USB 串口来下载代码。首先要在板子上设置一下,在板子上把 P3 端子的 RXD PA9STM32 TXD), TXDPA10(STM32 RXD)通过跳线帽连接起来,这样我们就把 CH340G MCU 的串口 1 连接上了。这里由于 ALIENTEK 这款开发板自带了一键下载电路,所以我们并不需要去关心 BOOT0BOOT1 的状态,但是为了让下下载完后可以按复位执行程序,我们建议大家把 BOOT1 BOOT0 都设置为 0。设置完成如图 4.2.1 所示:

这里简单说明一下一键下载电路的原理,我们知道, STM32 串口下载的标准方法是两个步骤:1, 把 B0 V3.3(保持 B1 GND)。

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

接着我们在 USB_232 处插入 USB 线, 并接上电脑, 如果之前没有安装 CH340G 的驱动(如果已经安装过了驱动,则应该能在设备管理器里面看到 USB 串口,如果不能则要先卸载之前的驱动,卸载完后重启电脑,再重新安装我们提供的驱动) ,则需要先安装 CH340G 的驱动, 找到光盘à软件资料à软件 文件夹下的 CH340 驱动,安装该驱动,如图 4.2.2 所示:

在驱动安装成功之后,拔掉 USB 线,然后重新插入电脑,此时电脑就会自动给其安装驱动了。在安装完成之后,可以在电脑的设备管理器里面找到 USB 串口(如果找不到,则重启下电脑), 如图 4.2.3 所示:

在图 4.2.3 中可以看到,我们的 USB 串口被识别为 COM3, 这里需要注意的是: 不同电脑可能不一样, 你的可能是 COM4COM5 等,但是 USB-SERIAL CH340,这个一定是一样的。如果没找到 USB 串口,则有可能是你安装有误,或者系统不兼容。在安装了 USB 串口驱动之后,我们就可以开始串口下载代码了,这里我们的串口下载软件选择的是 flymcu,该软件是 mcuisp 的升级版本(flymcu 新增对 STM32F4 的支持),由 ALIENTEK提供部分赞助, mcuisp 作者开发,该软件可以在 www.mcuisp.com 免费下载, 本手册的光盘也附带了这个软件, 版本为 V0.188。该软件启动界面如图 4.2.4 所示:

然后我们选择要下载的 Hex 文件,以前面我们新建的工程为例,因为我们前面在工程建立的时候,就已经设置了生成 Hex 文件,所以编译的时候已经生成了 Hex 文件,我们只需要找到这个 Hex 文件下载即可。用 flymcu 软件打开 OBJ 文件夹,找到 test.hex,打开并进行相应设置后,如图 4.2.5 所示:

4.2.5 中圈中的设置,是我们建议的设置。编程后执行, 这个选项在无一键下载功能的条件下是很有用的, 当选中该选项之后,可以在下载完程序之后自动运行代码。 否则,还需要按复位键,才能开始运行刚刚下载的代码。

编程前重装文件,该选项也比较有用, 当选中该选项之后, flymcu 会在每次编程之前,将hex 文件重新装载一遍,这对于代码调试的时候是比较有用的。特别提醒:不要选择使用 RamIsp,否则,可能没法正常下载。

最后,我们选择的 DTR 的低电平复位,RTS 高电平进 BootLoader,这个选择项选中,flymcu就会通过 DTR RTS 信号来控制板载的一键下载功能电路,以实现一键下载功能。如果不选择,则无法实现一键下载功能。 这个是必要的选项(在 BOOT0 GND 的条件下)。

在装载了 hex 文件之后,我们要下载代码还需要选择串口,这里 flymcu 有智能串口搜索功能。每次打开 flymcu 软件,软件会自动去搜索当前电脑上可用的串口,然后选中一个作为默认的串口(一般是你最后一次关闭时所选择的串口)。也可以通过点击菜单栏的搜索串口, 来实现自动搜索当前可用串口。串口波特率则可以通过 bps 那里设置,对于 STM32F103, 可以设置为最高: 460800,而如果是 F4,则建议最高设置为: 76800 即可。 然后, 找到 CH340 虚拟的串口, 如图 4.2.6 所示:

从之前 USB 串口的安装可知,开发板的 USB 串口被识别为 COM3 了(如果你的电脑是被识别为其他的串口,则选择相应的串口即可) , 所以我们选择 COM3,波特率设置为 460800。设置好之后,我们就可以通过按开始编程(P) 这个按钮, 一键下载代码到 STM32 上,下载成功后如图 4.2.7 所示:

4.2.7 中,我们圈出了 flymcu 对一键下载电路的控制过程,其实就是控制 DTR RTS电平的变化,控制 BOOT0 RESET,从而实现自动下载。另外, 下载成功后,会有“共写入 xxxxKB,耗时 xxxx 毫秒” 的提示,并且从 0X80000000处开始运行了,我们打开串口调试助手(XCOM V2.0,在光盘à6,软件资料à软件à串口调试助手里面) 选择 COM3(得根据你的实际情况选择),设置波特率为: 115200,会发现从ALIENTEK 精英 STM32F103 发回来的信息,如图 4.2.8 所示:

接收到的数据和我们期望的是一样的,证明程序没有问题。至此, 说明我们下载代码成功了,并且从硬件上验证了我们代码的正确性。

4.3 STM32F1 在线调试

上一节,我们介绍了如何通过利用串口给 STM32 下载代码,并在 ALIENTEK 精英STM32F103 上验证了我们程序的正确性。这个代码比较简单,所以不需要硬件调试,我们直接就一次成功了。可是,如果你的代码工程比较大,难免存在一些 bug,这时,就有必要通过在线调试来解决问题了。串口只能下载代码,并不能实时跟踪调试,而利用调试工具,比如 JLINKULINKSTLINK等就可以实时跟踪程序, 从而找到你程序中的 bug, 使你的开发事半功倍。这里我们以 JLINKV8 为例,说说如何在线调试 STM32F1JLINK V8 支持 JTAG SWD, 同时 STM32F1 也支持 JTAG SWD。所以,我们有 2 种方式可以用来调试, JTAG 调试的时候,占用的 IO 线比较多,而 SWD 调试的时候占用的 IO 线很少,只需要两根即可。JLINK V8 的驱动安装比较简单, 我们在这里就不说了。在安装了 JLINK V8 的驱动之后,我们接上 JLINK V8,并把 JTAG 口插到 ALIENTEK 精英 STM32F103 上,打开之前 3.2 节新建的工程, 点击 ,打开 Options for Target 选项卡,在 Debug 栏选择仿真工具为 useJ-LINK/J-TRACE Cortex,如图 4.3.1 所示:

上图中我们还勾选了 Run to main(),该选项选中后, 只要点击仿真就会直接运行到 main 函数, 如果没选择这个选项,则会先执行 startup_stm32f10x_hd.s 文件的 Reset_Handler,再跳到main 函数。

然后我们点击 Settings(注意,如果你的 JLINK 固件比较老,此时可能会提示升级固件,点击确认升级即可),设置 J-LINK 的一些参数,如图 4.3.2 所示:

4.3.2 中,我们使用 J-LINK V8 SW 模式调试,因为我们 JTAG 需要占用比 SW 模式多很多的 IO 口,而在 ALIENTEK 精英 STM32F103 上这些 IO 口可能被其他外设用到,可能造成部分外设无法使用。所以,我们建议大家在调试的时候,一定要选择 SW 模式Max Clock,可以点击 Auto Clk 来自动设置(最大可达 50Mhz), 图 4.3.2 中我们设置 SWD 的调试速度为10MhzJLINK V8 的话,最大时钟频率, 推荐大家设置为 10Mhz),这里,如果你的 USB 数据线比较差,那么可能会出问题,此时, 你可以通过降低这里的速率来试试。单击 OK,完成此部分设置,接下来我们还需要在 Utilities 选项卡里面设置下载时的目标编程器,如图 4.3.3 所示:

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

这里 MDK5 会根据我们新建工程时选择的目标器件,自动设置 flash 算法。我们使用的是STM32F103ZET6FLASH 容量为 512K 字节, 所以 Programming Algorithm 里面默认会有 512K型号的 STM32F10x High-density Flash 算法。另外,如果这里没有 flash 算法,大家可以点击 Add按钮,自行添加即可。 最后, 选中 Reset and Run 选项,以实现在编程后自动运行, 其他默认设置即可。设置完成之后,如图 4.3.4 所示。在设置完之后,点击 OK,然后再点击 OK,回到 IDE 界面,编译一下工程。 然后点击:(开始/停止仿真按钮),开始仿真(如果开发板的代码没被更新过,则会先更新代码(即下载代码),再仿真, 你也可以通过按 ,只下载代码,而不进入仿真。 特别注意:开发板上的 B0B1 都要设置到 GND,否则代码下载后不会自动运行的!), 如图 4.3.5 所示:

因为我们之前勾选了 Run to main()选项,所以,程序直接就运行到了 main 函数的入口处。我们在 uart_init 处设置一个断点,点击 ,程序将会快速执行到该处。如图 4.3.6 所示:

接下来,我们就可以和软件仿真一样的开始操作了,不过这是真正的在硬件上的运行,而不是软件仿真!其结果更可信。硬件调试就给大家介绍到这里,硬件仿真更详细的介绍,请看光盘视频:光盘\2ALIENTEK 精英 STM32F103 V1 开发板视频教程\1,基础视频教程\ 3JLINK下载调试代码方法.rmvb

http://www.xdnf.cn/news/7259.html

相关文章:

  • vLLM - LLM 类初始化参数
  • Addressable-加载指定资源
  • QT6 源(108)篇二:阅读与注释菜单栏里的菜单对象 QMenu,先是成员函数,后是信号函数的测试
  • Python 位运算:深入理解与实践应用
  • Linux开放访问端口
  • boost之signal2
  • 【ROS2】虚拟机使用fishros脚本一键安装humble
  • 我的创作纪念日——512天
  • 学习笔记:hspice仿真Verilog-a
  • ReentrantLock、ReentrantReadWriteLock、StampedLock讲解
  • ET Attribute
  • 【Python 算法零基础 4.排序 ① 选择排序】
  • 深度剖析:YOLOv8融入UNetv2 SDI模块的性能提升之旅
  • 游戏服务器之聊天频道设计
  • 双紫擒龙紫紫红指标源码学习,2025升级版紫紫红指标公式-重点技术
  • transformer project tutorial
  • volatile
  • Python实例题:Flask开发轻博客
  • mybatis中的resultMap的association及collectio的使用
  • 【动态规划】状压dp
  • Mlp-Mixer-BiGRU故障诊断的python代码合集
  • LLMs:《POE报告:2025年春季人工智能模型使用趋势》解读
  • 实习记录小程序|基于SSM+Vue的实习记录小程序设计与实现(源码+数据库+文档)
  • 涉密载体管控系统|DW-S402系统组成
  • 【LLM MoE】论文分享No.11:DeepSeekMoE
  • 前缀和——中心数组下标
  • Leetcode 3552. Grid Teleportation Traversal
  • 【开源分享】健康饮食管理系统(双端+论文)
  • 2- PyTorch
  • 如何使用 Apple 提供的 benchmark 工具