【正点原子STM32】新建HAL库版本MDK工程

一、新建工程前的准备工作
二、新建HAL库版本MDK工程步骤

  • 2.1、新建工程文件夹
  • 2.2、新建一个工程框架
  • 2.3、添加文件
  • 2.4、魔术棒设置
  • 2.5、添加 main.c,并编写代码

三、下载验证
四、总结

一、新建工程前的准备工作

1、下载相关STM32Cube 官方固件包(F1/F4/F7/H7)

STM32Cube官网

路径:战舰 V4资料:资料→8,STM32 参考资料→1,STM32CubeXX固件包
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、搭建开发环境:

请参考 搭建开发环境

二、新建HAL库版本MDK工程步骤

新建工程文件夹分为 2 个步骤:1,新建工程文件夹;2,拷贝工程相关文件。
【正点原子STM32】新建HAL库版本MDK工程_第1张图片

2.1、新建工程文件夹

【正点原子STM32】新建HAL库版本MDK工程_第2张图片
这是一个典型的STM32工程的目录结构,按照这样的结构可以更好地组织项目文件,使得代码清晰有序,方便团队协作和后期维护。这样的划分主要是基于不同类型的文件和功能进行分类。一般来说:

  • Drivers 文件夹存放芯片厂商提供的驱动文件,这里可能包括 STM32 提供的 HAL 库、LL 库等。
  • Middlewares 文件夹存放一些中间件组件,这可能包括正点原子提供的中间层组件,或者其他第三方中间件。
  • Output 文件夹用于存放编译输出的文件,比如生成的可执行文件、库文件等。
  • Projects 文件夹是专门用于存放MDK工程文件的,这样可以将不同类型的文件分开,方便维护。
  • User 文件夹通常存放用户自定义的文件,包括 main.c 主程序文件、中断处理文件等。

这样的结构在大型嵌入式项目中是比较常见的,有助于保持项目的整洁和有序。
【正点原子STM32】新建HAL库版本MDK工程_第3张图片

拷贝/新建工程相关文件

【正点原子STM32】新建HAL库版本MDK工程_第4张图片
【正点原子STM32】新建HAL库版本MDK工程_第5张图片
   BSP 文件夹,用于存放正点原子提供的板级支持包驱动代码(原 HARDWARE 文件夹下),如:LED、蜂鸣器、按键等。本章我们暂时用不到该文件夹,不过可以先建好备用。
   SYSTEM 文件夹,用于存放正点原子提供的系统级核心驱动代码,sys.c/h,usart.c/h,delay.c/h,方便大家快速搭建自己的工程。该文件同样可以从“A 盘→4,程序源码→2,标准例程-HAL 库版本”文件夹里面的任何一个实验的 Drivers 文件夹里面拷贝过来。
   CMSIS 文件夹,用于存放 CMSIS 底层代码(ARM 和 ST 提供),如:启动文件(.s 文件)、stm32f1xx.h 等各种头文件。该文件夹我们可以直接从 STM32CubeF1 固件包(路径:A 盘→8,STM32 参考资料→1,STM32CubeF1 固件包)里面拷贝,CMSIS 的文件夹路径在“STM32CubeF1固件包→Drivers”。由于这个文件夹原来设计是用于匹配全部 F1 系列的芯片的,导致非常大,部分文件对我们的例程来说不会使用到,而且浪费磁盘的存储空间,所以我们会对这个文件夹进行精简:打开目录“CMSIS\Device\ ST\STM32F1xx”,其中的 Include 文件夹里都是芯片的头文件我们只留下如下图 这三个头文件,其他删除。
