在这里插入图片描述

📃个人主页:island1314

⛺️ 欢迎关注:👍点赞 👂🏽留言 😍收藏 💞 💞 💞

  • 生活总是不会一帆风顺,前进的道路也不会永远一马平川,如何面对挫折影响人生走向 – 《人民日报》


纯新手教学

一、基本概述

Keil提供了包括C编译器 、宏汇编、链接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(μVision)将这些部分组合在一起。
补充:目前软件对中文的支持不友好,不建议安装网上的一些汉化包之类的。另外建立的工程文件路径也尽量不要存在中文,否则可能会出现一些异常。

二、软件下载安装配置

1. 软件下载

通过网盘分享的文件:MDK535.EXE
链接: https://pan.baidu.com/s/1cPaoAq0jAj-8onEOrRXekg 提取码: j3yy

当前觉得网盘下载慢的,也可以直接官网下载,用注册机生成Lisence即可(网上有教程),个人用没什么问题,企业组织的话最好购买正版

2. 软件安装

这个没什么特殊的,一路next就行。如果是自己用的,一般不建议装在C盘,因为后续芯片包都会默认安装在此目录下,文件会变得很大。

3. 下载/安装芯片包

跟旧版本的Keil不一样,Keil4以前是软件里集成芯片包,也就是只要下载安装完Keil的软件,就有对应的一些芯片可供选择使用。但由于现在软件支持的芯片越来越多,软件的体量也就越来越大,如果把所有芯片包都跟软件打包一起下载,那软件估计得有几百个G。所以为了简洁,Keil把集成环境跟芯片包、例程等东西分开单独下载,具体要用到什么芯片再自己去下载安装对应的芯片包。

这里以 STM32F103 为例

方式一:在Keil里下载
    点击 “Pack Installer”,也就是这个图标,第一次打开可能会很慢,因为要从官网自动更新所有芯片包的信息。这时候很坑的一个点是,你不更新,可能又没法找到你想要的芯片,所以在信息更新完前,只能乖乖地等它更新完。然而这种国外链接,又时不时给你断一下。

image-20260412000503100

在更新完后,在左边的窗口中找到想要安装的芯片型号,可以选择整个系列(或具体芯片,结果是一样的),这里以STM32G071为例。然后在右边窗口中,找到"Device Specific"里面 “Keil:STM32F1xx_DFP” 这一项,点击按钮 “Install” 下载安装。(同样的,网络卡的时候下载很慢,还经常断开链接)

等到下载安装完成后(右下角有进度条),“Install"键会变成"up to date”,这时候说明安装成功。

当前也有可能出现 install 是灰色的,这样只能去官方网站下

方式二:官网下载
    前面那种方法在很多时候都是行不通的,不是网络不好就是网络不好。所以可以通过另外一个方式更新芯片包,那就是先从官网提前下载好芯片包,再点击安装。
官网链接:https://www.keil.com/dd2/Pack/
    同样,先找到对应的芯片(这里展开时可能不会显示所有芯片,找不到对应芯片时,点击下面"View all in family"展示所有芯片),选择"xxxxx_DFP",点"Download Recommended Pack"即可下载。

image-20260412000721044

点击进去之后,如下:

image-20260412000824341

这种方式有个好处就是即使在官网无法下载时,也可以假借他人之手去下载。为了防止小伙伴们在官网下载也出现网络中断的情况,这里提供STM32常用系列的芯片包供下载使用(版本可能不是最新的,可以凑和着用)。

这种方法安装之后的包记得放在软件的 Packs 路径下,如下:

image-20260412000911737

然后直接点击这个包进行安装,一路 Next 即可

4. 注意事项

  1. 工程路径下不可以有中文,否则可能编译或调试时会有影响。
  2. 工程文件路径不可过长,这个软件对路径的识别是有长度限制的,当文件的总路径长度超过一定限制后,编译时可能会报无法查找到相关文件。

三、创建工程

步骤 1:新建工程

① 打开 Keil MDK 5

② 点击 Project → New uVision Project

image-20260412001100688

