本帖最后由 正点原子运营 于 2026-7-24 15:10 编辑
第七章 新建HAL版本MDK工程
1)实验平台:正点原子Mini STM32H562开发板
2)章节摘自【正点原子】STM32H562开发指南 V1.0
3)购买链接: https://detail.tmall.com/item.htm?id=753606659612
4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/stm32/zdyz_stm32h562_mini.html
5)正点原子官方B站:https://space.bilibili.com/394620890
6)正点原子STM32开发板技术交流群:414052738
在前面的章节我们介绍了STM32H5xx官方固件包的一些知识,本章我们将讲解新建HAL库版本的MDK工程的详细步骤。我们把本章新建好的工程放在光盘里,路径:4,程序源码\2,标准例程-HAL库版本\实验0 基础入门实验\实验0-2,新建工程实验-HAL库版本,大家在学习新建工程过程中间遇到一些问题,可以直接打开这个工程,然后对比学习。
本章将分为如下三个小节:
7.1 新建HAL库版本MDK工程
7.2 下载验证
7.3 分散加载文件简介
7.1 新建HAL库版本MDK工程
本节我们将教大家如何新建一个STM32H562的HAL库版本MDK5工程。为了方便大家参考,我们将本节最终新建好的工程模板存放在A盘:4、程序源码\1,标准例程-HAL库版本\实验0 基础入门实验\实验0-2,新建工程实验-HAL库版本,如遇新建工程问题,请打开该实验对比。
整个新建过程比较复杂,我们将其拆分为5个步骤进行讲解,请准备大概2个小时时间,耐心细致的做完!对你后续的学习非常有帮助!
在新建工程之前,首先我们要做如下准备:
1、 STM32Cube官方固件包:我们使用的固件包版本是STM32Cube_FW_H5_V1.0.0,固件包路径:A盘→8,STM32参考资料→1,STM32CubeH5固件包。
2、开发环境搭建:参考本书第三章相关内容。
7.1.1 新建工程文件夹
新建工程文件夹分为2个步骤:1,新建工程文件夹;2,拷贝工程相关文件。
1. 新建工程文件夹
首先我们在桌面新建一个工程根目录文件夹,后续的工程文件都将在这个文件夹里建立,我们把这个文件夹重命名为:实验0-2,新建工程实验-HAL库版本。如图7.1.1.1所示:
图7.1.1.1 新建工程根目录文件夹
为了让工程的文件目录结构更加清晰易懂,我们会在工程根目录文件夹下建立以下几个文件夹,每个文件夹名称及其作用如表7.1.1.1所示:
表7.1.1.1 工程根目录新建文件夹及其作用
新建完成以后,最后得到我们的工程根目录文件夹如图7.1.1.2所示。
图7.1.1.2 工程根目录文件夹
另外我们的工程根文件目录下还有一个名为keilkill.bat的可执行文件,双击便可执行。其作用是删除编译器编译后的无关文件,减少工程占用的内存,方便打包。还有一个名为readme的记事本文件,其作用是介绍本实验的各种信息。
工程根目录及其相关文件夹新建好以后,我们需要拷贝一些工程相关文件过来(主要是在Drivers文件夹里面),以便等下的新建工程需要。
2. 拷贝工程相关文件
接下来,我们按图7.1.1.2的根目录文件夹顺序介绍每个文件夹及其需要拷贝的文件。
Drivers文件夹
该文件夹用于存放与硬件相关的驱动层文件,一般包括如表7.1.1.2所示的三个文件夹:
表7.1.1.2 Drivers包含文件夹
BSP文件夹,用于存放正点原子提供的板级支持包驱动代码,如:LED、蜂鸣器、按键等。本章我们暂时用不到该文件夹,不过可以先建好备用。
CMSIS文件夹,用于存放CMSIS底层代码(ARM和ST提供),如:启动文件(.s文件)、stm32h5xx.h等各种头文件。该文件夹我们可以直接从STM32CubeH5固件包(路径:A盘→8,STM32参考资料→1,STM32CubeH5固件包)里面拷贝,不过由于固件包里面的CMISIS兼容了太多芯片,导致非常大(127多MB),因此我们根据实际情况,对其进行了大幅精简,精简后的CMSIS文件夹大小为2.55MB左右。精简后的CMSIS文件夹大家可以在:A盘→4,程序源码→1,标准例程-HAL库版本 文件夹里面的任何一个实验的Drivers文件夹里面拷贝过来。
SYSTEM文件夹,用于存放正点原子提供的系统级核心驱动代码,如:sys.c、delay.c和usart.c等,方便大家快速搭建自己的工程。该文件同样可以从:A盘→4,程序源码→1,标准例程-HAL库版本 文件夹里面的任何一个实验的Drivers文件夹里面拷贝过来。
STM32H5xx_HAL_Driver文件夹,用于存放ST提供的H5xx HAL库驱动代码。该文件夹我们可以直接从STM32CubeH5固件包里面拷贝。直接拷贝“STM32CubeH5固件包→Drivers”路径下的“STM32H5xx_HAL_Driver”文件夹到我们工程的Drivers下,只保留Inc和Src文件夹即可。
执行完以上操作后,Drivers文件夹最终结构如图7.1.1.3所示:
图7.1.1.3 工程根目录下的Drivers文件夹
关于工程根目录下的Drivers文件操作到这里就完成了,可以说步骤是有点多。在此过程遇到问题的话,请大家多参考我们提供的实验0-2,新建工程实验-HAL库版本工程,一步步操作。
Middlewares文件夹
该文件夹用于存放正点原子和其他第三方提供的中间层代码(组件/Lib等),如:USMART、MALLOC、TEXT、FATFS、USB、LWIP、各种OS、各种GUI等等。本章我们暂时用不到该文件夹,不过可以先建好备用,后面的实验将会陆续添加各种文件。
Output文件夹
该文件夹用于存放编译器编译工程输出的中间文件,比如:.hex、.bin、.o文件等等。这里不需要操作,后面只需要在MDK里面设置该文件夹为编译过程中间文件的存放文件夹就行。
Projects文件夹
该文件夹用于存放编译器(MDK、IAR等)工程文件,我们主要用MDK,为了方便区分,我们在该文件夹下新建:MDK-ARM文件夹,用于存放MDK的工程文件,如图7.1.1.4所示:
图7.1.1.4 在Projects文件夹下新建MDK-ARM文件夹
User文件夹
User文件夹用于存放HAL库用户配置文件、main.c文件、中断处理文件等。
我们首先从官方固件包里面直接拷贝官方的模板工程下的HAL库用户配置文件和中断处理文件到我们的User文件夹里。官方的模板工程路径:STM32Cube_FW_H5_V1.0.0\Projects \NUCLEO-H563ZI\Templates\TrustZoneDisabled,打开Template_Project文件夹,如图7.1.1.8所示。
图7.1.1.8 官方模板工程根目录
我们需要的文件就在Inc和Src文件夹里面,在这两个文件夹里面找到:stm32h5xx_it.c、stm32h5xx_it.h、stm32h5xx_hal_conf.h这三个文件,并且拷贝到我们的User文件夹下。
最后在User文件夹下新建一个命名为SCRIPT的文件夹,用于存放分散加载文件。分散加载文件直接在我们的实验0-2,新建工程实验-HAL库版本工程对应位置拷贝过来,后面再给大家讲解。main.c文件我们也是放在User文件夹里面的,后面在MDK里面教大家新建.c文件并保存。
7.1.2 新建一个工程框架
首先,打开MDK软件。然后点击Project→New uVision Project如图7.1.2.1所示:
图7.1.2.1 新建MDK工程
然后弹出工程命名和保存的操作窗口,将工程文件保存路径设置在上一节新建的工程文件夹内,具体路径为:桌面→实验0-2,新建工程实验-HAL库版本→Projects→MDK-ARM,工程名字我们取:atk_h750,最后点击保存即可。具体操作窗口如图7.1.2.2所示:
图7.1.2.2 保存工程界面
之后,弹出器件选择对话框,如图7.1.2.3所示。因为Mini STM32H562开发板所使用的STM32型号为STM32H562VIT6,所以我们选择:STMicroelectronics→STM32H5→Series→STM32H562→STM32H562VITx(如果使用的是其他系列的芯片,选择相应的型号就可以了,特别注意:一定要安装对应的器件pack才会显示这些内容哦!!!如果没得选择,请关闭MDK,然后安装 A盘:6,软件资料\1,软件\MDK5\ Keil.STM32H5xx_DFP.1.0.0.pack这个安装包后重试)。
图7.1.2.3 器件选择界面
点击OK,MDK会弹出Manage Run-Time Environment对话框,如图7.1.2.4所示:
图7.2.1.4 Manage Run-Time Environment界面
这是MDK5新增的一个功能,在这个界面,我们可以添加自己需要的组件,从而方便构建开发环境,不过这里我们不做介绍。所以在图7.1.2.4所示界面,我们直接点击Cancel,即可,得到如图7.1.2.5所示界面:
图7.1.2.5 工程初步建立
此时,我们打开MDK-ARM文件夹,会看到MDK在该文件夹下自动创建了3个文件夹(DebugConfig、Listings和Objects),如图7.1.2.6所示:
图7.1.2.6 MDK新建工程时自动创建的文件夹
这三个文件夹的作用如表7.1.2.1所示:
表7.1.2.1 三个文件夹及其作用
编译过程产生的链接列表、调试信息、预览、lib等文件,统称为中间文件。为了统一管理,方便使用,我们会把输出在Listings和Objects文件夹的内容,统一改为输出到Output文件夹(通过魔术棒设置),我们先把MDK自动生成的这两个文件夹(Listings和Objects)删除。
至此,我们还只是建了一个框架,还有好几个步骤要做,比如添加文件、魔术棒设置、编写main.c等。
7.1.3 添加文件
本节将分5个步骤:1,设置工程名和分组名;2,添加启动文件;3,添加SYSTEM源码4,添加 User 源码;5,添加 STM32H5xx_HAL_Driver 源码。
1. 设置工程名和分组名
在Project→Target上右键,选择Manage Project Items…(方法一)或在菜单栏点击品字形红绿白图标(方法二)进入工程管理界面,如图7.1.3.1所示:
图7.1.3.1 进入工程管理界面
在工程管理界面,我们可以执行设置工程名字(Project Targets)、分组名字(Groups)以及添加每个分组的文件(Files)等操作。我们设置工程名字为:Template,并设置四个分组:Startup(存放启动文件)、User(存放main.c等用户代码)、Drivers/SYSTEM(存放系统级驱动代码)、Readme(存放工程说明文件),如图7.1.3.2所示:
图7.1.3.2 设置工程名和分组名
设置好之后,我们点击OK,回到MDK主界面,可以看到我们设置的工程名和分组名如图7.1.3.3所示:
图7.1.3.3 设置成功
这里我们只是新建了一个简单的工程,并没有添加BSP、Middlewares等分组,后面随着工程复杂程度的增加,我们需要一步步添加对应的分组。
注意:为了让工程结构清晰,我们会尽量让MDK的工程分组和我们前面新建的工程文件夹对应起来,由于MDK分组不支持多级目录,因此我们将路径也带入分组命名里面,以便区分。如:User分组对应User文件夹里面的源码,Drivers/SYSTEM分组,对应Drivers/SYSTEM文件夹里面的源码,Drivers/BSP分组对应Drivers/BSP文件夹里面的源码等。
2. 添加启动文件
启动文件(.s文件)包含STM32的启动代码,其主要作用包括:1、堆栈(SP)的初始化;2、初始化程序计数器(PC);3、设置向量表异常事件的入口地址;4、调用main函数等,是每个工程必不可少的一个文件,我们在本书第九章会有详细介绍。
启动文件由ST官方提供,存放在STM32CubeH5软件包的:Drivers→CMSIS→Device→ST→STM32H5xx→Source→Templates→arm文件夹下。因为我们开发板使用的是STM32H562VIT6,对应的启动文件为:startup_stm32h562xx.s,为了节省空间,在精简版CMSIS文件夹里面我们把其他启动文件都删了。
关于启动文件的说明,我们就介绍这么多,接下来我们看如何添加启动文件到工程里面。我们有两种方法给MDK的分组添加文件:1,双击Project下的分组名添加。2,进入工程管理界面添加。
这了我们使用方法1添加(路径:实验0-2,新建工程实验-HAL库版本\Drivers\CMSIS\
Device\ST\STM32H5xx\Source\Templates\arm),如图7.1.3.4所示:
图7.1.3.4 双击分组添加启动文件(startup_stm32h562xx.s)
上图中,我们也可以点击Add按钮进行文件添加。添加完后,点击Close,完成启动文件
添加,得到工程分组如图7.1.3.5所示:
图7.1.3.5 启动文件添加成功
3. 添加SYSTEM源码
这里我们在工程管理界面(方法2)进行SYSTEM源码添加。点击:
按钮,进入工程管理界面,选中Drivers/SYSTEM分组,然后点击:Add Files,进入文件添加对话框,依次添加delay.c、sys.c和usart.c到该分组下,如图7.1.3.6所示:
图7.1.3.6 添加SYSTEM源码
注意:这些源码都是在第7.1.1小节的第二步拷贝过来的,如果之前没拷贝,是找不到这些源码的。添加完成后,如图7.1.3.7所示:
图7.1.3.7 SYSTEM源码添加完成
4. 添加User源码
这里我们在工程管理界面(方法2)进行User源码添加。点击:
按钮,进入工程管理界面,选中User分组,然后点击:Add Files,进入文件添加对话框,依次添加stm32h5xx_it.c和system_stm32h5xx.c到该分组下,如图7.1.3.8所示:
图7.1.3.8添加User源码
注意:这些源码都是在第7.1.1小节的第二步拷贝过来的,如果之前没拷贝,是找不到这些源码的。添加完成后,如图7.1.3.9所示:
图7.1.3.9 User源码添加完成
5. 添加STM32H5xx_HAL_Driver源码
接下来我们往Drivers/STM32H5xx_HAL_Driver分组里添加文件。点击:
按钮,进入工程管理界面,选中Drivers/STM32H5xx_HAL_Driver分组,然后点击:Add Files,进入文件添加对话框,依次添加stm32h5xx_hal.c、stm32h5xx_hal_cortex.c、stm32h5xx_hal_dma.c、stm32h5xx_hal_dma_ex.c、stm32h5xx_hal_gpio.c、stm32h5xx_hal_icache.c、stm32h5xx_hal_pwr.c、stm32h5xx_hal_pwr_ex.c、stm32h5xx_hal_rcc.c、stm32h5xx_hal_rcc_ex.c、stm32h5xx_hal_uart.c、stm32h5xx_hal_uart_ex.c、stm32h5xx_hal_usart.c和stm32h5xx_hal_usart_ex.c到该分组下,如图7.1.3.10所示:
图7.1.3.10 添加STM32H5xx_HAL_Driver源码
添加完成后,如图7.1.3.11所示:
图7.1.3.11 STM32H5xx_HAL_Driver源码添加完成
可以看到分组中有些.c文件有个小钥匙的符号,这是因为官方的固件包的文件设置了只读权限,我们取消只读权限就好了,方法如图7.1.2.12所示。
图7.1.2.12 取消工程文件夹的只读权限
7.1.4 魔术棒设置
为避免编写代码和编译报错,我们需要通过魔术棒对MDK工程进行相关设置。在MDK主界面,点击:
(魔术棒图标,即Options for Target按钮),进入工程设置对话框,我们将进行如下几个选项卡的设置。
1. 设置Target选项卡
在魔术棒→Target选项卡里面,我们进行如图7.1.4.1所示的设置:
图7.1.4.1 Target选项卡设置
上图中,工程默认使用AC6编译器,而且STM32H5系列只能使用AC6编译器。
这里我们说明一下AC5和AC6编译的差异,如表7.1.4.2所示:
表7.1.4.1 AC5&AC6简单对比
2. 设置Output选项卡
在魔术棒→Output选项卡里面,进行如图7.1.4.2所示设置:
图7.1.4.2 设置Output选项卡
注意,我们勾选:Browse Information,用于输出浏览信息,这样就可以使用go to definition查看函数/变量的定义,对我们后续调试代码比较有帮助,如果不需要调试代码,则可以去掉这个勾选,以提高编译速度。
3. 设置Listing选项卡
在魔术棒→Listing选项卡里面,进行如图7.1.4.3所示设置:
图7.1.4.3 设置Listing选项卡
经过Output和Listing这两步设置,原来存储在Objects和Listings文件夹的内容(中间文件)就都改为输出到Output文件夹了。
4. 设置C/C++(AC6)选项卡
在魔术棒→C/C++(AC6)选项卡里面,进行如图7.1.4.4所示设置:
图7.1.4.4 设置C/C++选项卡
上图中,设置了全局宏定义:STM32H562xx,USE_HAL_DRIVER;设置头文件包含路径;设置编译选项,关闭对汉字的错误警告;其它基本按照默认设置就好。
在第3处,我们可以进行头文件包含路径设置,点击此按钮,进行如图7.1.4.5所示设置:
图7.1.4.5 设置头文件包含路径
上图中我们设置了6个头文件包含路径。为避免频繁设置头文件包含路径,正点原子最新源码的include全部使用相对路径,也就是我们只需要在头文件包含路径里面指定一个文件夹,那么该文件夹下的其他文件夹里面的源码,如果全部是使用相对路径,则无需再设置头文件包含路径了,直接在include里面就指明了头文件所在。
关于相对路径,这里大家记住3点:
1,默认路径就是指MDK工程所在的路径,即.uvprojx文件所在路径(文件夹)
2,“./”表示当前目录(相对当前路径,也可以写做“.\”)
3,“../”表示当前目录的上一层目录(也可以写做“..\”)
举例来说,上图中:..\..\Drivers\CMSIS\Device\ST\STM32H5xx\Include,前面两个“..\”,表示Drivers文件夹在当前MDK工程所在文件夹(MDK-ARM)的上2级目录下,具体解释如图7.1.4.6所示:
图7.1.4.6 ..\..\Drivers\CMSIS\Device\ST\STM3H5xx\Include的解释
上图表示根据头文件包含路径:..\..\Drivers\CMSIS\Device\ST\STM32H5xx\Include,编译器可以找到第6处所包含的这些头文件,即代码里面可以直接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处设置:-Wno-invalid-source-encoding,避免中文编码报错!!
5. 设置Debug选项卡
在魔术棒→Debug选项卡里面,进行如图7.1.4.7所示设置:
图7.1.4.7 Debug选项卡设置
图中,我们选择使用:CMSIS-DAP仿真器,使用SW模式,并设置最大时钟频率为10Mhz,以得到最高下载速度。当我们将仿真器和开发板连接好,并给开发板供电以后,仿真器就会找到开发板芯片,并在SW Device窗口显示芯片的IDCODE、Device Name等信息(图中⑤处),当无法找到时,请检查供电和仿真器连接状况。
6. 设置Utilities选项卡
在魔术棒→Debug选项卡里面,进行如图7.1.4.8所示设置:
图7.1.4.8 Utilities选项卡设置
图中第5处虽然勾选了自动复位和运行,但实际上并没起作用的。因为我们预留的下载接口是没有引出复位引脚的,所以下载完程序后,需要手动按复位按键进行复位和运行程序。
至此魔术棒的设置就完成了。
7.1.5 添加main.c,并编写代码
在MDK主界面,点击:
,新建一个main.c文件,并保存在User文件夹下。然后双击User分组,弹出添加文件的对话框,将User文件夹下的main.c文件添加到User分组下。得到如图7.1.5.1所示的界面:
图7.1.5.1 在User分组下加入main.c文件
至此,我们就可以开始编写我们自己的代码了。我们在main.c文件里面输入如下代码:
- #include "./SYSTEM/sys/sys.h"
- #include "./SYSTEM/usart/usart.h"
- #include "./SYSTEM/delay/delay.h"
- int main(void)
- {
- HAL_Init(); /* HAL库初始化 */
- HAL_ICACHE_Enable(); /* 使能指令缓存 */
- sys_stm32_clock_init(250, 4, 2, 2); /* 系统时钟初始化,250Mhz */
- delay_init(250); /* 延时初始化 */
- usart_init(115200); /* 串口初始化 */
- while(1)
- {
- printf("Hello ALIENTEK STM32H562\r\n");
- delay_ms(1000);
- }
- }
复制代码 此部分代码,在A盘→4,程序源码→1,标准例程-HAL库版本→实验0 基础入门实验→实验0-2,新建最工程实验-HAL库版本→User→main.c里面有,大家可以自己输入,也可以直接拷贝。强烈建议自己输入,以加深对程序的理解和印象!!
注意,这里的include就是使用的相对路径,关于相对路径,请参考前面C/C++(AC6)选项卡设置章节进行学习。
编写完main.c,我们点击:
(Rebuild)按钮,编译整个工程,编译结果如下图所示:
图7.1.5.2 编译结果
编译结果可以看到0个错误,0个警告。如果你的编译结果有错误或者警告,请根据提示自行处理。
编译结果提示:代码总大小(Porgram Size)为:FLASH占用15204字节(Code + RO + RW),SRAM占用3120字节(RW + ZI);并成功创建了Hex文件(可执行文件,放在Output目录下)。
总结:如果编译提示有错误/警告,请根据提示,从第一个错误/警告开始解决,直到0错误0警告。如果出错,很有可能是之前的操作存在问题,请对照教程找问题。
另外,我们在Readme分组下还没有添加任何文件,由于只是添加一个说明性质的文件(.txt),并不是工程必备文件,因此这里我们就不添加了,开发板光盘的源码我们是有添加的,大家可以去参考一下。
至此,新建HAL库版本MDK工程完成。
7.2 下载验证
这里我们继续使用DAP仿真器下载,在MDK主界面,点击:
(下载按钮,也可以按键盘快捷键:F8),就可以将代码下载到开发板,如图7.2.1所示:
图7.2.1 下载成功
上图提示:Flash Load finished,则表示代码下载成功,但是没有开始运行,所以需要我们手动按复位按键才会开始运行程序。此时,打开XCOM.exe,并进行如图7.2.2的设置,就可以看到实验现象。
图7.2.2 设置XCOM并查看实验现象 |