【正点原子STM32】新建HAL库版本MDK工程_第6张图片
Source 文件夹下的 Templates 文件夹留下
【正点原子STM32】新建HAL库版本MDK工程_第7张图片
arm 文件夹存放的是启动文件,我们只需要 startup_stm32f103xe.s,其他全部删除。
【正点原子STM32】新建HAL库版本MDK工程_第8张图片
最后就是 CMSIS 文件夹下的 Include 文件夹,里面都是内核的头文件,我们只需要
【正点原子STM32】新建HAL库版本MDK工程_第9张图片
  到这里 CMSIS 文件夹就处理完成了。精简后的 CMSIS 文件夹大家也可以在“A 盘→4,程序源码→2,标准例程-HAL 版本”文件夹里面的任何一个实验的 Drivers 文件夹里面拷贝过来。
  STM32F1xx_HAL_Driver 文件夹,用于存放 ST 提供的 F1xx HAL 库驱动代码。该文件夹我们可以直接从 STM32CubeF1 固件包里面拷贝。直接拷贝“STM32CubeF1 固件包→Drivers”路径下的 “STM32F1xx_HAL_Driver”文件夹到我们工程的 Drivers 下。该文件夹目录最终如下图 的内容。
在这里插入图片描述
  到这里,我们就完成了把官方固件包中必要的驱动文件添加到我们工程文件中。
最终我们新建的 Drivers 文件夹目录下的文件构成如图
【正点原子STM32】新建HAL库版本MDK工程_第10张图片
  Middlewares 文件夹
  Middlewares 文件夹用于存放正点原子提供的中间层组件文件和第三方中间层文件,比如:USMART、MALLOC、TEXT、FATFS、USB、LWIP、各种 OS、各种 GUI 等等。我们新建工程实验暂时用不到,留空就行,后面的实验将会陆续添加各种文件。
  Output 文件夹
  Output 文件夹用于存放编译器编译工程输出的中间文件,比如:.hex、.bin、.o 文件等。这里不需要操作,后面只需要在 MDK 里面设置该文件夹为编译输出文件的存放文件夹就行。
  Projects 文件夹
  Projects 文件夹用于存放 MDK 工程,因为我们的工程是基于 ARM,所以我们在 Projects文件夹里面新建一个命名为 MDK-ARM 的文件夹,用于存放 MDK 的工程文件,如图 所示。
在这里插入图片描述
  User 文件夹
  User 文件夹用于存放 HAL 库用户配置文件、main.c、中断处理文件,以及配置文件stm32f1xx_hal_conf.h。我们首先从官方固件包里面直接拷贝官方的模板工程下的 HAL 库用户配置文件和中断处理文件到我们的 User 文件夹里。官方的模板工程路径:STM32Cube_FW_F1_V1.8.0\Projects\STM3210E_EVAL\Templates,打开 Template_Project 文件夹,如图
【正点原子STM32】新建HAL库版本MDK工程_第11张图片
  我们需要的文件就在 Inc 和 Src 文件夹里面,在这两个文件夹里面找到:stm32f1xx_it.c、stm32f1xx_it.h、stm32f1xx_hal_conf.h 这三个文件,并且拷贝到我们的 User 文件夹下。
  main.c 文件我们也是放在 User 文件夹下,后面在 MDK 里面教大家新建.c 文件并保存。User 文件夹最终构成图如图
【正点原子STM32】新建HAL库版本MDK工程_第12张图片

2.2、新建一个工程框架

在这里插入图片描述
列出了一些新建工程框架的基本步骤和文件夹结构,这些步骤主要针对 Keil μVision 软件进行 STM32 工程的创建。

