注:本文为 "Keil 软硬件仿真" 相关合辑。
图片清晰度受引文原图所限。
略作重排,未整理去重。
如有内容异常,请看原文。
Keil 软件仿真
MC_J 于 2019-05-10 14:06:28 发布
本文详细阐述嵌入式系统开发过程中的程序调试方法,包括断点设置、函数内部执行、代码逐行运行、函数跳出操作、变量状态观测、内存地址数据查看等内容,同时介绍通过串口查看窗口监测串口通信状态的方法。

首先需对上图所示的 Debug 选项进行配置,选定软件仿真模式,再根据目标硬件的芯片型号选择对应的器件型号。

标注 8 对应的功能为进入上图所示的 Debug 调试模式。
标注 1 对应的功能为复位,与硬件复位按钮功能一致。
标注 2 对应的功能为运行至断点,在标注 3 对应的行号区域双击鼠标左键,即可生成红色断点标记。
标注 4 对应的功能为执行进入函数内部。
标注 5 对应的功能为代码逐行执行。
标注 6 对应的功能为跳出当前函数内部。
标注 7 对应的功能为运行至光标处,标注 4、5、6、7 对应的功能,可在代码调试实践过程中逐步理解。
标注 9 对应的功能为汇编窗口的开启与关闭。

选中 num 变量并单击鼠标右键,选择"添加到 watch1"选项,在标注 10 对应的区域选择 watch1 窗口,即可查看 num 变量的实时数值变化情况。
标注 11 对应的功能为内存数据查看,点击该按钮后,在界面右下角的内存窗口中输入目标内存地址,即可查看对应内存区域的数据内容。
标注 12 对应的功能为串口查看窗口,可用于监测程序运行过程中的串口通信状态。
keil 软件调试(Debug)仿真教程(软件调试和硬件调试的区别)及常用调试按键详解
豫见嵌入式 原创已于 2023-01-09 16:01:33 修改
本文阐述单片机程序调试的两种主要方式------软件模拟调试与硬件调试,强调仿真器在硬件调试过程中的作用。在 Keil Debug 调试部分,详细列举常用功能按钮的功能定义,例如 RST 复位、全速运行、单步执行等,同时介绍变量观测与汇编代码查看的方法。
前言
单片机的程序调试方式分为两种,一种是软件模拟调试,第二种是硬件调试,两种调试方式存在明显差异:软件模拟调试存在一定的误差,硬件调试需借助仿真器实现,是嵌入式开发领域的常用调试方法。

一、软件调试(Debug)
单片机的程序调试方式分为两种,一种是软件模拟调试 ,即通过单片机程序开发工具(IDE)模拟单片机的指令执行过程,并仿真单片机片内资源的运行状态。
为解决软件调试的局限性,第二种调试方式为硬件调试 。硬件调试同样需要计算机软件的配合,其大致流程为:计算机软件将编译完成的程序通过串口、并口或 USB 接口传输至硬件调试设备(该设备称为仿真器 ),仿真器可完全仿真单片机的所有资源(包括所有接口及真实引脚输出),并可接入实际电路,实现与单片机一致的运行效果。
仿真的作用:
仿真器可将单片机内部的内存数据、时序信息等反馈至计算机的配套软件,开发人员可通过软件查看程序的实际运行状态。此外,还可通过计算机软件实现单步执行、全速运行、运行至光标处等常规调试操作。
二、keil Debug 常用按钮

单击窗口中的调试按钮快捷图标(上图红色框内图标),即可进入软件模拟调试模式。

RST (上图红色框内图标 ):可将程序复位至 main() 函数起始位置,为程序重新运行做好准备。

全速运行(上图红色框内图标):程序将持续运行,运行过程中不会自动停止。

停止全速运行(上图红色框内图标):仅在程序全速运行时激活,用于终止程序的全速运行状态。

进入子函数内部(上图红色框内图标):程序执行至函数调用语句时,可进入函数内部执行代码。

单步执行代码(上图红色框内图标):程序将逐行执行,遇到函数调用语句时,不会进入函数内部,直接跳过当前函数。

跳出当前进入的函数(上图红色框内图标):该按钮仅在进入函数内部调试时激活,按下后可跳出当前函数,返回至函数调用语句的下一行代码。