③ 选择保存路径,输入工程名(如 RTC_Time_Demo

④ 点击保存

步骤 2:选择芯片型号

① 在弹出的设备选择窗口中,展开 STMicroelectronics

② 选择 STM32F1 SeriesSTM32F103

image-20260412001342901

③ 选择你的具体型号(如 STM32F103C8

④ 点击 OK

步骤 3:配置运行环境

弹出询问是否添加启动文件和 CMSIS 时:

  • 勾选 CMSIS 下的 CORE
  • 勾选 Device 下的 Startup
  • 点击 OK

image-20260412001415074

这个时候一个工程项目就生成好啦,如下:

image-20260412001520054

新建/添加文件

有了工程还不够,就像建房子一样,这时候只是把钢筋水泥弄好,做出个房子的外型,离真正可以居住的温馨小屋还差亿点点距离。所以这时候就得加点核心进来,也就是我们的源代码。

创建示例工程

用 Pack Installer 安装 DFP 后,直接打开芯片厂商提供的示例工程,理解工程结构

这里以其提供的工程项目为例,如下:

image-20260412100544547

示例名称难度用途
CMSIS-RTOS Blinky⭐ 简单LED 闪烁 + RTOS 基础
USB Device Virtual COM⭐⭐ 中等串口通信
emWin Example⭐⭐⭐ 较难图形界面显示
USB Device HID⭐⭐⭐ 较难USB 键盘/鼠标
USB Device Mass Storage⭐⭐⭐ 较难U盘功能
File System Demo⭐⭐⭐ 较难SD 卡文件操作
CAN/CAN RTR⭐⭐⭐ 较难CAN 总线通信
emWin GUI Demo⭐⭐⭐⭐ 困难复杂图形界面

这里为了方便理解,我就选择CSIS-RTOS Blinky

  1. 点击对应的 Copy 按钮
  2. 等待下载完成(可能需要几分钟)
  3. 安装完成后,示例会自动添加到系统中

image-20260412100947829

理解工程结构

打开工程后,会看到以下文件结构:

Project: RTOS_Blinky
│
├───RTE (Run-Time Environment)
│    ├───CMSIS
│    │    └── RTX_Conf_CM.c       ← RTOS 配置文件
│    ├───Device
│    │    └── STM32F103C8
│    │         ├───startup_stm32f10x_md.s  ← 启动文件
│    │         └───system_stm32f10x.c      ← 系统配置
│    └───_RTOS_Blinky
│
├───Blinky.c                      ← 主程序(LED 闪烁)
├───main.c                        ← 入口函数
└───README.txt                    ← 说明文档

📄 关键文件说明:

main.c - 程序入口:

int main(void) {
    SystemInit();           // 系统初始化(时钟配置)
    osKernelInitialize();   // RTOS 内核初始化
    osThreadCreate(osThread(Blinky), NULL);  // 创建 LED 任务
    osKernelStart();        // 启动 RTOS
}

Blinky.c - LED 闪烁任务:

void Blinky(void const *argument) {
    for (;;) {
        LED_On();           // 开 LED
        osDelay(500);       // 延时 500ms
        LED_Off();          // 关 LED
        osDelay(500);       // 延时 500ms
    }
}

四、具体使用

1. 打开工程

  1. 在 Keil 5 中,点击 Project → Open Project(或按 Ctrl+O
  2. 导航到示例工程目录
  3. 选择 .uvprojx 文件(Keil 5 工程文件)
  4. 点击 Open

image-20260412101318491

打开之后结果如下:

image-20260412101048278


2. 新建/添加文件

如果是有了工程还不够,就像建房子一样,这时候只是把钢筋水泥弄好,做出个房子的外型,离真正可以居住的温馨小屋还差亿点点距离。所以这时候就得加点核心进来,也就是我们的源代码。

image-20260412123835416

创建文件组
  1. 右击项目选择 Manege Project Items
  2. 右键 Source Group 1Rename → 改为 User
  3. 右键 Target 1 → Add New Group to Group ‘User’
    • 输入:Driver
  4. 再添加一个组:
    • 输入:System

image-20260412185618063

但是当前我是以示例工程作为示例,所以可以不用新增其他文件


3. 配置工程

为了可以正常地跟开发板及烧录器进行匹配,这里我们还需要对工程进行一些配置。

3.1 选择正确的芯片型号
  1. 右键点击项目名Options for Target ‘…’(或点击工具栏魔术棒图标 🔧)

    image-20260412101821667

  2. Device 标签页:

    • 点击 Change… 按钮
    • 展开 STMicroelectronicsSTM32F1 Series
    • 选择你的具体型号,例如:STM32F103VB
    • 点击 OK

    image-20260412101913165


3.2 配置调试器

选择在线调试或离线仿真两种方式,如果有开发板,建议选在线调试直接在板子上进行实验。

在这里插入图片描述

离线仿真设置

  1. 选择仿真器:在 Keil5 中,点击魔法棒图标,进入项目设置页面。在“Debug”选项 卡中,选择“Use Simulator”。
  2. 设置晶振:输入你所使用的单片机板子的晶振频率。
  3. 选择 DLL 文件:根据所使用的单片机型号,选择相应的 DLL 文件。例如,使用 STM32 系列单片机时,选择 DARMSTM.DLL。
    image-20260412102111580

如果是没有开发板的情况,想要大致跑下自己写的逻辑有没有问题,可以使用离线仿真这种方式。但如果逻辑中涉及跟单片机外设或开发板外围电路的一些配合,则不适合使用这种方式调试。

在线烧录设置

选择了在线调试后,需要选择烧录器的类型。

① 选择烧录器类型(这里我们选择,也就是开发板上自带的这个烧录器的类型)

image-20260412112318372

这里还得看具体的烧录器配置,我之前选择ST-Link导致我后面在烧录的时候出现了:No ST-LINK detected",表示我选错了 选错了调试器类型

② 点击右侧的 Settings 按钮:

  • Port 选择:SW

  • Max Clock 设置为:5 MHz(默认 10MHz)(如果烧录失败,降低到 1 MHz)

  • 点击 OK

    image-20260412102405058

③ 测试连接:

  • 点击 Flash Download 标签页

    Programming Algorithm:烧录算法选择,一般选择完芯片后,会自动选择对应的烧录算法。手动添加烧录算法。添加方式很简单,把对应的算法文件(后缀是FLM)放到Keil安装根目录 Keil_v5/ARM/Flash 路径下,点 Add 按钮,选择对应的文件即可。

  • 点击 Add 添加 Flash 算法(通常会自动添加)

  • 确保看到你的芯片 Flash 信息

image-20260412102737218

  1. Erase Full Chip:擦除整片,每次下载时,都会对整个Flash进行擦除操作。
  2. Erase Sectors:擦除部分,每次下载时,只会擦除使用到的Flash扇区(备注:只要在start和size设置好程序擦除的范围就可以避免自己的存储的flash数据被误擦)。
  3. Do not Erase:不擦除,每次下载时,不擦除原本代码。
  4. Program:烧录,下载时才会把代码写入Flash,否则不写入。
  5. Verify:校验,烧录代码之后,对代码进行校验。
  6. Reset and Run:复位并运行,下载完成之后,立即复位运行程序。
  7. RAM for Algorithm:给烧录算法的RAM空间,一般选择完芯片之后,按默认就行。
    1. Start:RAM空间的起始地址。
    2. Size:RAM空间的大小。
理解 Max Clock

Max ClockSWD/JTAG 调试接口的时钟频率(SWCLK 引脚的信号频率)。

作用原理

PC (Keil) ←→ CMSIS-DAP←→ SWCLK/SWDIO ←→ STM32芯片
           ↓
      这个时钟频率控制通信速度
  • 高频率 = 烧录/调试速度快,但稳定性差
  • 低频率 = 烧录/调试速度慢,但稳定性好

场景对比:

情况推荐频率原因
短接线、良好环境10 MHz速度快,节省时间
长接线、杜邦线1-5 MHz减少信号干扰
烧录失败、不稳定1 MHz最稳定,保证成功
芯片时钟配置错误1 MHz芯片时钟异常时仍能通信

常见问题场景

问题 1:烧录时断时续

Error: Flash Download failed - Target DLL has been cancelled

解决:降低 Max Clock 到 1 MHz

问题 2:调试时经常断开

Error: Could not stop Cortex-M device

解决:降低频率,增加稳定性

问题 3:芯片时钟未配置或错误

  • 如果芯片使用内部 8MHz HSI,SWD 频率过高会通信失败
  • 降低到 1 MHz 确保可靠通信
Flash 算法

Flash 算法(在 Keil 里通常以 .FLM 文件存在)负责调试器与 MCU 内部 Flash 通信的全套操作

功能说明
擦除 (Erase)按扇区(Sector)或整片(Chip)擦除,将数据恢复为 0xFF
编程/写入 (Program)把编译好的代码数据写入 Flash 指定地址
校验 (Verify)写入后立即读回对比,确保数据 100% 正确
空白检查 (Blank Check)检查某块区域是否已是空的(全 0xFF),避免重复擦除
读/写保护操作解除或设置芯片的 Read/Write Protection 状态

🤔 为什么需要它?

不同 MCU 的 Flash 控制器硬件设计完全不同

  • 操作命令序列不同(STM32 是写寄存器解锁→擦除→编程→锁存)
  • 时序要求不同(等待 Busy 标志、延迟周期)
  • 扇区划分不同(F1 系列是 1KB/页,F4 系列是 16KB/128KB 混合扇区)
  • 电压/温度补偿机制不同

Keil 的调试核心(ST-Link/J-Link 固件)是通用的,它不懂具体芯片怎么操作 Flash。Flash 算法就是**“翻译官”**,把通用的下载指令翻译成目标芯片能听懂的寄存器操作。

⚙️ 在 Keil 中是如何工作的?

当你点击下载或进入调试时,幕后流程如下:

  1. 加载:Keil 从 Flash Download 列表中找到对应的 .FLM 文件
  2. 搬运:通过 SWD/JTAG 把这段算法代码临时下载到 STM32 的 RAM 中
  3. 执行:调试器发送命令,让 CPU 执行 RAM 里的算法代码
  4. 操作:算法代码直接读写 Flash 控制器寄存器,完成擦除/写入/校验
  5. 清理:操作完成后,算法从 RAM 移除,你的正式程序开始运行

💡 关键点:算法是跑在目标芯片 RAM 里的,不是跑在电脑或调试器里的。

📦 通俗比喻

调试器 (ST-Link)  = 快递员
你的代码数据     = 包裹
Flash 算法       = 不同小区的“门禁密码 + 电梯操作指南 + 楼层分布图”
芯片内部 Flash   = 一栋结构复杂的公寓楼

没有算法 → 快递员到了门口,不知道按哪个键、怎么进楼、包裹该放几零几
有了算法 → 快递员按指南操作,准确把包裹送到指定房间

3.3 编译选项设置
  1. Target 标签页:

    XTAL (MHz): 8.0
    Read/Only Memory Areas:
      IROM1: Start = 0x08000000, Size = 0x10000 (64KB)
    

    image-20260412102908234

  2. Output 标签页:

    • 勾选 Create HEX File(生成 HEX 文件)

    • 点击 Select Folder for Objects… 选择输出目录(一般默认生成放在当前工程路径下,所以这个可以不用管的)

      image-20260412103101519

    有些场合下,只能通过Hex文件进行烧录,这时候就需要在工程里勾选"Create HEX File",这样在编译之后工程会自动生成Hex的可执行文件。

  3. C/C++ 标签页:(重点⭐⭐,必须设置)

    • Define 框中输入:

      USE_STDPERIPH_DRIVER, STM32F10X_MD
      
    • Include Paths 添加必要路径:

      • 点击 按钮

      • 添加:

        ./RTE/_RTOS_Blinky
        ./RTE/CMSIS
        ./RTE/Device/STM32F103VB
        

知识补充

🔍Q1.Define 框里的内容到底是什么?

在 C 语言中,#define 用于定义宏。Keil 的 Define 框的作用是:在编译整个工程时,自动在所有源文件头部注入这些宏定义

1. USE_STDPERIPH_DRIVER

  • 字面意思:使用标准外设驱动库(Standard Peripheral Library)

  • 底层作用:STM32 的官方库文件(如 stm32f10x.h)里写满了条件编译代码:

    #ifdef USE_STDPERIPH_DRIVER
        #include "stm32f10x_conf.h"  // 引入外设配置文件
    #endif
    

    如果你不在 Define 框里写这个宏,编译器就会跳过 #include,导致后续所有 GPIO、USART、RTC 等函数全部报 undefined identifier(未定义标识符)。

    💡 注:如果用的是较新的 HAL 库,这里通常换成 USE_HAL_DRIVER。你看的这个老示例基于 SPL 库,所以是 STDPERIPH

2. STM32F10X_MD

  • 字面意思:STM32F10 系列 中容量(Medium Density) 芯片

  • 底层作用:STM32F103 有很多子型号,Flash 大小不同,外设也有差异。库文件通过宏来区分:

    #if defined (STM32F10X_LD)   // 小容量 (16K~32K Flash)
    #elif defined (STM32F10X_MD) // 中容量 (64K~128K Flash) → 如 C8、RB
    #elif defined (STM32F10X_HD) // 大容量 (256K~512K Flash) → 如 ZET6、RCT6
    #endif
    

    定义 MD 后,编译器只会编译与你芯片匹配的外设代码,避免编译进不存在的硬件驱动导致报错,同时减小固件体积

    ⚠️ 注意:如果实际用的是 STM32F103RCT6(256KB Flash),这里必须改成 STM32F10X_HD,否则烧录后部分功能会异常!


📂 Q2.Include Paths(头文件路径)为什么必须手动加?

编译器的“找文件”规则:

当写 #include "stm32f10x.h" 时,编译器默认只去两个地方找:

  1. 当前 .c 文件所在的文件夹
  2. 编译器自带的标准库路径

但 Keil 的 Pack 安装包把文件分散放在了 RTE/ 子目录里,编译器根本不知道去哪找。Include Paths 就是告诉编译器:“去这些文件夹里搜头文件!”

如果不加这些路径 → 编译直接报:

error: #5: cannot open source input file "stm32f10x.h": No such file or directory

🛠 现代 Keil 开发中的“自动 vs 手动”

你问“其他一般默认即可,为啥这个要手动?” 这里有个重要背景:

  • 早期 Keil(无 Pack 时代):所有路径和宏都必须手动敲,非常繁琐。
  • 现代 Keil 5 + CMSIS-Pack:当通过 Pack Installer 安装 DFP 并在 RTE 界面勾选组件后,Keil 理论上会自动生成 这些路径和宏。
  • 为什么还看到需要手动加?
    1. Pack 安装不完整或路径未刷新。
    2. 手动配置是最稳妥的兜底方案,尤其适合理解底层机制。

建议:在新建工程时,如果使用了 Pack 和 RTE 勾选器,通常不需要手动填。但理解这些配置的含义,能让你在遇到 #include 找不到、宏未定义、芯片型号不匹配等 90% 的编译错误时,瞬间定位问题.

3.4 RTX RTOS 配置
  1. 展开左侧项目树,找到 RTE 文件夹

  2. 双击 RTX_Conf_CM.c 文件

  3. 检查关键配置:

    #define OS_CLOCK 72000000  // 系统时钟 72MHz
    #define OS_TICK 1000       // RTOS 心跳 1ms
    

image-20260412105423983


4. 编译工程

方法 1:工具栏按钮

  • 点击工具栏的 Rebuild 按钮(两个箭头循环图标 🔄)

方法 2:快捷键

  • F7

方法 3:菜单

  • Project → Rebuild all target files

image-20260412105631079

查看编译结果

底部 Build Output 窗口显示:

image-20260412105715472

成功标志0 Error(s), 0 Warning(s)

注:如果此时出现了Error信息,则无法编译通过,需要修改源代码直到编译结果0-Error,才可以正常生成可执行文件。如果出现Warning信息,可视情况进行处理,Warning信息不影响编译结果,但建议多关注下这些Warning信息,很多Bug就隐藏在里面。

常见编译错误及解决:

错误 1:找不到头文件

error:  #5: cannot open source input file "stm32f10x.h": No such file or directory

解决

  • Options → C/C++ → Include Paths
  • 添加路径:./RTE/Device/STM32F103C8

示例:

D:\lifeskill\Keil5\Packs\Keil\STM32F1xx_DFP\2.4.1\Device\Include\stm32f10x.h(8347): error:  #5: cannot open source input file "stm32f10x_conf.h": No such file or directory
    #include "stm32f10x_conf.h"
Blinky.c: 0 warnings, 1 error
compiling Buttons_MCBSTM32E.c...

这个错误非常明确:编译器找不到 stm32f10x_conf.h 文件。这是 STM32 标准外设库(SPL)的核心配置文件,示例工程依赖它来启用/关闭各种外设。

别担心,这是 Keil 导入旧版 Pack 示例时的常见问题。

  1. 方式一:将该文件(文件可以用 Everything 搜一下就可以了,一般默认放在 \Packs\Keil\STM32F1xx_DFP\2.4.1\Device\Include)复制到 复制 到工程根目录(即和 Blinky.uvprojx 同级的文件夹)。

    原理:Keil 默认会将工程根目录加入头文件搜索路径。文件放这儿,编译器立刻就能找到

  2. 方式二:在 Keil 中添加头文件路径(更规范)

  3. 重新编译:点击 Keil 的 Clean(垃圾桶图标)→ 再点击 Rebuild(F7)。

错误 2:未定义符号

error:  #20: identifier "LED_PORT" is undefined

解决

  • 检查是否安装了正确的 Pack
  • Pack Installer → 安装 STM32F1xx_DFP

错误 3:代码大小超限

Error: L6406E: No space in execution regions

解决

  • MDK-Lite 版本限制 32KB
  • 使用教育授权或商业版

5. 烧录程序到开发板

经过前面的步骤,我们已经得到了机器中识别的执行文件.axf。并且工程也已经配置了对应的烧录器及芯片,此时先连接烧录器到开发板上,点击"Project"->“Optinos for Target ‘xxx’”->“Debug”->"Setting"查看当前是否已正常连接。如果已正常连接,点击,可以看到左下方有个烧录的进度条。

烧录程序

方法 1:工具栏按钮

  • 点击 Load 按钮(向下箭头⬇️图标)

方法 2:快捷键

  • Ctrl + F8

方法 3:菜单

  • Flash → Download

此时底部窗口会显示:

image-20260412111747547

成功标志Verify OK

烧录失败排查

问题 1:No Target Connected

Error: Flash Download failed - No Target Connected

解决

  • 检查接线
  • 检查开发板供电(3.3V LED 是否亮)
  • Options → Debug → Settings → 测试 SWD 连接

问题 2:Flash Algorithm 缺失

Error: Flash Download failed - Target DLL has been cancelled

解决

  • Options → Debug → Settings → Flash Download
  • 点击 Add 添加正确的 Flash 算法
  • 选择 STM32F10x Medium Density Flash

成功烧录之后显示的结果

c09ccbff85947aaa92471997650e6cc0

烧录程序 FlyMcu(mcuisp)

通过串口下载程序

FlyMcu 通过 ISP 烧录与调试器“直接烧录”的最终结果完全一样(都是把 HEX 里的机器码写入 MCU 的 Flash),但实现路径、硬件依赖、速度、功能边界有显著差异。下面按维度对比:

核心区别对比

对比维度FlyMcu + ISP(串口烧录)调试器“直接烧录”(SWD/JTAG)
通信接口UART(TX/RX)SWD 或 JTAG 调试接口
协议/通道依赖芯片出厂固化在 ROM 的 Bootloader调试器通过 CoreSight 架构直接访问 Flash 控制器,绕过 Bootloader
硬件依赖USB 转 TTL 模块(CH340/CP2102 等)ST-Link / J-Link / DAP-Link 等仿真器
引脚要求需配置 BOOT0=1, BOOT1=0(以 STM32F1 为例),使用特定串口引脚仅需 SWDIO、SWCLK、GND、3.3V不受 BOOT 引脚影响
烧录速度受限于串口波特率(通常 115.2k~921.6k),几十 KB 需数秒~十秒级SWD 有效速率可达数 MHz,通常 1~3 秒完成
功能支持仅支持擦除、烧录、校验、读 Flash支持全功能调试、断点、内存读写、Option Bytes 配置、读保护管理、半主机等
读保护影响若芯片已开启读保护(RDP L1),ISP 通常直接失败调试器可检测保护状态,支持执行整片擦除解除(需确认是否允许)
适用场景量产烧录、现场固件升级、无调试器的简易开发板日常开发调试、快速迭代、需要在线 Debug 的项目

本质相同点

  • 写入内容完全一致:HEX 只是 Intel 格式的文本载体,最终都会被转换成二进制机器码写入相同的 Flash 地址。程序运行效果没有任何区别。
  • 都不改变硬件设计:只要引脚正确、供电稳定,两种方法写入后 MCU 的行为完全一样。

(1)打开 FlyMcu.exe 如图所示

image-20260413220217258

(2)用数据线连接 EBD-A23 开发板的 USB 口,点击搜索串口,再从 Port 菜单中选择对应的 端口号(可从计算机的设备管理器中获知正确的端口号),如图上的 COM14。

(3)从工程文件夹中,找到对应的 hex 文件,点击打开,如图下所示。

image-20260413220345251

(4)接着选择 STMISP 项,设置如上所示

(5)点击开始编程,则系统监测串口,等待芯片连接信号,如下所示,

image-20260413220428123

(6)在开发板上按住 ISP 按键后(BOOT0 高电位,进入 ISP 模式启动),再按 RESET 按键,释 放 RESET 键后再释放 ISP 键即可将 hex 文件下载到开发板上,如图下所示。可以从开发板 上观察程序运行现象。

image-20260413220415367


6. 运行和调试

方式 1:直接运行(最简单)

  1. 烧录成功后,拔掉 CMSIS-DAP
  2. 给开发板单独供电(5V 或 3.3V)
  3. 观察 LED 闪烁(通常 PC13 引脚)

方式 2:调试运行(推荐学习)

步骤 1:进入调试模式

  • 点击工具栏的 Start/Stop Debug Session 按钮(🐞 图标)

  • 或按 Ctrl + F5

    退出调试界面非常简单,再次按下 Ctrl + F5 即可(该快捷键是“进入/退出调试”的切换开关)。

    🖱️ 鼠标操作方式

    1. 顶部工具栏按钮:点击那个 带红色叉号的调试图标(鼠标悬停会显示 Start/Stop Debug Session)。

      (注:实际图标为红色方块或带斜杠的虫子)

    2. 菜单栏:点击 DebugStart/Stop Debug Session

    💡 退出后的状态说明

    项目说明
    界面变化自动切回普通的代码编辑视图,底部 Registers/Watch 等调试窗口关闭
    芯片状态MCU 不会复位,会继续独立运行你之前烧录的程序(只要不断电)
    代码修改退出后可直接编辑代码,下次编译会自动覆盖旧程序
    按钮变灰如果按钮呈灰色不可点,说明已退出调试或连接已断开,无需额外操作

步骤 2:调试界面介绍

image-20260412120642807

  1. Disassembly - 反汇编窗口(可关闭)
  2. Watch - 变量观察窗口
  3. Call Stack + Locals - 调用栈和局部变量
  4. Peripherals - 外设寄存器

界面乱了想恢复到原来的样子怎么办,如下:

image-20260412120543922

效果:所有窗口会恢复到 Keil 默认布局,包括 Watch、Registers、Memory 等调试窗口

步骤 3:常用调试操作

操作快捷键说明
单步跳过F10执行当前行,不进入函数
单步进入F11进入函数内部
跳出函数Ctrl+F11执行完当前函数返回
全速运行F5运行到下一个断点
设置断点Ctrl+B在代码行左侧点击
停止调试Ctrl+F5退出调试模式

步骤 4:观察 LED 控制

  1. Blinky.cLED_On() 处设置断点(点击行号左侧)
  2. F5 运行
  3. 程序会在断点处暂停
  4. 查看 Peripherals 窗口:
    • 展开 GPIOC
    • 观察 ODR 寄存器变化
  5. F5 继续,观察 LED 状态

五、清除 STM32 已烧录程序

当你发现板子没烧录就有灯亮,说明芯片里已经有程序在运行了。以下是几种清除方法:

方法 1:使用 Keil 全片擦除(最简单)

步骤:

  1. 确保调试器连接正常

    • 魔术棒 → Debug → 选择你的调试器(CMSIS-DAP)
    • 点击 Settings → 确认能看到芯片信息
  2. 执行全片擦除

    • 点击工具栏的 Erase 按钮(橡皮擦图标 🧹)

    • 或者:Flash → Erase 菜单

      image-20260412114102877

  3. 观察输出窗口

    Batch-Build summary: 0 succeeded, 0 failed, 3 skipped - Time Elapsed: 00:00:00
    Full Chip Erase Done.
    Flash Erase finished 11:40:38
    
  4. 验证

    • 擦除后,板子上的 LED 应该会熄灭状态改变
    • 因为 Flash 全为 0xFF,程序无法正常运行

方法 2:使用 STM32CubeProgrammer(推荐,功能最强)

从 ST 官网免费下载:

https://www.st.com/en/development-tools/stm32cubeprog.html

擦除步骤

  1. 打开 STM32CubeProgrammer

  2. 选择连接方式

    • 右侧选择CMSIS-DAP
    • 点击 Connect
  3. 全片擦除

    • 顶部菜单点击 Erasing & Programming
    • 点击 Full chip erase
    • 等待完成
  4. 验证

    • Memory Editor 查看 Flash 区域,应该全是 FF

六、ISP 和 RST 按钮

这两个按钮是 STM32 开发板上最常用的物理按键,理解它们能让你轻松解决 90% 的"烧录失败"和"程序不跑"问题。


1. RST 按钮(Reset / NRST)

我的数码管不亮灯就是因为我没按这个,没招了

作用:硬件复位,让芯片"重启"

工作原理:

按下 RST → NRST 引脚被拉低 → 芯片内部复位电路触发
    ↓
1. CPU 寄存器清零
2. 程序计数器 PC = 0x00000000
3. 重新执行启动文件 (startup_stm32f10x.s)
4. 跳转到 main() 函数

常见使用场景:

场景操作效果
程序跑飞/死机按一下 RST芯片重启,程序从头执行
烧录后不运行烧录完成 → 按 RST让新程序立即生效
调试时重置状态Debug 模式下按 RST清除所有变量/寄存器状态
切换启动模式后改完 BOOT 跳线 → 按 RST让新启动配置生效

小技巧:

  • 按住复位键烧录:如果程序禁用了 SWD 引脚导致无法连接,可以按住 RST → 点烧录 → 1 秒后松开,能"抢"在程序运行前完成烧录。

2. ISP 按钮(In-System Programming)

作用:切换启动模式,让芯片进入"系统存储器启动"(用于串口下载)

核心原理:STM32 的三种启动模式

STM32F103 通过 BOOT0BOOT1 两个引脚的电平决定启动方式:

BOOT1BOOT0启动模式用途
00Main Flash Memory正常运行用户程序(默认)
01System Memory 🔧ISP 模式,用于串口下载
10SRAM 🧪调试用,断电程序丢失
11保留不建议使用

ISP 按钮的典型电路:

        3.3V
          │
         10kΩ (上拉电阻)
          │
    BOOT0 ─┼─────┐
          │     │
         [ISP]  │   ← 按下时 BOOT0 = 0 (接地)
          │     │
         GND   100nF (滤波电容)

⚠️ 注意:不同板子设计可能相反!有些板子 按下 ISP = BOOT0=1(通过上拉),请以原理图为准。

3. ISP 按钮的使用流程(串口下载专用)

如果调试器坏了,或者想用串口(USART1)直接烧录,就需要用到 ISP 按钮:

步骤 1:硬件准备

开发板          USB转TTL模块
─────           ───────────
3.3V    →       3.3V
GND     →       GND
PA9(TX) →       RX
PA10(RX)→       TX

步骤 2:进入 ISP 模式

1. 断电
2. 按住 [ISP] 按钮不放
3. 按住 [RST] 按钮 → 松开 → 再松开 [ISP]
   (此时 BOOT0=1, BOOT1=0,芯片进入系统存储器启动)

步骤 3:用工具烧录

  • 打开 FlyMcuSTM32CubeProgrammersscom + XMODEM
  • 选择正确 COM 口,波特率 115200
  • 加载 .hex 文件 → 点击"开始编程"

步骤 4:恢复正常运行

1. 烧录完成
2. 断电
3. 松开 [ISP] 按钮(BOOT0 恢复为 0)
4. 按一下 [RST] 重启
5. 程序开始运行!✅

4. 常见问题排查

问题 1:按了 RST 程序还是不跑

可能原因

  • 供电不稳 → 检查 3.3V LED 是否常亮
  • 复位电路故障 → 用万用表测 NRST 引脚,按下时应≈0V,松开≈3.3V
  • 程序本身有死循环 → 用调试器单步跟踪

问题 2:按 ISP + RST 后串口没反应

排查步骤

  1. 确认 BOOT0/BOOT1 电平(万用表测):
    • ISP 按下时:BOOT0 应为 1(或 0,依设计而定)
    • BOOT1 应始终为 0
  2. 确认串口接线:TX↔RX 交叉,共地
  3. 尝试不同波特率:9600 / 115200 / 57600
  4. 用 FlyMcu 的"清除芯片"功能先擦除

问题 3:烧录后必须按 RST 才运行

正常现象
因为烧录完成后芯片停在"编程状态",按 RST 才会跳转到用户程序入口

★,°:.☆( ̄▽ ̄)/$:.°★ 】那么本篇到此就结束啦,如果有不懂 和 发现问题的小伙伴可以在评论区说出来哦,请持续关注我 !!

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