下面是详细的步骤来新建一个 STM32 工程。这里以 Keil μVision 为例:

  1. 新建工程:

    • 打开 Keil μVision 软件。
    • 选择 “Project” 菜单,点击 “New Project”。
    • 在 “Create New Project” 对话框中,选择项目的保存路径和文件名,点击 “Save”。
  2. 选择主控型号:

    • 在 “Select Device for Target” 对话框中,选择你的 STM32 主控型号。
      • 可以使用搜索框输入型号,选择对应的供应商和系列,再选择具体型号。
    • 点击 “OK”。
  3. 配置目标选项:

    • 在主界面左下角的 “Project” 窗口中,右键点击 “Target 1”,选择 “Options for Target ‘Target 1’”。
    • 在 “Target” 对话框中,可以设置一些编译和调试的选项。
    • 点击 “OK”。
  4. 添加源文件:

    • 在 “Project” 窗口中,右键点击 “Source Group 1”(通常是 “Source” 或 “Source Group 1”),选择 “Add New Item to Group ‘Source Group 1’”。
    • 在 “Select ‘Add New Item’ Dialog” 中,选择 “C File (.c)” 或 “C++ File (.cpp)”,输入文件名,点击 “Add”。
    • 在新创建的文件中编写你的代码。
  5. 配置系统文件和驱动文件:

    • 在 “Project” 窗口中,右键点击 “Target 1”,选择 “Options for Target ‘Target 1’”。
    • 在 “C/C++” 选项卡中,添加你的头文件路径(例如,CMSIS 和 HAL 库的路径)。
    • 在 “Linker” 选项卡中,添加库文件路径和链接相关的设置。
    • 点击 “OK”。
  6. 构建工程:

    • 在工具栏中点击 “Build” 按钮或者按下快捷键(一般是 F7)来构建工程。
  7. 下载和调试:

    • 连接你的 STM32 开发板到电脑上。
    • 在工具栏中点击 “Flash” 按钮或者按下快捷键(一般是 F8)来下载程序到目标芯片。
    • 在 “Debug” 菜单中选择 “Start/Stop Debug Session” 来启动调试器。

这就是一个基本的 STM32 工程的创建和配置流程。具体的步骤可能会有细微差别,具体取决于你使用的工具链和硬件。

新建工程

在这里插入图片描述
【正点原子STM32】新建HAL库版本MDK工程_第13张图片

选择主控型号

  接下来会弹出一个选择 Device 的界面,就是选择我们的芯片设备型号,大家根据自己使用的芯片型号依次选择即可。STM32F103 战舰开发板的芯片型号是:STM32F103ZET6,所以我们选择:STMicroelectronics→STM32F1 Series→STM32F103→STM32F103ZE(如果使用的是其他芯片,选择相应的型号就可以了),如图
在这里插入图片描述
【正点原子STM32】新建HAL库版本MDK工程_第14张图片
特别注意:一定要安装对应的器件支持包(即 pack 包)才会显示这些内容哦,如果没得选择,请关闭 MDK,然后安装光盘:6,软件资料\1,软件\MDK5\ Keil.STM32F1xx_DFP.2.3.0 这个安装包后重试。
【正点原子STM32】新建HAL库版本MDK工程_第15张图片
  编译过程产生的链接列表、调试信息、预览、lib 等文件,统称为中间文件。为了统一管理,方便使用,我们会把输出在 Listings 和 Objects 文件夹的内容,统一改为输出到 Output 文件夹(通过魔术棒设置),我们先把 MDK 自动生成的这两个文件夹(Listings 和 Objects)删除。
在这里插入图片描述

2.3、添加文件

【正点原子STM32】新建HAL库版本MDK工程_第16张图片

1.设置工程名和分组名

【正点原子STM32】新建HAL库版本MDK工程_第17张图片
  在工程管理界面,我们可以执行设置工程名字(Project Targets)、分组名字(Groups)以及添加每个分组的文件(Files)等操作。我们设置工程名字为:Template,并设置五个分组:Startup(存放启动文件)、User(存放 main.c 等用户代码)、Drivers/SYSTEM(存放系统级驱动代码)、Drivers/STM32F1xx_HAL_Driver(存放 ST 提供的 HAL 库驱动代码)、Readme(存放工程说明文件),如图
【正点原子STM32】新建HAL库版本MDK工程_第18张图片
  设置好之后,我们点击 OK,回到 MDK 主界面,可以看到我们设置的工程名和分组名如图