程序直接运行至当前光标所在行(上图红色框内图标):按下后,程序将快速运行至光标所在代码行并停止。


显示/隐藏编译窗口(上图红色框内图标):可查看每一行 C 语言代码对应的汇编代码。

显示/隐藏变量观察窗口:可查看程序运行过程中各变量的数值变化情况。
总结
在软件调试模式下,可完成断点设置、单步执行、全速运行、函数内部执行等操作,同时可实现变量变化监测、硬件 IO 口电平状态模拟、代码执行时间查看等功能。
Keil 的软件仿真和硬件仿真
qlexcel 原创于 2017-07-10 09:30:55 发布
本文阐述 Keil 开发环境下软件仿真与硬件仿真的配置流程及操作方法,详细说明仿真选项配置、Debug 工具栏功能调用、寄存器与内存数据观测等内容。
一、软件仿真
Keil 集成软件仿真功能,可在无硬件平台条件下排查程序潜在问题,观测与硬件相关的寄存器数值,通过寄存器数值变化判断程序运行状态。该方式可减少程序下载次数,延长单片机 Flash 存储单元的使用寿命。
开展仿真操作前,需完成下述选项配置。
- 在工程配置界面中,设置目标芯片型号与外部晶振频率参数。
- 在"Debug"选项卡内,勾选"Use Simulator"选项以启用软件仿真功能;勾选"Run to main()"选项,使仿真过程跳过汇编初始化代码,直接跳转至
main()函数开始执行。将"Dialog DLL"参数项配置为"DARMSTM.DLL"与"TARMSTM.DLL";将"parameter"参数项配置为"-pSTM32F103C8",该配置用于启用对 STM32F103C8 芯片的软硬件仿真支持。
- 点击
按钮启动仿真,此时界面将新增 Debug 工具栏。
Debug 工具栏各功能按钮编号及对应功能定义如下:
1:复位,功能等效于硬件复位按键,执行该操作后,程序将从起始地址重新开始执行。
2:运行至断点,用于将程序快速运行至预先设置的断点位置。适用于无需逐行观测程序执行流程、仅需查看特定位置运行结果的场景,使用该功能的前提为已在目标代码行设置断点。
3:停止运行,该按钮仅在程序处于持续运行状态时生效,点击后程序停止运行,进入单步调试模式。
4:执行进入,用于进入被调用函数的内部执行程序。在无函数调用的代码行执行该操作时,功能等效于执行跳过按钮。
5:执行跳过,程序执行至函数调用语句时,点击该按钮可单步跳过当前函数,不进入函数内部执行代码。
6:执行跳出,在函数内部执行单步调试操作时,若无需继续执行函数剩余代码,点击该按钮可完成函数剩余代码的执行,并跳出当前函数,返回至函数调用语句的下一行代码。
7:运行至光标处,可将程序快速运行至光标所在代码行,功能与运行至断点按钮类似。
8:汇编窗口,点击该按钮可打开汇编代码显示窗口,对程序执行效率分析与底层代码调试具有参考价值。
9:堆栈局部变量窗口,点击该按钮可打开 Call Stack+Locals 窗口,窗口内将显示当前执行函数的局部变量名称及对应数值,便于调试过程中观测变量状态。
10:观察窗口,MDK5 开发环境提供 2 个观察窗口,可通过下拉菜单进行切换。点击该按钮可调出变量观察窗口,输入待观测的变量名称或表达式,即可实时查看对应数值,是程序调试过程中的常用工具。
11:内存查看窗口,MDK5 开发环境提供 4 个内存查看窗口,点击该按钮可调出内存数据显示窗口,输入待观测的内存起始地址,即可查看对应内存区域的数值变化情况。
12:串口打印窗口,MDK5 开发环境提供 4 个串口打印窗口,点击该按钮可调出类似串口调试助手的界面,用于显示程序中串口输出的内容。
13:逻辑分析窗口,该按钮包含 3 个功能选项,通常选用第一个逻辑分析窗口选项。通过窗口内的 SETUP 按钮添加需要观测的 IO 端口引脚,即可查看对应引脚的电平变化波形,支持多种数据显示格式,可直观呈现引脚状态变化。
14:系统查看窗口,点击该按钮可打开外设寄存器观测窗口,可通过下拉菜单选择不同外设。选定目标外设后,窗口将显示该外设的所有寄存器列表及对应数值,便于验证寄存器配置参数的正确性。
二、硬件仿真
硬件仿真指将程序下载至目标单片机中执行的仿真方式,可真实反映程序在实际硬件平台中的运行状态。
在 Debug 选项卡中选择硬件仿真对应的选项,通过下拉菜单选定所使用的仿真器型号,后续调试操作步骤与软件仿真一致。
注:在硬件仿真模式下使用逻辑分析仪等工具时,需启用"Trace"功能。
STM32-Keil 软件仿真和硬件仿真/在线仿真
BUG 从入门到精通 于 2020-09-22 18:42:05 发布
本文详细阐述 STM32 系列芯片在 Keil 开发环境中的仿真配置与操作方法,明确软件仿真与硬件/在线仿真的区别。软件仿真适用于程序逻辑错误排查场景,硬件仿真适用于涉及硬件交互的功能调试场景。在硬件仿真部分,重点讲解 Jlink、STlink、ULINK 等常见仿真器的使用方法,介绍 JTAG、SWD、RDI 等仿真通信协议,同时详细说明 Jlink 仿真器在 Keil5 开发环境中的配置步骤。
软件仿真与硬件仿真的区别:软件仿真是无实际硬件参与的仿真方式,完全通过软件算法模拟单片机的运行机制;硬件仿真是将程序下载至目标控制芯片的 FLASH 或 RAM 存储区域,直接在实际硬件平台上执行的仿真方式。
仿真功能的使用效率存在差异,合理运用仿真功能可提升程序调试效率,使用不当则可能增加调试难度,甚至出现"还不如直接在硬件上调试靠谱"的情况。总体而言,仿真功能具有较高的实用价值,例如在排查寄存器配置错误等软件问题时,软件仿真的结果具有较高的可靠性;在涉及外部信号采集、硬件信号输出等与硬件强相关的功能调试时,则需采用硬件仿真或在线仿真方式。关于仿真技术的相关资料较为丰富,本文仅进行归纳总结。
一、软件仿真
1.1 仿真配置
首先确定仿真对应的硬件环境参数。点击工程配置的魔术棒图标
,在 Target 选项卡中确认仿真芯片型号参数正确,随后设置外部时钟源频率,STM32 系列芯片通常采用外部时钟,一般将外部时钟频率设置为 8 MHz 8\ \text{MHz} 8 MHz。

