📖 第 5 章:STM32基础知识入门(STM32 Fundamentals)

🔧 正点原子《DMF407 开发指南》V1.0 · Chapter 5
🗨️ 「地基不牢,地动山摇:本章把后续 38 章都要用到的 STM32 通用知识一次讲透。」
这一章在干嘛? 复习 STM32 嵌入式开发必备的 C 语言(位操作、宏定义、结构体、指针)+ 寄存器本质 + STM32F407 系统架构 + 存储器与寄存器映射。读完后面对 HAL 库「为什么这样封装」会有恍然大悟的感觉。
5.1 C 语言基础知识复习5.2 寄存器基础知识5.3 STM32F407 系统架构

5.1 C 语言基础知识复习

5.1.1 位操作

嵌入式天天和 bit 打交道:清零 &= ~BIT、置位 |= BIT、取反 ^= BIT、读取 (x & BIT) ? 1 : 0

5.1.2 define 宏定义

#define PI 3.14 文本替换;带参数 #define MAX(a,b) ((a)>(b)?(a):(b)) 注意整体加括号避免运算符优先级坑。

5.1.3 ifdef 条件编译

头文件防重包含 #ifndef __STM32_H\n#define __STM32_H ... #endif;区分调试与发布 #ifdef DEBUG ... #endif

5.1.4 extern 外部声明

extern uint8_t g_flag; 告诉编译器「这变量在别的文件里定义」,不要分配空间。多文件工程必备。

5.1.5 typedef 类型别名

typedef unsigned int uint32_t; 让代码可移植、易读。C99/C11 的 <stdint.h> 已经替我们做好:uint8_t/uint16_t/uint32_t/uint64_t/int8_t/.../int64_t

5.1.6 结构体

把相关变量打包:struct GPIO_TypeDef { uint32_t MODER; uint32_t OTYPER; ... };。访问用 .(普通变量)或 ->(指针变量)。

5.1.7 指针

STM32 大量用「外设寄存器结构体指针」:#define GPIOA ((GPIO_TypeDef *)0x40020000),然后 GPIOA->BSRR = 0x01; 就是点亮 PA0。指针就是地址,地址就是数字,没什么神秘的。

C 语言建议: 把这 7 节内容当字典,不懂就翻,3 天后自然就熟了。

5.2 寄存器基础知识

寄存器 = 特殊功能的内存单元。本质:

(*(unsigned int *)(0x40010C0C)) = 0xFFFF;     // 把 GPIOB->ODR 设为 0xFFFF

但可读性差,所以改用结构体:

GPIOB->ODR = 0xFFFF;                          // 实质等价上一行

寄存器按 32 位组织,每位或几位代表一个开关/参数。命名约定:xxxx_CR1/CR2/CR3 配置寄存器、xxxx_SR 状态寄存器、xxxx_DR 数据寄存器、xxxx_BRR 波特率寄存器。

5.3 STM32F407 系统架构

5.3.1 Cortex M4 内核 & 芯片

Cortex-M4 由 ARM 设计,包含 NVIC(嵌套向量中断控制器)、SysTick、MPU、FPU、DSP 指令等。ST 在此基础上集成自家外设(USART/SPI/...)。

5.3.2 STM32 系统架构

F407 有 8 条主控总线:I-Code、D-Code、S-Bus、DMA、FSMC、AHB、APB1、APB2。

原书图 5.3.2.1:STM32 系统架构框图
原书图 5.3.2.1:STM32 系统架构框图

5.3.3 存储器映射

整个 4 GB 地址空间划分:

地址范围用途
0x0000_0000~0x1FFF_FFFFCode 区(Flash 映射)
0x2000_0000~0x3FFF_FFFFSRAM(192 KB)
0x4000_0000~0x5FFF_FFFF外设寄存器
0x6000_0000~0x7FFF_FFFFFSMC 扩展(外部 SRAM/NOR)
0x8000_0000~0x9FFF_FFFFFSMC 扩展(NAND)
0xA000_0000~0xDFFF_FFFFFSMC 扩展(其它)
0xE000_0000~0xFFFF_FFFFCortex-M4 内核(NVIC/SysTick)

原书图 5.3.3.1:STM32 存储器映射图
原书图 5.3.3.1:STM32 存储器映射图

记住常用段: RAM 起始 0x20000000;外设起始 0x40000000;Flash 起始 0x08000000(启动后映射到 0x00000000)。

5.3.4 寄存器映射

寄存器描述解读:手册里每个寄存器都有「位定义表」,例如 USART_BRR 寄存器:

名称读写功能
[3:0]DIV_FractionRW小数部分
[15:4]DIV_MantissaRW整数部分

寄存器映射举例:把 USART1 的 BRR 地址算出:

外设基地址USART 基地址偏移总地址
0x400000000x400110000x080x40011008

寄存器地址计算:外设基址 + 偏移;外设基址 = 总线基址 + 总线相对偏移;总线基址 = 总线基址基址 + N×总线间距。

原书图 5.3.4.1:寄存器描述解读示例
原书图 5.3.4.1:寄存器描述解读示例

stm32f407xx.h 寄存器映射说明:ST 已经把整个 F407 的寄存器映射成结构体,我们直接 USART1->BRR = 0x0683; 即可,不用自己算地址。

🧠 小测验
寄存器本质是什么?
特殊功能的内存单元,本质上是 32 位/16 位/8 位的内存地址。
STM32 的 I-Code 与 D-Code 总线各管什么?
I-Code 取指令(Flash→CPU),D-Code 读常量(常量数据)。
SRAM 起始地址与外设起始地址分别是?
SRAM 0x20000000,外设 0x40000000。
如何清零与置位某一位?
a &= ~BIT 清零,a |= BIT 置位。
← 上一篇🏠 顶层目录下一篇 →