【正点原子STM32】新建HAL库版本MDK工程_第19张图片
  这里我们只是新建了一个简单的工程,并没有添加 BSP、Middlewares 等分组,后面随着工程复杂程度的增加,我们需要一步步添加对应的分组。

  注意:为了让工程结构清晰,我们会尽量让 MDK 的工程分组和我们前面新建的工程文件夹对应起来,由于 MDK 分组不支持多级目录,因此我们将路径也带入分组命名里面,以便区分。如:User 分组对应 User 文件夹里面的源码,Drivers/SYSTEM 分组,对应 Drivers/SYSTEM文件夹里面的源码,Drivers/STM32F1xx_HAL_Driver 分组对应 Drivers/STM32F1xx_HAL_Driver文件夹里面的源码等。

2.添加启动文件

  启动文件(.s 文件)包含 STM32 的启动代码,其主要作用包括:1、堆栈(SP)的初始化;2、初始化程序计数器(PC);3、设置向量表异常事件的入口地址;4、调用 main 函数等,是每个工程必不可少的一个文件,我们在本书第九章会有详细介绍。
  该文件由 ST 官方提供,对于 STM32F103 来说有 4 个启动文件可选,如表

启动文件 对应 FLASH 容量 说明
startup_stm32f103x6.s Flash≤32KB 用于小容量 F103 系列芯片的启动文件
startup_stm32f103xb.s 64KB≤Flash≤128KB 用于中容量 F103 系列芯片的启动文件
startup_stm32f103xe.s 256KB≤Flash≤512KB 用于大容量 F103 系列芯片的启动文件
startup_stm32f103xg.s 768KB≤Flash≤1024KB 用于超大容量 F103 系列芯片的启动文件

  启动文件存放的位置在前面也有所说明,因为我们开发板使用的是 STM32F103ZET6,对应的启动文件为:startup_stm32f103xe.s。
  关于启动文件的说明,我们就介绍这么多,接下来我们看如何添加启动文件到工程里面。我们有两种方法给 MDK 的分组添加文件:1,双击 Project 下的分组名添加。2,进入工程管理界面添加。
 这里我们使用方法 1 添加(路径:实验 0-3,新建工程实验-HAL 库版本\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\arm),如图:
【正点原子STM32】新建HAL库版本MDK工程_第20张图片
【正点原子STM32】新建HAL库版本MDK工程_第21张图片

3. 添加 User 源码

【正点原子STM32】新建HAL库版本MDK工程_第22张图片
注意:这些源码都是在前面 小节的第二步拷贝过来的,如果之前没拷贝,是找不到这些源码的。添加完成后,如图
【正点原子STM32】新建HAL库版本MDK工程_第23张图片

4. 添加 SYSTEM 源码

【正点原子STM32】新建HAL库版本MDK工程_第24张图片
【正点原子STM32】新建HAL库版本MDK工程_第25张图片

5. 添加 STM32F1xx_HAL_Driver 源码

  接下来我们往 Drivers/STM32F1xx_HAL_Driver 分组里添加文件,这里的操作跟前面添加SYSTEM 源码一样的。进入工程管理界面,选中 Drivers/STM32F1xx_HAL_Driver分 组 , 然 后 点 击 : Add Files , 进 入 文 件 添 加 对 话 框 , 依 次 添 加 stm32f1xx_hal.c 、stm32f1xx_hal_cortex.c、stm32f1xx_hal_dma.c、stm32f1xx_hal_gpio.c、stm32f1xx_hal_gpio_ex.c、
stm32f1xx_hal_rcc.c、stm32f1xx_hal_rcc_ex.c、stm32f1xx_hal_uart.c 和 stm32f1xx_hal_usart.c 到该分组下,如图所示:
【正点原子STM32】新建HAL库版本MDK工程_第26张图片
【正点原子STM32】新建HAL库版本MDK工程_第27张图片
  可以看到分组中有些.c 文件有个小钥匙的符号,这是因为官方的固件包的文件设置了只读权限,我们取消只读权限就好了,方法如图所示。
【正点原子STM32】新建HAL库版本MDK工程_第28张图片

2.4、魔术棒设置

在这里插入图片描述

  1. 设置 Target 选项卡
    【正点原子STM32】新建HAL库版本MDK工程_第29张图片
      我们设置芯片所使用的外部晶振频率为 8Mhz,选择 ARM Compiler 版本为:Use default compiler version 5(即 AC5 编译器)。