按照下述步骤完成选项勾选与参数配置,启用软件仿真需勾选 Use Simulator 选项;勾选 Run to main() 选项,使仿真过程跳过汇编初始化代码,直接跳转至 main() 函数开始执行。根据目标芯片型号修改 Dialog DLL 与 Parameter 参数,例如使用 STM32F103ZE 芯片时,需将参数 -pSTM32F103VB 修改为 -pSTM32F103ZE,该配置用于启用对所选芯片型号的软硬件仿真支持。完成配置后,仿真过程中可通过 Peripherals 菜单选择对应外设的观测窗口,查看仿真结果(该功能实用性较强,后续将详细说明)。

1.2 操作方法
点击
按钮启动仿真。

DEBUG 工具栏为程序调试的常用工具,对于入门级开发者而言,下述加粗标注的功能按钮使用频率较高。
- 复位:功能等效于硬件复位按键,执行该操作后,程序将从起始地址重新开始执行。
- 运行至断点:用于将程序快速运行至预先设置的断点位置。适用于无需逐行观测程序执行流程、仅需查看特定位置运行结果的场景,使用该功能的前提为已在目标代码行设置断点。
- 挂起:该按钮仅在程序处于持续运行状态时生效,点击后程序停止运行,进入单步调试模式。
- 执行进入:用于进入被调用函数的内部执行程序。在无函数调用的代码行执行该操作时,功能等效于执行跳过按钮。
- 执行跳过:程序执行至函数调用语句时,点击该按钮可单步跳过当前函数,不进入函数内部执行代码。
- 执行跳出:在函数内部执行单步调试操作时,若无需继续执行函数剩余代码,点击该按钮可完成函数剩余代码的执行,并跳出当前函数,返回至函数调用语句的下一行代码。
- 运行至光标处:可将程序快速运行至光标所在代码行,功能与运行至断点按钮类似,两者区别为:断点可在程序中设置多个,而光标在同一时间仅能存在一个位置。
- 汇编窗口:点击该按钮可打开汇编代码显示窗口,对程序执行效率分析与底层代码调试具有参考价值。
- 堆栈局部变量窗口 :点击该按钮可调出变量显示窗口,可在窗口中查看当前函数的局部变量数值,是程序调试过程中的常用工具。
- Watch 窗口:可用于观测程序中的全局变量数值。
- 串口打印窗口:点击该按钮可调出类似串口调试助手的界面,用于显示程序中串口输出的内容。需注意,该功能在硬件调试模式下无法使用,硬件调试时需通过专用硬件设备采集串口数据。
- 内存查看窗口:点击该按钮可调出内存数据显示窗口,输入待观测的内存起始地址,即可查看对应内存区域的数值变化情况,是程序调试过程中的常用工具。
- 性能分析窗口(未标注):点击该按钮可调出性能分析窗口,窗口内将显示程序中各函数的执行时间及占比数据,可用于函数执行效率分析。
- 逻辑分析窗口 :点击该按钮可调出逻辑分析窗口,通过窗口内的 SETUP 按钮添加需要观测的 IO 端口引脚,即可查看对应引脚的电平变化波形,支持多种数据显示格式,可直观呈现引脚状态变化。
关于程序运行至指定位置、断点设置与清除
等常规操作,本文不再赘述。
逻辑分析窗口
点击选择逻辑分析仪(Logic Analyzer)功能选项。

