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

STM32新建不同工程的方式

新建工程的方式

  • 1. 安装开发工具 MDK5 / keil5
  • 2. CMSIS 标准
  • 3. 新建工程
    • 3.1 寄存器版工程
    • 3.2 标准库版工程
    • 3.3 HAL/LL库版工程
    • 3.4 HAL库、LL库、标准库和寄存器对比
    • 3.5 库开发和寄存器的关系
  • 4. STM32CubeMX工具的作用

1. 安装开发工具 MDK5 / keil5

MDK5 由两个部分组成:MDK Core 和 Software Packs。其中,Software Packs 可以独立于工具链进行新芯片支持和中间库的升级。

在这里插入图片描述

  • MDK Core 分为四个部分:uVision IDE with Editor(编辑器)ARM C/C++ Compiler(编译器)Pack Installer(包安装器)uVision Debugger with Trace(调试跟踪器)。Pack Installer 用于下载、安装、更新和管理 Software Packs。
  • Software Packs(软件包) 分为三个部分:Device(芯片支持)CMSIS(微控制器软件接口标准)Mdidleware(中间库)

特性MDK5Keil5
定位完整的开发套件集成开发环境(IDE)
包含内容IDE、编译器、调试器、中间件、设备支持包仅包含 IDE
适用场景ARM Cortex-M 微控制器开发嵌入式开发(尤其是 ARM Cortex-M)
功能范围更广泛,包含完整的开发工具链专注于代码编辑、编译和调试
适用项目规模开发复杂的嵌入式系统,或者需要使用丰富的中间件只需要一个 IDE 来编写和调试代码,或者项目规模较小

2. CMSIS 标准

因为基于 Cortex 系列芯片采用的内核都是相同的,区别主要为核外的片上外设的差异,这些差异却导致软件在同内核,不同外设的芯片上移植困难。为了解决不同的芯片厂商生产的 Cortex 微控制器软件的兼容性问题,ARM 与芯片厂商建立了 CMSIS 标准(微控制器软件接口标准)。所有芯片厂家的官方库(包括ST官方库)都是根据这套标准设计的。
在这里插入图片描述

  从图中可以看出,CMSIS 层在整个系统中是处于中间层,向下负责与内核和各个外设直接打交道,向上提供实时操作系统用户程序调用的函数接口。如果没有 CMSIS 标准,那么各个芯片公司就会设计自己喜欢的风格的库函数,而 CMSIS 标准就是要强制规定,芯片生产公司设计的库函数必须按照 CMSIS 这套规范来设计。

  其实不用讲这么复杂的,举一个简单的例子,我们在使用 STM32 芯片的时候首先要进行系统初始化,CMSIS 规范就规定,系统初始化函数名字必须为 SystemInit,所以各个芯片公司写自己的库函数的时候就必须用 SystemInit 对系统进行初始化。CMSIS 还对各个外设驱动文件的文件名字规范化,以及函数名字规范化等等一系列规定。例如函数GPIO_ResetBits 这个函数名字也是不能随便定义的,是要遵循 CMSIS 规范的。


CMSIS 分为 3 个基本功能层:

  • 核内外设访问层:用于访问内核寄存器的名称、地址定义以及功能函数,ARM 公司提供
  • 中间件访问层:用于访问中间件的通用 API,ARM 公司提供
  • 外设访问层:提供片上的核外外设的地址和中断定义以及外设的访问函数,芯片生产商提供

3. 新建工程

3.1 寄存器版工程

必备文件描述位置
stm32f4xx.h标准外设库头文件,包含寄存器定义、外设地址映射、位域定义等内容。ST官方提供STM32Cube_FW_F4_V1.26.0\Drivers\
CMSIS\Device\ST\STM32F4xx\Include
startup_stm32f407xx.s汇编语言启动文件,主要进行初始化堆栈,定义中断向量表以及跳转到主程序main()。ST官方提供STM32Cube_FW_F4_V1.26.0\Drivers\
CMSIS\Device\ST\STM32F4xx\Source\
Templates\arm