AC5和AC6编译器对比

【正点原子STM32】新建HAL库版本MDK工程_第30张图片

  1. 设置 Output 选项卡
    【正点原子STM32】新建HAL库版本MDK工程_第31张图片
      注意,我们勾选:Browse Information,用于输出浏览信息,这样就可以使用 go to definition查看函数/变量的定义,对我们后续调试代码比较有帮助,如果不需要调试代码,则可以去掉这个勾选,以提高编译速度。
  2. 设置 Listing 选项卡
    【正点原子STM32】新建HAL库版本MDK工程_第32张图片
      经过 Output 和 Listing 这两步设置,原来存储在 Objects 和 Listings 文件夹的内容(中间文件)就都改为输出到 Output 文件夹了。
  3. 设置 C/C++选项卡
    【正点原子STM32】新建HAL库版本MDK工程_第33张图片
     &emsp在②处设置了全局宏定义:USE_HAL_DRIVERSTM32F103xE,他们之间是用英文逗号隔开的。添加全局宏定义标识符,在工程中任何地方都可见,在 stm32f1xx.h 里面会用到该宏定义。
     &emsp在③处设置了优化等级为-O0,可以得到最好的调试效果,当然为了提高优化效果提升性能
    并降低代码量,可以设置-O1~-O3,数字越大效果越明显,不过也越容易出问题。注意:当使用AC6 编译器的时候,这里推荐默认使用-O1 优化。
      在④处勾选 C99 模式,即使用 C99 C 语言标准。
      在⑤处,我们可以进行头文件包含路径设置,点击此按钮,进行如图所示设置:
    【正点原子STM32】新建HAL库版本MDK工程_第34张图片
      上图中我们设置了 5 个头文件包含路径,其中 4 个在 Drivers 文件夹下,一个在 User 文件夹下。为避免频繁设置头文件包含路径,正点原子最新源码的 include 全部使用相对路径,也就是我们只需要在头文件包含路径里面指定一个文件夹,那么该文件夹下的其他文件夹里面的源码,如果全部是使用相对路径,则无需再设置头文件包含路径了,直接在 include 里面就指明了头文件所在。
      关于相对路径,这里大家记住 3 点:
      1,默认路径就是指 MDK 工程所在的路径,即.uvprojx 文件所在路径(文件夹)
      2,“./”表示当前目录(相对当前路径,也可以写做“.\”)
      3,“…/”表示当前目录的上一层目录(也可以写做“…\”)
      举例来说,上图中:…\Drivers\CMSIS\Device\ST\STM32F1xx\Include,前面两个“…\”,表示 Drivers 文件夹在当前 MDK 工程所在文件夹(MDK-ARM)的上 2 级目录下,具体解释如图所示:
    【正点原子STM32】新建HAL库版本MDK工程_第35张图片

  上图表示根据头文件包含路径:…\Drivers\CMSIS\Device\ST\STM32F1xx\Include,编译器可以找到⑥处所包含的这些头文件,即代码里面可以直接 include 这些头文件使用。
  再举个例子,在完成如图 6.1.4.5 所示的头文件包含路径设置以后,我们在代码里面编写:
#include “./SYSTEM/sys/sys.h”
  即表示当前头文件包含路径所指示的 4 个文件夹里面,肯定有某一个文件夹包含了:
SYSTEM/sys/sys.h 的路径,实际上就是在 Drivers 文件夹下面,两者结合起来就相当于:
#include “…/…/Drivers/SYSTEM/sys/sys.h”
  这就是相对路径。它既可以减少头文件包含路径设置(即减少 MDK 配置步骤,免去频繁
设置头文件包含路径的麻烦),同时又可以很方便的知道头文件具体在那个文件夹,因此我们推
荐在编写代码的时候使用相对路径

最后,我们如果使用 AC6 编译器,则在图 6.1.4.4 的 Misc Controls 处需要设置:-Wnoinvalid-source-encoding,避免中文编码报错,如果使用 AC5 编译器,则不需要该设置!!