点击窗口左上角的 SETUP 按钮。

在配置界面中选择 Bit 显示类型,显示颜色可根据需求自由选择。引脚观测表达式需按照特定格式编写,例如观测 GPIOC13 引脚电平时,表达式为 ( P O R T C & 0 x 00002000 ) ≫ 13 (PORTC \ \& \ 0x00002000) \gg 13 (PORTC & 0x00002000)≫13。其中,PORTC 对应 GPIOC 端口寄存器,0x00002000 为掩码,用于提取 GPIOC13 引脚对应的 bit 位数值,右移 13 13 13 位操作可将该 bit 位移至最低位(总结规律为:观测引脚编号为 n n n 时,需将运算结果右移 n n n 位)。

若不清楚"&"按位与运算的掩码数值如何确定,可参考下述各引脚对应的宏定义数值:
cpp
#define GPIO_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */
#define GPIO_Pin_1 ((uint16_t)0x0002) /*!< Pin 1 selected */
#define GPIO_Pin_2 ((uint16_t)0x0004) /*!< Pin 2 selected */
#define GPIO_Pin_3 ((uint16_t)0x0008) /*!< Pin 3 selected */
#define GPIO_Pin_4 ((uint16_t)0x0010) /*!< Pin 4 selected */
#define GPIO_Pin_5 ((uint16_t)0x0020) /*!< Pin 5 selected */
#define GPIO_Pin_6 ((uint16_t)0x0040) /*!< Pin 6 selected */
#define GPIO_Pin_7 ((uint16_t)0x0080) /*!< Pin 7 selected */
#define GPIO_Pin_8 ((uint16_t)0x0100) /*!< Pin 8 selected */
#define GPIO_Pin_9 ((uint16_t)0x0200) /*!< Pin 9 selected */
#define GPIO_Pin_10 ((uint16_t)0x0400) /*!< Pin 10 selected */
#define GPIO_Pin_11 ((uint16_t)0x0800) /*!< Pin 11 selected */
#define GPIO_Pin_12 ((uint16_t)0x1000) /*!< Pin 12 selected */
#define GPIO_Pin_13 ((uint16_t)0x2000) /*!< Pin 13 selected */
#define GPIO_Pin_14 ((uint16_t)0x4000) /*!< Pin 14 selected */
#define GPIO_Pin_15 ((uint16_t)0x8000) /*!< Pin 15 selected */
例如,观测 PA11 引脚电平时,表达式为 ( P O R T A & 0 x 0800 ) ≫ 11 (PORTA \ \& \ 0x0800) \gg 11 (PORTA & 0x0800)≫11。根据上述宏定义,PA11 引脚对应的掩码数值为 0 x 0800 0x0800 0x0800,因此"&"按位与运算的操作数为 0 x 0800 0x0800 0x0800,引脚编号为 11 11 11,故将运算结果右移 11 11 11 位。
完成引脚观测表达式配置后,在 View 菜单中勾选窗口实时更新选项,仿真过程中数据将实时刷新,逻辑分析仪窗口可直观显示目标引脚的电平变化波形。