3.2 标准库版工程

  标准外设库 是对 STM32 芯片的一个完整的封装,包括所有标准器件外设的器件驱动器,是 ST 最早推出的针对 STM 系列主控的库函数。标准外设库仍然接近于寄存器操作,主要就是将一些基本的寄存器操作封装成了 C 函数。开发者仍需要关注所使用的外设是在哪个总线之上,具体寄存器的配置等底层信息。
  ST 为各系列提供的标准外设库稍微有些区别。例如,STM32F1x 的库和 STM32F4x 的库在文件结构上就有些不同,此外,在内部的实现上也稍微有些区别,这个在具体使用(移植)时,需要注意一下!但是,不同系列之间的差别并不是很大,而且在设计上是相同的。
  STM32 的标准外设库涵盖以下 3 个抽象级别:

  • 包含位,位域和寄存器在内的完整的寄存器地址映射
  • 涵盖所有外围功能(具有公共 API 的驱动器)的例程和数据结构的集合。
  • 一组包含所有可用外设的示例,其中包含最常用的开发工具的模板项目。

在这里插入图片描述


在这里插入图片描述

上图黄色部分为新建工程所必须的内容,接下来介绍这些文件的作用

文件名作用类别是否必须
stm32f4xx_conf.h1.用户配置文件,启用或禁用外设驱动: 通过条件编译控制是否包含特定外设的头文件 用户层
stm32f4xx_it.c
stm32f4xx_it.h
1.用户定义和处理与内核外设相关的中断事件,不一定放到这个文件,可删除 用户层
stm32f4xx.h1.定义所有外设寄存器及其位于 (寄存器定义)
2.使用结构体组织相关寄存器 (外设结构体)
3.定义外设寄存器的基地址和偏移量 (地址映射)
4.定义中断向量号和中断处理 (中断定义)
5.定义一些常用宏,用于位操作、寄存器配置等 (常用宏)
6.定义标准数据类型,如 uinit32_t (类型定义)
7.包含外设的配置选项和默认设置 (外设配置)
CMSIS
核心层
system_stm32f4xx.c
system_stm32f4xx.h
1.实现SystemInit()函数,负责在系统启动时初始化关键硬件模块 (系统初始化)
2.实现SystemCoreClockUpdate()函数,用于更新全局变量SystemCoreClock的值 (系统时钟更新)
3.定义全局变量SystemCoreClock,用于存储系统核心时钟频率 (全局变量定义)
4.定义默认的时钟配置,确保系统以正确的频率运行 (默认时钟配置)
5.在启动文件中,SystemInit()函数会在 main() 函数执行之前被调用,确保系统在进入用户代码之前完成初始化 (与启动文件配合)
CMSIS
核心层
startup_stm32f40xx.s1.定义中断向量表
2.初始化堆栈指针
3.在复位后初始化 .data 和 .bss 段
4.调用系统初始化函数SystemInit()
5.跳转到用户的主程序main()
6.提供默认的中断处理函数
CMSIS
核心层
core_cm4.h1.定义内核的寄存器结构体和地址映射,包括NVIC、SCB、SysTick、MPU、FPU (定义内核寄存器)
2.提供一系列内联函数,用于方便地访问内核的功能 (提供内联函数)
3.定义特殊功能寄存器(如xPSR、CONTROL、PRIMASK 等),用于控制处理器的运行状态 (定义特殊功能寄存器)
4.定义FPU相关的寄存器和函数,用于配置和控制 FPU (支持 FPU)
5.提供 CMSIS 标准接口
6.与标准外设库stm32f4xx.h配合使用,提供对内核功能的访问 (与标准外设库配合)
CMSIS
核心层
core_cmFunc.h1.提供内联函数访问内核的特殊功能寄存器(如xPSR、CONTROL、PRIMASK 等
2.支持特权和非特权模式的切换
3.提供中断控制函数(如全局中断的使能和禁用)
4.支持浮点单元(FPU)操作(如果可用)
CMSIS
核心层
core_cmInstr.h1.定义内联函数,用于封装内核的汇编指令(如WFI、WFE、SEV、NOP 等
2.提供同步指令(如 ISB、DSB、DMB
3.支持低功耗模式指令(如WFI 和 WFE
CMSIS
核心层
core_cmSimd.h1.定义 SIMD 指令的访问函数
2.提供对 DSP 扩展指令的支持
CMSIS
核心层
stm32f4xx_ppp.c
stm32f4xx_ppp.h
1.提供操作外设的 API 函数
2.定义外设的寄存器结构体、函数声明和宏定义
设备
驱动层


标准外设库各文件间的关系:
在这里插入图片描述

3.3 HAL/LL库版工程

  LL 库(Low Layer)目前与 HAL 库捆绑发布,它设计为比 HAL 库更接近于硬件底层的操作,代码更轻量级,代码执行效率更高的库函数组件,可以完全独立于 HAL 库来使用,但 LL库不匹配复杂的外设,如 USB 等。所以 LL 库并不是每个外设都有对应的完整驱动配置程序。使用 LL 库需要对芯片的功能有一定的认知和了解,它可以:

  • 独立使用,该库完全独立实现,可以完全抛开 HAL 库,只用 LL 库编程完成。
  • 混合使用,和 HAL 库结合使用。

 HAL 库和 LL 库设计为彼此独立的分支,但又同属于 HAL 库体系。标准库和 HAL 库、LL 库完全相互独立,HAL 库更倾向于外设通用化,扩展组件中解决芯片差异操作部分;LL倾向于最简单的寄存器操作,ST 在未来还将重点维护和建设 HAL 库,标准库已经部分停止更新。HAL 库和 LL 库的应用将是未来的一个趋势。

  HAL 即硬件抽象层。HAL 库是 ST 公司提供的外设驱动代码的驱动库,用户只需要调用库的 API 函数,便可间接配置寄存器。我们要写程序控制 STM32 芯片,其实最终就是控制它的寄存器,使之工作在我们需要得模式下,HAL 库将大部分寄存器的操作封装成了函数,我们只需要学习和掌握 HAL 库函数的结构和用法,就能方便地驱动 STM32 工作,以节省开发时间。

  HAL 库开发,指的是利用 HAL 库里面封装好的 C 语言编写的驱动文件,来实现对 STM32 内部和外部电器元件的控制过程。但只有 HAL 库还不能直接驱动一个 STM32 的芯片,其他的组件已经由 ARM 与众多芯片硬件、软件厂商指定的通用的软件开发标准 CMSIS 实现了。

  STM32Cube 是 ST 提供的一套性能强大的免费开发工具和嵌入式软件模块,它包含两个关键部分:

  1. 允许用户通过图形配置工具STM32CubeMX来生成 C 语言工程。可以通过 STM32CubeMX 实现方便地下载各种软件或开发固件包。
  2. 嵌入式软件包(STM32Cube 库)包含完整的 HAL 库(硬件抽象层 API),配套的中间件(包括 RTOS、USB、FAT文件系统、图形、TCP/IP 、以太网),以及一系列完整的例程。

在这里插入图片描述

在这里插入图片描述


上图黄色部分为新建工程所必须的内容,接下来介绍这些文件的作用

文件名作用类别是否
必须
stm32f4xx_it.c
stm32f4xx_it.h
标准外设库一样 用户层
stm32f4xx_hal_conf.h标准外设库stm32f4xx_conf.h 作用一样 用户层
stm32f4xx_hal_msp.c回调函数存放文件,已删除 用户层
stm32f407xx.h标准外设库stm32f4xx.h 作用一样 CMSIS
核心层
system_stm32f4xx.c
system_stm32f4xx.h
标准外设库一样 CMSIS
核心层
startup_stm32f407xx.s标准外设库一样 CMSIS
核心层
stm32f4xx.h是所有 STM32F4 系列的顶层头文件,并且可以选择性包含某一特定的
STM32F4 系列芯片的头文件(比如包含:F407头文件 stm32f407xx.h
CMSIS
核心层
core_cm4.h标准外设库一样 CMSIS
核心层
cmsis_armcc.h
cmsis_armclang.h
cmsis_compiler.h
cmsis_version.h
mpu_armv7.h
内核头文件,一般都不需要去了解 CMSIS
核心层
sm32f4xx_hal.c
stm32f4xx_hal.h
HAL 库的初始化、系统滴答,HAL 库延时函数等功能 设备
驱动层
stm32f4xx_hal_def.h通用 HAL 库资源定义 设备
驱动层
stm32f4xx_hal_ppp.c
stm32f4xx_hal_ppp.h
外设的操作 API 函数文件 设备
驱动层
stm32f4xx_hal_ppp_ex.c
stm32f4xx_hal_ppp_ex.h
拓展外设特性的 API 函数文件 设备
驱动层
stm32f4xx_II_ppp.c
stm32f4xx_II_ppp.h
LL 库文件,在一些复杂外设中实现底层功能 设备
驱动层


HAL库各文件间的关系:
在这里插入图片描述

3.4 HAL库、LL库、标准库和寄存器对比

HAL库标准库LL库寄存器
使用频率最高逐渐减少逐渐增加较低
优点开发效率高代码简洁,代码效率较高代码效率高,高于标准库代码效率最高
缺点代码体积大,执行效率低已停止维护开发效率略低于HAL库开发难度大,可移植性差
使用场景快速开发、跨平台移植老项目、简单应用性能与开发效率平衡的场景高性能需求、底层开发
开发效率最高较高中等最低
代码性能较低中等较高最高

3.5 库开发和寄存器的关系

  寄存器(Register)是单片机内部一种特殊的内存,它可以实现对单片机各个功能的控制,简单的来说可以把寄存器当成一些控制开关,控制包括内核及外设的各种状态。所以无论是 51单片机还是 STM32,都需要用寄存器来实现各种控制,以完成不同的功能。
  由于寄存器资源非常宝贵,一般都是一个位或者几个位控制一个功能,对于 STM32 来说,其寄存器是 32 位的,一个 32 位的寄存器,可能会有 32 个控制功能,相当于 32 个开关,由于STM32 的复杂性,它内部有几百个寄存器,所以整体来说 STM32 的寄存器还是比较复杂的。不过,我们不要被其吓到了,实际上 STM32 是由于内部有很多外设,所以导致寄存器很多,实际上我们把它分好类,每个外设也就那么几个或者几十个寄存器,学起来就不难了。
  从大方向来区分,STM32 寄存器分为两类,如表所示:
在这里插入图片描述
其中,内核寄存器,我们一般只需要关心中断控制寄存器和 SysTick 寄存器即可,其他三大类,我们一般很少直接接触。


对于STM32 来说,以 GPIOB 的 ODR 寄存器为例,其寄存器地址为:0X40010C0C,我们对其赋值 0XFFFF,表示 GPIOB 所有 IO 口(16 个 IO 口)都输出高电平:

(*(unsigned int *))(0X40010C0C) = 0XFFFF;

虽然上面的代码实现了我们需要的功能,但是从实用的角度来说,这么写肯定是不好的,可读性极差,可维护性也很差,所以一般我们使用结构体来访问,比如改写成这样:

GPIOB->ODR = 0XFFFF;

这种方法当然可以,但是这种方法的劣势是你需要去掌握每个寄存器的用法,你才能正确使用STM32,而对于 STM32 这种级别的 MCU,数百个寄存器记起来又是谈何容易。于是 ST(意法半导体)推出了官方固件库,固件库将这些寄存器底层操作都封装起来,提供一整套接口(API)供开发者调用,大多数场合下,你不需要去知道操作的是哪个寄存器,你只需要知道调用哪些函数即可。
比如控制 BSRRL 寄存器实现电平控制,官方 HAL 库封装了一个函数:

void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{
	assert_param(IS_GPIO_PIN(GPIO_Pin));
	assert_param(IS_GPIO_PIN_ACTION(PinState));
	if(PinState != GPIO_PIN_RESET){
		GPIOx->BSRR = GPIO_Pin;
	}
	else{
		GPIOx->BSRR = (uint32_t)GPIO_Pin << 16;
	}
}

  这个时候你不需要再直接去操作BSRRL寄存器了,你只需要知道怎么使用HAL_GPIO_WritePin这个函数就可以了。在你对外设的工作原理有一定的了解之后,你再去看固件库函数,基本上函数名字能告诉你这个函数的功能是什么,该怎么使用,这样开发起来会方便很多。
  任何处理器,不管它有多么的高级,归根结底都是要对处理器的寄存器进行操作。但是固件库不是万能的,如果想要把 STM32 学透,光读 STM32 固件库是远远不够的。你还是要了解一下 STM32 的原理,了解 STM32 各个外设的运行机制。只有了解了这些原理,你在进行固件库开发过程中才可能得心应手游刃有余。只有了解了原理,才能做到“知其然知其所以然”,所以在学习库函数的同时,别忘了要了解一下寄存器大致配置过程。
  标准库函数是对寄存器简单的进行了一次封装。将每个功能都独立的封装成一个函数。每个函数的功能比较单一。而HAL库相当于对寄存器进行了二次或者三次的封装,它将能合并的功能都合并在了一起。减小了写代码的难度。但是库函数本身阅读起来要比标准库要费劲一些。这样就导致,如果程序出错的话调试起来要比标准库难一点。但是HAL写程序却比较简单,函数的名字也更容易理解。更接近于面向对象的思想。没有哪种方式更好,每种都有自己的优缺点,根据实际情况,自己喜欢用哪种就用那种。通过对官方的这两种库的对比,可以看出在产品开发中代码永远都有优化和改进的空间。以后自己在开发项目的时候,也可以用这两种不同的方式对自己的代码进行优化升级。

描述标准外设库HAL / LL库
内核寄存器封装文件core_cm4.hcore_cm4.h
内核寄存器操作文件1.core_cm4.h
2.misc.c / misc.h : 封装NVIC、SysTick等操作
3.system_stm32f4xx.c : 系统初始化和时钟配置函数,涉及对内核寄存器的操作
4.startup_stm32f40xx.s: 底层汇编代码,涉及内核寄存器初始化
1. core_cm4.h
2.stm32f4xx_hal_cortex.c : 封装对内核寄存器的操作
3.system_stm32f4xx.c : 系统初始化和时钟配置函数,涉及对内核寄存器的操作
4.startup_stm32f40xx.s: 底层汇编代码,涉及内核寄存器初始化
5.stm32f4xx_hal.c: 间接操作内核寄存器
外设寄存器封装文件stm32f4xx.hstm32f4xx.h
外设寄存器操作文件stm32f4xx_ppp.c
stm32f4xx_ppp.h
stm32f4xx_hal_ppp.c
stm32f4xx_hal_ppp.h
stm32f4xx_hal_ppp_ex.c
stm32f4xx_hal_ppp_ex.h
stm32f4xx_II_ppp.c
stm32f4xx_II_ppp.h

4. STM32CubeMX工具的作用

STM32CubeMX是一款图形化配置工具,主要用于STM32微控制器的初始化和代码生成。 其主要作用包括:

  1. 引脚配置: 可视化配置引脚功能,如GPIO、外设接口等,避免冲突。
  2. 时钟树配置: 通过图形界面配置系统时钟、外设时钟等,确保时钟设置正确。
  3. 外设配置: 配置外设参数,如UART、SPI、I2C、ADC等,生成初始化代码。
  4. 中间件配置: 配置FreeRTOS、FATFS、USB库等中间件,简化开发。
  5. 功耗配置: 配置低功耗模式,优化功耗管理。
  6. 代码生成: 生成初始化代码,支持多种IDE(如Keil、IAR、STM32CubeIDE等),并提供HAL库和LL库选项。
  7. 项目管理: 创建和管理项目,支持多种开发环境和工具链。
  8. 固件更新: 集成STM32固件更新功能,方便升级。


通过STM32CubeMX工具自动生成驱动代码,让开发者只需专注实现 应用逻辑。


http://www.kler.cn/a/517750.html

相关文章:

  • 工业数据分析:解锁工厂数字化的潜力
  • python生成图片和pdf,快速
  • 2025美赛数学建模C题:奥运金牌榜,完整论文代码模型目前已经更新
  • 浅谈Redis
  • 导出地图为pdf文件
  • Linux下php8安装phpredis扩展的方法
  • 如何运用python爬虫获取大型资讯类网站文章,并同时导出pdf或word格式文本?
  • 【图文详解】lnmp架构搭建Discuz论坛
  • 纯css实现div宽度可调整
  • 为什么 TCP 挥手需要有 TIME_WAIT 状态?
  • 论文阅读的附录(七):Understanding Diffusion Models: A Unified Perspective(二):公式46的推导
  • 计算机图形学:实验三 光照与阴影
  • IBM 后端开发(二)
  • 【Project】CupFox电影网站数据爬取分析与可视化
  • 三代PacBio HiFi SV检测工具的安装
  • springboot基于spark的保险平台用户行为分析与研究
  • OpenAI Edge-TTS的使用方法
  • DAY5, 使用read 和 write 实现链表保存到文件,以及从文件加载数据到链表中的功能
  • 《Effective Java》学习笔记——第8部分 序列化
  • PyQt5菜单加多页签实现
  • Python爬虫之——Cookie存储器
  • Spring--SpringMVC的调用流程
  • 网关与云平台携手打造全轮转胶印机远程物联网监控系统
  • Spring Boot 后端跨域解决方案:解锁前后端通信的障碍
  • 使用python调用JIRA6 进行OAuth1认证获取AccessToken
  • 【u8g2模拟仿真】windows环境下使用sdl模拟仿真u8g2图形库