绝对路径和相对路径对比

在这里插入图片描述
绝对路径和相对路径是计算机领域中用于指定文件或目录位置的两种不同方式。

绝对路径:
  • 定义: 绝对路径是指文件或目录从根目录开始一直到目标位置的完整路径。
  • 示例: C:\Users\YourUsername\Documents\Project\file.txt (Windows 系统)
  • 特点: 绝对路径是唯一确定文件或目录位置的一种方式,不受当前工作目录的影响。
相对路径:
  • 定义: 相对路径是指文件或目录相对于当前工作目录或另一文件的位置。
  • 示例:
    • ./folder/file.txt 表示当前目录下的 folder 目录中的 file.txt
    • ../parentfolder/file.txt 表示当前目录的上一级目录中的 parentfolder 目录中的 file.txt
  • 特点: 相对路径是相对于当前环境而言的,可能会受到工作目录的变化而影响。
适用场景:
  • 绝对路径: 适用于需要确切指定文件或目录位置的场景,路径的唯一性是必要的。
  • 相对路径: 适用于在特定环境中,通过相对位置来定位文件或目录,便于移植和共享。
补充说明:
  1. 在命令行或脚本中,当前工作目录的设置可能会影响相对路径的解析。
  2. 在不同操作系统中,路径分隔符可能不同,例如在 Windows 使用 \,而在 Unix/Linux 使用 /

在 MDK 工程中,相对路径通常指的是相对于工程文件(.uvprojx 文件)所在的目录。

USE_HAL_DRIVER 和 STM32F103xE 宏定义

用于在项目中引入不同的头文件,以适配不同的硬件平台。

  1. USE_HAL_DRIVER 宏定义:
    • 该宏定义用于标识是否使用HAL库(Hardware Abstraction Layer)。如果定义了该宏,就会包含 stm32f1xx_hal.h 头文件,从而启用HAL库相关的功能。
    • 如果不使用HAL库,可以在项目中不定义该宏,避免引入不必要的库和功能。
#if defined (USE_HAL_DRIVER)
   #include "stm32f1xx_hal.h"
#endif   /* USE_HAL_DRIVER */
  1. STM32F103xE 宏定义:
    • 该宏定义用于选择特定的STM32F1系列芯片型号,即 STM32F103xE。根据不同的型号,会包含不同的头文件。
    • 在条件编译中,如果定义了 STM32F103xE,则会包含 stm32f103xe.h 头文件。
#if defined (STM32F100xB)
#elif defined (STM32F103xE)
   #include "stm32f103xe.h"
#endif

在实际项目中,通过在编译器选项或源代码中定义这些宏,可以方便地适配不同的硬件平台和库。这种方式可以使项目更具有可移植性,方便在不同的STM32系列芯片上进行开发。
【正点原子STM32】新建HAL库版本MDK工程_第36张图片
【正点原子STM32】新建HAL库版本MDK工程_第37张图片
5. 设置 Debug 选项卡
在这里插入图片描述
  图中,我们选择使用:CMSIS-DAP 仿真器,使用 SW 模式,并设置最大时钟频率为 10Mhz,以得到最高下载速度。当我们将仿真器和开发板连接好,并给开发板供电以后,仿真器就会找到开发板芯片,并在 SW Device 窗口显示芯片的 IDCODEDevice Name 等信息(图中⑤处),当无法找到时,请检查供电和仿真器连接状况。
6. 设置 Utilities 选项卡
【正点原子STM32】新建HAL库版本MDK工程_第38张图片
  图中⑥处下载算法,是 MDK 默认添加的,针对 STM32F10x 大容量系列产品(FLASH 容量在 256KB~512KB 之间)。一般我们用这个即可。如果⑥处没有下载算法,则点击⑦处按钮,执行添加一下下载算法即可(名字和⑥处的算法名字一样)。
7. Linker 选项卡(可选)
添加外部FLASH的 没有不用设置
添加分散加载文件