完成所有配置后,点击
按钮运行程序,即可在逻辑分析仪窗口查看目标引脚的电平变化波形。

Watch 窗口
Watch 窗口可用于观测程序中的全局变量,将全局变量添加至窗口后,程序运行过程中可实时查看变量的数值变化情况。

例如,观测结构体数组变量时,变量的数值、数据类型等信息可在 Watch 窗口中清晰呈现。

需注意,Watch 窗口无法观测函数的局部变量,局部变量需通过堆栈局部变量窗口进行查看。
堆栈局部变量窗口
堆与栈的概念定义:
什么是堆栈?
内存分配方式分为三种:
1\] 从静态存储区域分配。内存在程序编译阶段完成分配,该部分内存在程序整个运行周期内均有效,例如全局变量、static 静态变量均存储于该区域。 \[2\] 在栈上创建。函数执行过程中,局部变量的存储单元在栈空间中分配,函数执行结束后,对应的栈空间将被自动释放。栈内存分配由处理器指令集直接支持,分配效率较高,但可分配的内存容量有限。 \[3\] 从堆上分配,也称为动态内存分配。程序运行过程中,可通过 malloc 函数或 new 运算符申请任意大小的内存空间,程序员需通过 free 函数或 delete 运算符手动释放已申请的内存。动态内存的生命周期由程序员控制,使用方式灵活,但如果未及时释放已申请的内存空间,将导致内存泄漏问题;频繁分配和释放不同大小的堆内存空间,将产生内存碎片。
简言之,堆栈局部变量窗口可用于观测在栈空间中分配的变量,经实际测试验证,该窗口也可查看静态变量。通过 Watch 窗口与堆栈局部变量窗口的配合使用,可实现对程序中几乎所有变量的监测。
Peripherals 窗口
该窗口用于在仿真过程中观测和修改芯片外设寄存器的数值,System Viewer 功能的入口为下图箭头所指位置。


需注意,System Viewer 为通用外设观测选项,涵盖多种类型的外设,但部分外设可能并非所选芯片实际集成的资源。例如,使用 STM32VBT6 芯片时,该芯片仅集成 3 个串口外设,而 System Viewer 窗口中显示的串口数量为 5 个。System Viewer 窗口中显示的外设类型由前文配置的 Dialog DLL 与 Parameter 参数决定,因此,若需正常使用该功能,必须确保 Dialog DLL 与 Parameter 参数与所选芯片型号保持一致。
两种外设观测窗口的界面存在差异,具体对比如下:


