前言:
作者本人在之前已经学习了STM32F1和F4的有关内容,F1是跟着江协科技的视频,F4是跟着正点原子的视频,之前是用Windows上的画图板做的笔记,内容有点杂。这一次我重新把笔记整理成了md格式并发布在了CSDN上目的也是为了整理笔记以及复习。当然自己其实学的并没有多好,希望大家多多交流,有不足以及错误之处还请大家纠正。
类型 使用库 芯片 F1 标准库 STM32F103C8T6核心板 F4 HAL库 正点原子探索者V3(STM32F407ZGT6) 这一部分基本上视频上抄写下来的,一方面是为了方便查阅,因为他们的资料内容过多,所以我把可能会有用的部分给总结出来了,另一方面也是为了给之后的内容过度,使后面的内容更加完整。如果要深入学习还是要看B站上面老师的视频。
文章目录
初识STM32
开发板的结构
由这个图可知,不同公司负责不同部分,因此在使用开发板的时候我们需要参考不同的数据手册比如正点原子的探索者V3开发板使用的是ARM公司的Cortex-M4架构的内核,由ST公司设计的STM32F407ZET6芯片,正点原子再集成其他外设实现对应功能。因此就会使用到不同的手册资料
我们主要会用到以下数据手册
ARM公司的Cortex-M4架构的内核:Cortex M3与M4权威指南.pdf
ST公司设计的STM32F407ZET6芯片:STM32F4xx参考手册_V4(中文版).pdf STM32F407IGT6.PDF(芯片手册)
正点原子再集成其他外设实现对应功能:STM32F407 探索者开发指南V1.2.pdf 探索者V3 硬件参考手册_V1.0.pdf EXPLORER_V3.4(探索者原理图).pdf 探索者V3 IO引脚分配表.xlsx
需要注意是:有一些外设集成在芯片上,称为片上外设,有一些则集成在开发板上,因此需要参考的数据手册就不一样
一、Cortex-M系列介绍
1.Cortex内核分类及特征
对比项 | Cortex-A (Application) | Cortex-R (Real-time) | Cortex-M (Microcontroller) |
---|---|---|---|
特点 | 高时钟频率,长流水线,高性能 | 较高时钟频率,较长的流水线,实时性强 | 时钟频率较低,通常较短的流水线,超低功耗 |
应用场景 | 移动计算、智能手机、平板电脑、数字电视 | 军工、汽车电子、无线基带、硬盘控制器 | 工控、传感器、消费电子、家用电器、医疗器械 |
2.Cortex-M3/4/7介绍
类别 | Cortex-M3 | Cortex-M4 | Cortex-M7 |
---|---|---|---|
核心版本 | ARMv7-M | ARMv7E-M | |
指令系统 | Thumb/Thumb-2 | ||
DSP指令扩展 | 无 | 有 | 有 |
浮点单元 | 无 | 单精度浮点单元 | 可选单/双精度浮点单元 |
流水线 | 3级 | 3级+分支预测 | 6级+分支预测 |
中断 | NVIC,NMI + 1~ 240物理中断源,8~256个中断优先级 | 同 | 同 |
系统定时器 | 24位系统滴答定时器 | 同 | 同 |
睡眠模式 | 集成WFI和WFE指令以及退出睡眠功能 | 同 | 同 |
调试 | 可选JTAG和SWD调试接口 | 同 | 同 |
内存保护 | 可选8个区域MPU | 可选8个区域MPU | 可选8、16个区域MPU |
DMIPS/MHz | 1.25 | 1.25 | 2.14 |
CoreMark®/MHz | 3.34 | 3.43 | 5.01 |
二、STM32命名规则