在这里插入图片描述
在这里插入图片描述
【正点原子STM32】新建HAL库版本MDK工程_第39张图片
在 Keil MDK(Microcontroller Development Kit)中,Linker选项卡用于配置链接器的设置,其中包括添加分散加载文件(Scatter File)的步骤。分散加载文件指定了程序在存储器中的布局。

以下是添加分散加载文件的一般步骤:

  1. 打开 Keil MDK 工程。

  2. 在工程管理器中,找到 “Project” 菜单,然后选择 “Options for Target”。

  3. 在弹出的对话框中,选择 “Linker” 选项卡。

  4. 在 “Scatter File” 一栏中,可以选择 “Browse” 按钮,或者手动输入分散加载文件的路径。

    • 如果选择 “Browse”,会弹出一个文件选择对话框,你可以在其中选择分散加载文件。

    • 如果手动输入路径,确保路径是相对于工程文件的相对路径或者是绝对路径。

  5. 选择完分散加载文件后,点击 “OK” 保存设置。

  6. 最后,点击 “Rebuild” 或 “Build” 来重新构建工程,使得新的链接设置生效。

分散加载文件(Scatter File)通常以 .sct.ld 为扩展名。在这个文件中,你可以定义存储器区域(Memory Regions)、存储器块(Memory Blocks)等,从而确定程序的存储布局。

在 Keil MDK 中使用分散加载文件可以更灵活地控制代码和数据的存放位置,适应不同的硬件平台和应用需求。

分散加载文件(Scatter File)

分散加载文件(Scatter File)寄存器版本和使用 HAL 库版本的工程中可能会有一些差异。这主要是因为这两种工程的初始化和存储器布局可能不同。

在使用寄存器版本的工程中,你可能会直接定义存储器区域(Memory Regions)和存储器块(Memory Blocks),以明确指定程序在存储器中的布局。例如,在 Cortex-M系列微控制器的寄存器版本工程中,你可以使用类似如下的分散加载文件:

LR_IROM1 0x08000000 0x00100000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00100000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00020000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

上述代码定义了加载的Flash存储器区域和RAM存储器区域。

而在使用 HAL 库版本的工程中,HAL 库会提供一个包含了初始化过程的 SystemInit 函数,通常会配置系统时钟等。因此,在分散加载文件中,可能需要调用 SystemInit 函数。这样的文件可能包含以下内容:

LR_IROM1 0x08000000 0x00100000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00100000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00020000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

; Include HAL-specific sections
INCLUDE STM32F1xx_HAL_CORTEX.S
INCLUDE STM32F1xx_HAL_FLASH.S
INCLUDE STM32F1xx_HAL_RCC.S
; ... include other HAL sections as needed

在上述的例子中,STM32F1xx_HAL_CORTEX.SSTM32F1xx_HAL_FLASH.SSTM32F1xx_HAL_RCC.S 是 HAL 库提供的特定部分,用于初始化 Cortex 内核、Flash 存储器和系统时钟等。

总的来说,根据工程的具体需求和使用的库,分散加载文件的内容可能会有所不同。

2.5、添加 main.c,并编写代码

在 MDK 主界面,新建一个 main.c 文件,并保存在 User 文件夹下。然后双击User 分组,弹出添加文件的对话框,将 User 文件夹下的 main.c 文件添加到 User 分组下。得到如图所示的界面:
【正点原子STM32】新建HAL库版本MDK工程_第40张图片
至此,我们就可以开始编写我们自己的代码了。我们在 main.c 文件里面输入如下代码:

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"

void led_init(void); /* LED 初始化函数声明 */

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(GPIOB,GPIO_PIN_5,GPIO_PIN_SET); /* PB5 置 1 */
		HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET); /* PE5 置 0 */
		delay_ms(500);
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET); /* PB5 置 1 */
		HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET); /* PE5 置 0 */
		delay_ms(500);
	}
}