左图为 System Viewer 窗口的界面,可直接显示外设的所有寄存器名称及各 bit 位的数值;右图为另一类外设观测窗口界面,相比 System Viewer 界面,数据呈现形式更为直观。
二、硬件/在线仿真
2.1 仿真器通信协议/接口
目前主流的仿真通信协议为 JTAG 协议与 SWD 协议,常见仿真器通常同时支持这两种协议/接口。
JTAG 协议/接口
JTAG(Joint Test Action Group,联合测试行动小组)是一种国际标准测试协议(兼容 IEEE 1149.1 标准),主要应用于芯片内部测试领域。当前,多数高性能半导体器件均支持 JTAG 协议,例如 ARM 处理器、DSP 数字信号处理器、FPGA 现场可编程门阵列等器件。JTAG 协议的工作原理可概括为:在器件内部定义一个 TAP(Test Access Port,测试访问端口),通过专用 JTAG 测试工具对器件内部的节点进行测试和调试。对于内置 JTAG Debug 接口模块的 CPU,只要时钟信号正常,即可通过 JTAG 接口访问 CPU 内部寄存器、挂载在 CPU 总线上的外设以及内置功能模块的寄存器。
JTAG 接口通过 5 根信号线与目标 CPU 连接,分别为 TMS、TCK、TDI、TDO、NTRST,各信号线的功能定义如下:
- TMS:测试模式选择,用于设置 JTAG 接口的工作模式;
- TCK:测试时钟输入,为 JTAG 接口提供同步时钟信号;
- TDI:测试数据输入,测试指令与数据通过该引脚输入至 JTAG 接口;
- TDO:测试数据输出,测试结果数据通过该引脚从 JTAG 接口输出;
- NTRST:JTAG 模块复位信号,用于对 JTAG 接口进行复位操作。
在引脚资源紧张的应用场景下,NTRST 复位引脚可省略。
SWD 协议/接口
SWD 全称为 Serial Wire Debug,是 ARM 公司专为嵌入式设备设计的轻量级调试接口,该接口仅通过一条双向数据线和一条时钟线,即可实现对 ARM 内核的调试功能。
SWD 接口通过 3 根信号线与目标 MCU 连接,分别为 SWDIO、SWDCLK 和 GND,各信号线的功能定义如下:
- SWDIO:双向数据接口,用于实现调试主机与目标设备之间的数据传输;
- SWDCLK:时钟接口,由调试主机提供同步时钟信号;
- GND:接地引脚,为接口提供电气参考。
关于 SWD 协议的详细技术内容,可参考文章
- ARM SWD 协议简介 - 代码复刻版
https://linmingjie.cn/index.php/archives/334/
若需开展更深入的研究,可参考硕士论文
- WD 协议的研究及 ARM 程序下载器的设计
https://wenku.baidu.com/view/49a9277aeff9aef8951e061f.html
RDI 协议/接口
RDI 全称为 Remote Debug Interface(远程调试接口),是 ARM 公司制定的标准调试接口规范,主要用于 ARM 系列芯片的仿真调试。早期,各 IDE 开发工具厂商使用的调试接口互不兼容,导致硬件调试功能无法跨平台使用。目前,多数 IDE 开发工具厂商已逐步采用标准 RDI 接口作为 ARM 仿真器的调试接口,实现了跨平台硬件调试功能。例如,EasyJTAG 仿真器采用标准 RDI 调试接口,可在 ARM ADS1.2、IAR EWARM 3.30 等支持标准 RDI 接口的 IDE 开发环境中使用。
2.2 常见仿真器
Jlink
J-Link 是德国 SEGGER 公司推出的基于 JTAG 协议的仿真器,本质为 JTAG 协议转换设备,即一款小型 USB 转 JTAG 接口的转换模块。该仿真器通过 USB 接口与计算机连接,通过 JTAG 协议与目标电路板通信,实现 USB 接口与 JTAG 接口之间的数据转换。J-Link 是一款通用型嵌入式开发工具,支持 Keil、IAR、ADS 等多种开发平台,具有运行速度快、调试效率高、功能丰富等特点,是性能较为出色的仿真器产品之一。

STlink
ST-LINK 是意法半导体公司推出的专用仿真器产品,适用于 STM8 和 STM32 系列芯片。ST-LINK /V2 仿真器支持 SWIM 标准接口和 JTAG / SWD 标准接口。

ULINK
ULINK 是 ARM/KEIL 公司推出的仿真器产品,专为 Keil 开发平台设计,无法在 ADS、IAR 等其他开发平台中使用。