网站:ST中文社区网:https://www.stmcu.org.cn ST官网: https://www.st.com
三、最小系统
最小系统:保证MCU正常工作的最小电路组成单元
四、程序下载接口(F4)
开发板下载程序有两种方式:DAP下载/串口下载
- DAP定义:DAP是一种用于访问和调试嵌入式系统(如ARM Cortex-M系列微控制器)的协议和接口标准。
- DAP下载器:实现DAP协议的硬件设备,常见的有ST-Link和J-Link等,用于连接计算机和目标芯片,实现程序的烧录和调试。
- JTAG和SWD都是调试接口。不过这两种调试接口是完全不同的。
如果使用串口下载,则不能调试
五、资源简介
STM32F103
STM32F103C8T6 资源 | |||||
---|---|---|---|---|---|
内核 | Cortex M3 | 基本定时器 | 2 | USART/UART | 3 |
主频 | 72Mhz | 通用定时器 | 3 | CAN | 1 |
FLASH | 64KB | 高级定时器 | 2 | SDIO | 0 |
SRAM | 20KB | 12 位 ADC | 3 | FSMC | 0 |
封装 | LQFP48 | ADC 通道数 | 18 | DMA | 1 |
IO 数量 | 37 | 12 位 DAC | 1 | RTC | 1 |
工作电压 | 3.3V | SPI | 2 | IIC | 2 |
STM32F407
STM32F407ZGT6 资源 | |||||
---|---|---|---|---|---|
内核 | Cortex M4 | 基本定时器 | 2 | USART/UART | 6 |
主频 | 168Mhz | 通用定时器 | 10 | CAN | 2 |
FLASH | 1024KB | 高级定时器 | 2 | SDIO | 1 |
SRAM | 192KB | 12 位 ADC | 3 | FSMC | 1 |
封装 | LQFP144 | ADC 通道数 | 18 | DMA | 2 |
IO 数量 | 114 | 12 位 DAC | 2 | RTC | 1 |
工作电压 | 3.3V | SPI | 3 | IIC | 3 |
MDK调试
一、JTAG/SWD调试原理概述
Cortex-M内核含有硬件调试模块,该模块可在取指(指令断点)或访问数据(数据断点)时停止。内核停止时,可以查询内核的内部状态和系统的外部状态。完成查询后,可恢复程序执行。
二、基础执行控制按钮介绍
比较重要的是执行到光标处,这个是之前不知道的
三、查看程序段/函数执行时间
显示运行时间一般是在开启仿真的时候,在整个界面的右下角会有一个当前运行的时间
四、结束仿真报错解决方法
五、工具栏常用窗口按钮介绍
- Call Stack 窗口:查看函数调用关系&局部变量
- Watch窗口:查看函数首地址&变量值
- Watch窗口:设置全局变量在被读或写后自动停止运行
- Memory窗口:内存查看窗口
- Peripheral窗口:查看寄存器的值
六、注意
七、MDK中设置
内核芯片F4系统架构
1,STM32系统框架
Cortex M内核& 芯片
MCU厂商,经ARM公司授权,添加不同的外设 = 各种XX32芯片
F4系统架构
主控总线 | 被控总线 |
---|---|
Cortex M4内核 I总线 | 内部FLASH Icode 总线 |
Cortex M4内核 D总线 | 内部FLASH Dcode 总线 |
Cortex M4内核 S总线 | 主要内部SRAM1(112KB) |
DMA1存储器总线 | 辅助内部SRAM2(16KB) |
DMA2存储器总线 | 辅助内部SRAM3(64KB)(适用于F42xxx和F43xxx) |
DMA2外设总线 | AHB1外设(包括AHB-APB总线桥和APB外设) |
以太网DMA总线 | AHB2外设 |
USB OTG HS DMA总线 | FSMC |
摘自:STM32F4xx参考手册_V4(中文版).pdf 2.1小节
2,STM32的寻址范围
32位的单片机可以有32根地址线(每根地址线有两种状态:导通或不导通)
单片机内存地址访问的存储单元是按字节编址的(而不是bit)
每一个地址可以找到对应一个字节的数据,地址编号数就是内存大小
STM32寻址大小:2^32= 4G(字节)
STM32寻址范围:0x0000 0000 ~ 0xFFFF
地址线根数 | 地址编号(二进制) | 地址编号数(即内存大小) |
---|---|---|
1 | 0、1 | 2 |
2 | 00、01、10、11 | 4 |
3 | 000、001、010、011、100、101、110、111 | 8 |
n | …… | 2^n |
3,存储器映射
存储器指可以存储数据的设备,本身没有地址信息,对存储器分配地址的过程称为存储器映射
存储设备中的地址线和数据线的区别和联系
特性 | 地址线 | 数据线 |
---|---|---|
方向 | 单向(控制器→存储设备) | 双向(控制器↔存储设备) |
作用 | 指定存储位置 | 传输实际数据 |
数量影响 | 决定寻址空间大小 | 决定单次传输数据量(位宽) |
时序 | 通常在操作周期开始时稳定 | 在操作周期的数据阶段有效 |
- 地址线:类似“邮政编码”,告诉系统数据存放在哪里。
- 数据线:类似“快递包裹”,实际传输的内容。
==因此存储设备的存储大小为2^(地址线个数+数据线个数)==单位为bit,不是字节
4,寄存器映射
寄存器是单片机内部一种特殊的内存,可以实现对单片机各个功能的控制
简单来说:寄存器就是单片机内部的控制机构
寄存器是特殊的存储器,给寄存器地址命名的过程,就叫寄存器映射
如何查看参考手册中的寄存器中的描述?
注意:
偏移地址是指这个外设的某个功能对应的寄存器对于这个外设寄存器的起始地址的偏移位置,即某个外设的某个功能对应的寄存器地址 = 某个外设的寄存器起始地址 + 偏移地址
复位值表示在复位之后,这个寄存器的初始值大小
寄存器相关缩写词列表寄存器说明中使用以下缩写词:
读/写 (rw) 软件可以读写这些位。 只读 ® 软件只能读取这些位。 只写 (w) 软件只能写入该位。读取该位时将返回复位值。 读取/清零 (rc_w1) 软件可以读取该位,也可以通过写入 1 将该位清零。写入“0”对该位的值无影响。 读取/清零 (rc_w0) 软件可以读取该位,也可以通过写入 0 将该位清零。写入“1”对该位的值无影响。 读取/读取清零 (rc_r) 软件可以读取该位。读取该位时,将自动清零。写入“0”对该位的值无影响。 读取/置位 (rs) 软件可以读取该位,也可将其置 1。写入“0”对该位的值无影响。 只读写触发 (rt_w) 软件可以读取该位。写入“0”或“1”时,将触发事件,但不会影响该位的值。 切换 (t) 软件只能通过写入“1”来切换该位。写入“0”无影响。 保留 (Res.) 保留位,必须保持复位值。
寄存器映射举例
举例:
1,获取外设挂在哪个总线上面?查:系统结构图
2,获取总线基地址,APB2总线基地址:0X4001 0000
3,获取外设地址偏移量,GPIOA相对APB2总线偏移量是:0X800
4,获取寄存器地址偏移量,ODR相对GPIOA外设基地址的偏移量是:0X0C
寄存器地址 = BUS_BASE_ADDR + PERIPH_OFFSET + REG_OFFSET
GPIOA_ODR = 0X4001 0000 + 0X800 + 0X0C = 0X4001 080C
HAL简介
1,初识HAL库
CMSIS (微控制器软件接口标准):Cortex Microcontroller Software Interface Standard,是由ARM和与其合作的芯片厂商、软件工具厂商,共同制定的标准
2,STM32Cube固件包浅析
从ST官网上下载的固件包包含以下内容:
Drivers 文件夹
Drivers 文件夹 | BSP 文件夹 | 也叫板级支持包,用于适配 ST 官方对应的开发板的硬件驱动程序,每一种开发板对应一个文件夹。例如触摸屏, LCD, NOR FLASH 以及 EEPROM等板载硬件资源等驱动。这些文件针只匹配特定的开发板使用,不同开发板可能不能直接使用。基本用不上 |
---|---|---|
同 | CMSIS 文件夹 | 顾名思义就是符合 CMSIS 标准的软件抽象层组件相关文件。文件夹内部文件比较多。主要包括DSP 库(DSP_LIB 文件夹), Cortex-M 内核及其设备文件(Include 文件夹),微控制器专用头文件/启动代码/专用系统文件等(Device 文件夹)。 在新建工程的时候,会使用到这个文件夹内部很多文件 |
同 | STM32F4xx_HAL_Driver文件夹 | 这个文件夹非常重要,它包含了所有的 STM32F4 xx 系列 HAL 库头文件和源文件,也就是所有底层硬件抽象层 API 声明和定义。它的作用是屏蔽了复杂的硬件寄存器操作,统一了外设的接口函数。该文件夹包含 Src 和 Inc 两个子文件夹,其中Src 子文件夹存放的是.c 源文件, Inc 子文件夹存放的是与之对应的.h 头文件。每个.c 源文件对应一个.h 头文件。**源文件名称基本遵循 stm32f4xx_ hal_ppp.c 定义格式,头文件名称基本遵循 stm32f 4xx_hal_ppp.h 定义格式。**比如 gpio 相关的 API 的声明和定义在文件 stm32f4xx_hal_gpio.h 和 stm32 f4xx_hal_gpio.c 中。该文件夹的文件在我们新建工程章节都会使用到,我们后面会做详细介绍。 |
注:BSP板级支持包只适用于ST公司的开发板,我们用的是正点原子的开发板,所以用不上
CMSIS标准规定软件包目录
也就是STM32CubeF4固件包\STM32Cube_FW_F4_V1.26.0\Drivers\CMSIS下的文件目录
这里用的是F1的例子但也是一样的
Device 文件夹关键文件介绍
文件 | 描述 |
---|---|
stm32f4xx.h | 该文件内容看起来不多,却非常重要,是所有 STM32F4 系列的顶层头文件。使用 STM32F4 任何型号的芯片,都需要包含这个头文件。该文件包含了很多条件定义和常用的枚举变量类型,与宏定义配合,选择性包含某一特定的STM32F4 系列芯片的头文件。这个文件使我们在使用STM32F4 系列的不同型号芯片时,不需要每次都修改工程头文件,只需要修改宏定义并增加特定型号芯片的头文件即可快速选择使用不同类型的 F4 芯片。 |
stm32f407xx.h | STM32F407 系列芯片通用的片上外设访问层头文件。只要我们使用 STM32F407 系列芯片,都需要包括这个头文件。这个文件的主要作用是定义声明寄存器以及封装内存操作,以结构体和宏定义标识符的形式。 |
system_stm32f4xx.c system_stm32f4xx.h | 主要是声明和定义了系统初始化函数 SystemInit 以及系统时钟更新函数 SystemCoreClockUpdate。 SystemInit 函数的作用是进行时钟系统的一些初始化操作以及中断向量表偏移地址设置,但它并没有设置具体的时钟值,这是与标准库的最大区别,在使用标准库的时候, SystemInit 函数会帮我们配置好系统时钟配置相关的各个寄存器。在启动文件startup_stm32f4xx.s 中 会 设 置 系 统 复 位 后 , 直 接 调 用SystemInit函数进行系统初始化。SystemCoreClockUpdate函数是在系统时钟配置进行修改后,调用这个函数来更新全局变量 SystemCoreClock 的值,变量 SystemCoreClock 是一个全局变量,开放这个变量可以方便我们在用户代码中直接使用这个变量来进行一些时钟运算。 |
startup_stm32f407xx.s | STM32F407 系列芯片的启动文件,每个系列都有与之对应的启动文件。启动文件的作用主要是进行堆栈的初始化,中断向量表以及中断函数定义等。启动文件有一个很重要的作用就是系统复位后引导进入 main 函数。 |
固件包的 CMSIS 文件包括了所有STM32F4 芯片型号的文件,而我们只用到 STM32F407 系列,所以只是挑我们用到的系列文件来讲。
Middlewares文件夹 基本用不上
Middlewares文件夹 | ST 子 文 件夹 | STemWin 文件夹 STemWin 文件夹 | STemWin 工具包。Segger提供。STemWin 工具包。Segger提供。 |
---|---|---|---|
同 | ST 子 文 件夹 | STemWin 文件夹 STM32_USB_Device_Library文件夹 | STemWin 工具包。Segger提供。USB 从机设备支持包。 |
同 | ST 子 文 件夹 | STemWin 文件夹 STM32_USB_Host_Library文件夹 | STemWin 工具包。Segger提供。USB 主机设备支持包。 |
同 | Third_Party子文件夹 | FatFs 文件夹 | FAT 文件系统支持包。采用的 FATFS 文件系统。 |
同 | Third_Party子文件夹 | FreeRTOS 文件夹 | FreeRTOS 实时系统支持包。 |
同 | Third_Party子文件夹 | LibJPEG 文件夹 | 基于 C 语言的 JPEG 图形解码支持包。 |
同 | Third_Party子文件夹 | LwIP 文件夹 | LwIP 网络通信协议支持包。 |
3,HAL库框架结构
HAL 库文件夹结构
HAL 库文件介绍
表中 ppp 代表任意外设
文件 | 描述 |
---|---|
sm32f4xx_hal.c stm32f4xx_hal.h | 初始化 HAL 库,(比如 HAL_Init,HAL_DeInit, HAL_Dela等),主要实现 HAL 库的初始化、系统滴答, HAL 库延时函数、 IO 重映射和 DBGMCU 功能等。 |
stm32f4xx_hal_conf.h HAL库中本身没有这个文件,可以自行定义,也可以直接使用 《 Inc 》 文 件 夹 下stm32f4xx_hal_conf_template.h的内容作为参考模版 | HAL 的用户配置文件, stm32f4xx_hal.h 引用了这个文件,用来对 HAL 库进行裁剪。由于 Hal 库的很多配置都是通过预编译的条件宏来决定是否使用这一 HAL 库的功能,这也是当前的主流库如 LWIP /FreeRTOS 等的做法,无需修改库函数的源码,通过使能/不使能一些宏来实现库函数的裁剪。 |
stm32f4xx_hal_def.h | 通用 HAL 库资源定义,包含 HAL 的通用数据类型定义,声明、枚举,结构体和宏定义。如 HAL 函数操作结果返回值类型 HAL_StatusTypeDef 就是在这个文件中定义的。 |
stm32f4xx_hal_cortex.h stm32f4xx_hal_cortex.c | 它是一些 Cortex 内核通用函数声明和定义,例如中断优先级NVIC 配置,系统软复位以及 Systick 配置等,与前面core_cm4.h 的功能类似。 |
stm32f4xx_hal_ppp.c stm32f4xx_hal_ppp.h | 外设驱动函数。对于所有的 STM32 该驱动名称都相同, pp代表一类外设,包含该外设的操作 API 函数。例如:当 pp为 adc 时,那么这个文件就是 stm32f4xx_hal_adc.c/h,可以分别在 Src/Inc 目录下找到。包含该外设的操作 API 函数。其中stm32f4xx_hal_cortex.c/.h 比较特殊,它是一些 Cortex 内核通用函数声明和定义,例如中断优先级 NVIC 配置, MPU,系统软复位以及 Systick 配置等。 |
stm324fxx_hal_ppp_ex.c stm32f4xx_hal_ppp_ex.h | 外设特殊功能的 API 文件,作为标准外设驱动的功能补充和扩展。针对部分型号才有的特殊外设作功能扩展,或外设的实现功能与标准方式完全不同的情况下作重新初始化的备用接口。 ppp 的含义同标准外设驱动。 |
stm32f4xx_II_ppp.c stm32f4xx_II_ppp…h | LL 库文件,在一些复杂外设中实现底层功能,在部分stm32f4xx_hal_ppp.c 中被调用。目前用不上 |
HAL 库API函数和变量命名规则
文件名 | stm32f4xx_hal_ppp (c/h) | stm32f4xx_hal_ppp_ex (c/h) |
---|---|---|
函数名 | HAL_PPP_Function HAL_PPP_FeatureFunction_MODE | HAL_PPPEx_Function HAL_PPPEx_FeatureFunction_MODE |
外设句柄 | PPP_HandleTypedef | 无 |
初始化参数结构体 | PPP_InitTypeDef | PPP_InitTypeDef |
枚举类型 | HAL_PPP_StructnameTypeDef | 无 |
- 初始化/反初始化函数:HAL_PPP_Init(), HAL_PPP_DeInit()
- 外 设 读 写 函 数 :HAL_PPP_Read(),HAL_PPP_Write(),HAL_PPP_Transmit(),HAL_PPP_Receive()
- 控制函数:HAL_PPP_Set (), HAL_PPP_Get ().
- 状态和错误:HAL_PPP_GetState (), HAL_PPP_GetError ()
HAL 库的回调函数
最后要分享的是 HAL 库的回调函数,这部分允许用户重定义,并在其中实现用户自定义的功能,也是我们使用 HAL 库的最常用的接口之一:
回调函数 | 举例 |
---|---|
HAL_PPP_MspInit() / _DeInit() | 举例: HAL_USART_MspInit()由 HAL_PPP_Init()这个 API 调用,主要在这个函数中实现外设对应的 GPIO、时钟、 DMA 和中断开启的配置和操作。 |
HAL_PPP_ProcessCpltCallback | 举例: HAL_USART_TxCpltCallback由外设中断或 DMA 中断调用 ,调用时 API 内部已经实现中断标记的清除的操作,用户只需要专注于自己的软件功能实现即可。 |
HAL_PPP_ErrorCallback | 举例: HAL_USART_ErrorCallback外设或 DMA 中断中发生的错误,用于作错误处理。 |
4,如何使用HAL库
基于CMSIS应用程序文件描述
嵌入式的软件开发流程总遵循以下步骤:组织工具链、编写代码、生成可执行文件、烧录到芯片、芯片根据内部指令执行我们编程生成的可执行代码。
类别 | 文件名 | 描述 | 是否必须 |
---|---|---|---|
用户程序文件 | main.c | 存放 main 函数,不一定要在这个文件 | 否 |
用户程序文件 | main.h | 包含头文件、声明等作用,已删除 | 否 |
用户程序文件 | stm32f4xx_it.c、stm32f4xx_it.h | 用户中断服务函数存放文件,不一定放到这个文件,可删除 | 否 |
用户程序文件 | stm32f4xx_hal_conf.h | 用户配置文件 | 是 |
用户程序文件 | stm32f4xx_hal_msp.c | 回调函数存放文件,已删除 | 否 |
设备驱动 | 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 库文件,在一些复杂外设中实现底层功能 | 是 |
CMSIS核心层 | stm32f4xx.h | STM32F4 系列的顶层头文件 | 是 |
CMSIS核心层 | stm32f407xx.h | STM32F407 系列片上外设头文件 | 是 |
CMSIS核心层 | system_stm32f4xx.c、system_stm32f4xx.h | 主要存放系统初始化函数 SystemInit | 是 |
CMSIS核心层 | startup_stm32hf407xx.s | 启动文件,运行到 main 函数前的准备 | 是 |
CMSIS核心层 | core_cm4.h | 内核寄存器定义,如 Systick、 SCB 等 | 是 |
CMSIS核心层 | cmsis_armcc.h、cmsis_armclang.h、cmsis_compiler.h、cmsis_version.h、mpu_armv7.h | 内核头文件,一般都不需要去了解 | 是 |
用户程序文件需要自己配置的文件,其中一些东西可以根据自己的需要进行裁剪,而设备驱动和CMSIS核心层文件是芯片厂商和ARM公司提供的,不可修改
HAL库的用户配置文件的修改
裁剪HAL库外设驱动源码(不进行编译)
设置外部晶振频率(根据开发板实际情况设置)
| 是 |
| CMSIS核心层 | core_cm4.h | 内核寄存器定义,如 Systick、 SCB 等 | 是 |
| CMSIS核心层 | cmsis_armcc.h、cmsis_armclang.h、cmsis_compiler.h、cmsis_version.h、mpu_armv7.h | 内核头文件,一般都不需要去了解 | 是 |
用户程序文件需要自己配置的文件,其中一些东西可以根据自己的需要进行裁剪,而设备驱动和CMSIS核心层文件是芯片厂商和ARM公司提供的,不可修改
HAL库的用户配置文件的修改
裁剪HAL库外设驱动源码(不进行编译)
设置外部晶振频率(根据开发板实际情况设置)