/**
* @brief 初始化 LED 相关 IO 口, 并使能时钟
* @param 无
* @retval 无
*/
void led_init(void)
{
	GPIO_InitTypeDef gpio_initstruct;
	__HAL_RCC_GPIOB_CLK_ENABLE(); /* IO 口 PB 时钟使能 */
	__HAL_RCC_GPIOE_CLK_ENABLE(); /* IO 口 PE 时钟使能 */
	gpio_initstruct.Pin = GPIO_PIN_5; /* LED0 引脚 */
	gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
	gpio_initstruct.Pull = GPIO_PULLUP; /* 上拉 */
	gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
	HAL_GPIO_Init(GPIOB, &gpio_initstruct); /* 初始化 LED0 引脚 */
	gpio_initstruct.Pin = GPIO_PIN_5; /* LED1 引脚 */
	HAL_GPIO_Init(GPIOE, &gpio_initstruct); /* 初始化 LED1 引脚 */
}

  此部分代码,在 A 盘→4,程序源码→1,标准例程-HAL 库版本→ 实验 0 基础入门实验→实验 0-3,新建工程实验-HAL 库版本→User→main.c 里面有,大家可以自己输入,也可以直接拷贝。强烈建议自己输入,以加深对程序的理解和印象!!
  注意,这里的 include 就是使用的相对路径,关于相对路径,请参考前面 C/C++选项卡设置章节进行学习。
  编写完 main.c 以后,我们点击(Rebuild)按钮,编译整个工程,编译结果如图。
【正点原子STM32】新建HAL库版本MDK工程_第41张图片
  我们在 Build Output 下找到第一个错误,双击这个错误信息定位到错误发生的代码位置。如图这个错误说找不到 main.h,因为我们也不需要用到 main.h,双击这个错误会弹出下面的STM32F1xx_it.c 文件对应包含 main.h 的语句。我们只需要把它删除,然后重新编译。
  再次编译,发现还有一处警告,这里是 HAL_IncTick 函数没有声明,如图所示。
【正点原子STM32】新建HAL库版本MDK工程_第42张图片
  因为这个函数是在 STM32F1xx_hal.c 定义了,并且在 STM32F1xx_hal.h 声明了。我们把STM32F1xx_hal.h 包含进来即可。这里还有一个原因是整个工程没有包含 STM32F1xx_hal.h 的语句,我们需要用到它,所以在这里把它包含进来。官方的 main.h 是有包含这个头文件的。我们不用 main.h 文件,我们在 STM32F1xx_it.c 文件刚才删除包含 main.h 的语句的位置,编写包含 STM32F1xx_hal.h 语句,如图所示。
在这里插入图片描述
再进行编译就会发现 0 错误 0 警告,结果如图所示:
【正点原子STM32】新建HAL库版本MDK工程_第43张图片
  编译结果提示:代码总大小(Porgram Size)为:FLASH 占用 5780 字节(Code + RO + RW),SRAM 占用 1928 字节(RW + ZI);并成功创建了 Hex 文件(可执行文件,放在 Output 目录下)。
  另外,我们在 Readme 分组下还没有添加任何文件,由于只是添加一个说明性质的文件(.txt),并不是工程必备文件,因此这里我们就不添加了,开发板光盘的源码我们是有添加的,大家可以去参考一下。
  至此,新建 HAL 库版本 MDK 工程完成。

三、下载验证

  有两种方法可以给 STM32F103 芯片下载代码:1,使用串口下载;2,使用仿真器下载。这里我们以仿真器下载为例,在 MDK 主界面,点击(下载按钮,也可以按键盘快捷键:F8),就可以将代码下载到开发板,如图所示:
【正点原子STM32】新建HAL库版本MDK工程_第44张图片
  上图提示:Application running…,则表示代码下载成功,且开始运行。可以看到 LED0 和LED1 交叉闪烁。

四、总结

【正点原子STM32】新建HAL库版本MDK工程_第45张图片
【正点原子STM32】新建HAL库版本MDK工程_第46张图片

你可能感兴趣的:(STM32,stm32,USE_HAL_DRIVER,STM32F103xE,新建HAL库版本MDK工程步骤,新建工程根目录文件夹,目标选项卡设置,工程文件概述)