2.3 Jlink 的 Keil5 仿真配置
首先确认所选芯片支持的仿真通信协议,STM32F103 系列芯片同时支持 JTAG 和 SWD 两种协议。需注意,PA13、PA14、PA15、PB3、PB4 引脚的默认功能为调试引脚,若需将这些引脚作为普通 IO 口使用,需进行引脚重映射配置,具体方法可参考文章《Remap 为普通 IO》。
STM32-PA13、PA14、PA15、PB3、PB4等默认为仿真功能引脚重映射为普通 IO
BUG从入门到精通 于 2020-09-22 19:13:33 发布
本文阐述 STM32 系列芯片中 PA13、PA14、PA15、PB3、PB4 引脚的功能特性,此类引脚默认配置为仿真功能,若需将其作为普通 IO 口使用,需执行引脚重映射操作。文中结合芯片手册说明引脚默认配置,并提供释放 PB3、PB4、PA15 等引脚为普通 IO 口的代码示例,实现引脚功能转换。
在未充分掌握仿真引脚特性的情况下,易出现"配置参数无误,但 PA13、PA14、PA15、PB3、PB4 引脚无法按预期工作"的问题,其核心原因在于此类引脚的默认功能为仿真功能。相关配置可参考下图(芯片手册截图):
若需将此类引脚配置为普通 IO 口,需执行重映射操作。下述代码可释放 PB3、PB4、PA15 引脚为普通 IO 口:
cppRCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);引脚重映射配置可使用以下参数,各参数对应不同的引脚释放范围:
GPIO_Remap_SWJ_NoJTRST:仅释放 PB4 引脚为普通 IO 口,保留完整的 SWJ 仿真功能(JTAG-DP + SW-DP),仅禁用 JTRST 功能;GPIO_Remap_SWJ_JTAGDisable:释放 PB3、PB4、PA15 引脚为普通 IO 口,禁用 JTAG-DP 功能,保留 SW-DP 仿真功能;GPIO_Remap_SWJ_Disable:释放所有仿真引脚为普通 IO 口,完全禁用 SWJ 仿真功能(JTAG-DP + SW-DP)。对应的宏定义如下:
cpp#define GPIO_Remap_SWJ_NoJTRST ((uint32_t)0x00300100) /*!< Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRST */ #define GPIO_Remap_SWJ_JTAGDisable ((uint32_t)0x00300200) /*!< JTAG-DP Disabled and SW-DP Enabled */ #define GPIO_Remap_SWJ_Disable ((uint32_t)0x00300400) /*!< Full SWJ Disabled (JTAG-DP + SW-DP) */总结
- STM32 的 PA13、PA14、PA15、PB3、PB4 引脚默认配置为仿真功能,直接配置为普通 IO 口无法正常工作;
- 引脚重映射需先开启 AFIO 外设时钟,再通过
GPIO_PinRemapConfig函数选择对应参数;- 不同重映射参数对应不同的引脚释放范围,需根据仿真功能保留需求选择适配参数。


在工程配置魔术棒的 DEBUG 选项卡中,选择使用仿真器选项,并通过下拉菜单选定对应的仿真器型号。

点击 setting 按钮,选择仿真接口类型(SW 接口或 JTAG 接口),建议将通信速度设置为 4 MHz 4\ \text{MHz} 4 MHz。通信速度过高时,可能导致 Flash 存储单元的擦写操作失败。

程序下载操作需通过仿真器完成,因此需在配置界面中勾选使用仿真器选项。

最后,根据所选芯片的 Flash 存储容量选择对应的下载算法。

2.4 硬件仿真操作方法
硬件仿真的操作步骤与软件仿真完全一致,两者区别在于硬件仿真基于实际硬件平台运行,可实现真实的硬件数据输入与输出功能。例如,在按键功能的仿真调试过程中,仅通过硬件/在线仿真方式,才能验证芯片对按键输入信号的处理逻辑是否正确。
若不清楚如何根据芯片型号确定 Flash 容量,可参考 STM32 芯片的命名规则,或查阅文章《STM32-不同芯片的移植》中相关内容。
STM32-不同芯片的移植
BUG从入门到精通 于 2020-09-16 21:18:25 发布
本文阐述 STM32 不同型号芯片间的代码移植步骤,包括确定目标芯片的 Flash 存储容量、选择适配的启动文件、修改工程配置参数及 IDE 开发环境相关设置。强调启动文件选择与系统初始化配置的重要性,并提供可验证的移植实例。
在实际项目开发过程中,需根据项目需求选择适配的芯片型号,部分应用场景下需将同一工程代码移植至不同型号的芯片。本文将详细讲解 STM32 不同型号芯片间的基础移植流程。
1. 准备工作
1.1 依据芯片命名规则确定目标芯片的 Flash 容量
芯片型号中的特定字符用于标识 Flash 存储容量,例如 STM32F103VBT6 型号中,字符"B"对应的 Flash 容量为 128 KB 128\ \text{KB} 128 KB,据此可确定目标芯片的 Flash 存储大小。
1.2 依据 Flash 容量选择适配的启动文件
ST 官方为 STM32F1 系列芯片提供 3 款启动文件,分别适配不同 Flash 存储容量的芯片,具体如下:
startup_stm32f10x_ld.s:适用于小容量芯片startup_stm32f10x_md.s:适用于中等容量芯片startup_stm32f10x_hd.s:适用于大容量芯片Flash 容量划分规则:
- 小容量: F L A S H ≤ 32 KB FLASH \le 32\ \text{KB} FLASH≤32 KB
- 中容量: 64 KB ≤ F L A S H ≤ 128 KB 64\ \text{KB} \le FLASH \le 128\ \text{KB} 64 KB≤FLASH≤128 KB
- 大容量: 256 KB ≤ F L A S H 256\ \text{KB} \le FLASH 256 KB≤FLASH
需根据目标芯片的 Flash 存储容量选择对应的
.s启动文件。若目标芯片对应的启动文件与原工程不一致,需替换启动文件;若一致,则可跳过该步骤(启动文件可在原子开发板配套资料中获取)。1.3 调整启动文件的系统初始化配置
项目开发过程中常用库函数版本的工程代码,而ST 官方提供的启动文件中,默认注释了调用系统初始化函数的代码段 (
.s汇编文件中,分号;为注释符)。若未取消该段代码的注释,将导致系统时钟无法完成初始化操作。因此,使用库函数版本工程时,必须删除该段代码的注释符号。
1.4 替换工程中的启动文件
将原工程中的启动文件替换为适配目标芯片的启动文件,即可完成该步骤操作。
2. 配置 IDE(Keil)
点击工程界面的魔术棒图标,按照下述步骤完成配置:
1)Device 选项:选择目标单片机的具体型号;
2)C/C++ 选项:根据目标芯片的 Flash 容量(大/中/小),在宏定义列表中对应修改为:
STM32F10X_HD、STM32F10X_MD、STM32F10X_LD。3)Debug 选项:根据目标芯片型号修改对应参数,例如目标芯片为 STM32F103VBT6 时,需将参数修改为
-pSTM32F103VB。修改完成后点击 OK 按钮保存配置。
4)再次打开 Debug 选项卡,按照界面箭头指引完成操作(下载器/仿真器的基础配置本文不赘述),根据目标芯片的 Flash 容量选择适配的 Flash 大小参数。
3. 下载/仿真验证
完成上述所有配置后,将程序下载至目标芯片,验证移植效果即可。
由于该方法尚未经过多型号芯片的大规模验证,为保证严谨性,笔者将根据网友反馈持续更新经验证的芯片型号。欢迎各位在移植成功后反馈所移植的芯片型号,也欢迎指正文中错误,以提升本文方法的可靠性与通用性。
验证案例:STM32F103ZET6 移植至 STM32F103VBT6,该方法验证可行。
总结
- STM32 跨型号移植需匹配 Flash 容量对应的启动文件与工程宏定义,启动文件中系统初始化函数的注释必须取消,否则会导致时钟初始化失败;
- Keil 开发环境配置需修改 Device 芯片型号、C/C++ 宏定义、Debug 芯片参数及 Flash 大小这 4 项内容;
- 已验证 STM32F103ZET6 到 STM32F103VBT6 的移植可行,其他型号需结合实际项目验证。
via:
-
Keil 软件仿真_keil 仿真如何直接到最后结果-CSDN 博客
https://blog.csdn.net/qq_37868856/article/details/90057141 -
keil 软件调试(Debug)仿真教程(软件调试和硬件调试的区别)及常用调试按键详解_keil debug-CSDN 博客
https://blog.csdn.net/weixin_51624736/article/details/128611549 -
Keil 的软件仿真和硬件仿真-CSDN 博客
https://blog.csdn.net/qlexcel/article/details/54949093 -
STM32-Keil 软件仿真和硬件仿真/在线仿真_stlink 仿真器能使程序运行在 ram 里面么-CSDN 博客
https://blog.csdn.net/wei348144881/article/details/108715684- STM32-PA13、PA14、PA15、PB3、PB4 等默认为仿真功能引脚重映射为普通 IO_stm32 的 pa 和 pb 引脚-CSDN 博客
https://blog.csdn.net/wei348144881/article/details/108738602 - STM32-不同芯片的移植_stm32f030 的文件可以装其他芯片吗-CSDN 博客
https://blog.csdn.net/wei348144881/article/details/108608570
- STM32-PA13、PA14、PA15、PB3、PB4 等默认为仿真功能引脚重映射为普通 IO_stm32 的 pa 和 pb 引脚-CSDN 博客









