1. 寄存器
1.1 寄存器是什么?
寄存器是位于硬件电路中的高速存储单元,通常用于存储控制信息、状态信息或数据。寄存器直接与 CPU 或外设相连,因此它们的访问速度非常快。
1.2 寄存器与内存的区别
- 寄存器:位于 CPU 或外设内部,通常用于存储临时数据和控制信息,容量小但速度极快。
- 内存(如 SRAM 和 Flash):用于存储程序代码和运行时数据,容量大,但访问速度较寄存器慢。
在 STM32 系列芯片中,寄存器用于控制外设的工作方式(如 GPIO、定时器、UART 等),而内存则用于存储程序和运行时数据。
2. 存储器架构:SRAM、Flash 和寄存器
2.1 SRAM(静态随机存储器)
- 用途:用于存储程序运行时的数据,如变量和栈。
- 特点:较大的容量(例如 STM32F103C8T6 有 20 KB SRAM),但比寄存器慢,且数据在断电后会丢失。
2.2 Flash(闪存)
- 用途:用于存储程序代码和常量数据。
- 特点:容量较大(例如 STM32F103C8T6 有 64 KB Flash),访问速度较慢,但数据在断电后不会丢失。
2.3 外设寄存器
外设寄存器位于外设硬件模块中,通过地址映射与 CPU 连接。它们不属于 SRAM 或 Flash,但在地址空间中和其他存储器一样被访问。外设寄存器用于控制和监控外设(如 GPIO、定时器、ADC 等)。
3. 地址映射与物理地址
3.1 地址空间划分
STM32 的地址空间通常分为以下几个区域:
- 代码区:存储程序代码,起始地址 0x08000000。
- SRAM 区:存储运行时数据,起始地址 0x20000000。
- 外设寄存器区:控制外设的寄存器,起始地址 0x40000000。
- 外部设备区:连接外部设备,如外置存储器,地址范围 0x60000000 至 0xDFFFFFFF。
- 私有外设区:内核相关寄存器,地址范围 0xE0000000 至 0xFFFFFFFF。
3.2 无效地址区
在不同型号芯片中,内存的大小不同,因此一些地址区域会被留作无效地址区。如果访问这些地址,会导致总线错误(Bus Fault)或硬故障(Hard Fault)。例如:
- STM32F103C8T6 的 Flash 只有 64 KB,因此从 0x08010000 到 0x080FFFFF 是无效地址。
4. 外部设备与通信协议
4.1 外部设备的工作原理
对于 EEPROM、外部 Flash 等外部设备,它们通常通过通信协议(如 I2C、SPI)与 MCU 交互。I2C 和 SPI 是常见的串行通信协议,其中 I2C 适用于低速设备(如 EEPROM),而 SPI 适用于高速设备(如外部 Flash)。
- I2C:通过 SCL 和 SDA 线进行数据传输。
- SPI:通过 SCK、MOSI、MISO 和 CS 线进行数据传输。
外部设备的数据传输是逐字节的,而内部存储器的访问则是通过地址总线进行直接访问的。因此,外部设备的操作看起来较为笨拙和复杂。
4.2 如何像操作内部存储器一样灵活操作外部设备?
虽然外部设备的操作通过通信协议进行,但可以通过以下技术将其抽象成像操作内部存储器一样灵活:
- 驱动程序封装:通过编写驱动程序,将底层通信协议封装,提供简洁的接口供上层代码调用。比如,写一个 EEPROM 的读写函数,使用者只需调用这些函数,而无需关注底层 I2C 通信的细节。
- 内存映射:某些高级 MCU 支持将外部设备映射到特定的内存地址。通过这种方式,开发者可以像访问内部存储器一样,使用指针直接访问外部 Flash 或 EEPROM 的数据。
// 示例:外部 Flash 内存映射操作
uint32_t *external_flash = (uint32_t *)0x60000000;
external_flash[0] = 0x12345678; // 写入数据
uint32_t data = external_flash[0]; // 读取数据
4.3 相关技术
- 内存映射(Memory Mapping):通过硬件支持(如 STM32 的 FSMC/FMC 模块),可以将外部设备映射到 MCU 的地址空间,进而简化访问过程。
- DMA(直接存储器访问):DMA 可以直接在外设和存储器之间传输数据,减少 CPU 的负担。
5. 总结
- 寄存器与内存的关系:寄存器是 CPU 或外设内部的高速存储单元,主要用于控制信息和状态存储;内存(如 SRAM 和 Flash)用于存储数据和程序。
- 地址空间的映射与划分:STM32 等嵌入式芯片通过统一的地址空间设计,使得不同类型的存储器(Flash、SRAM)和外设寄存器可以像内存一样被访问。无效地址区的存在则是因为不同型号的芯片有不同的资源大小。
- 外部设备的通信协议与抽象:外部设备通过 I2C、SPI 等协议与 MCU 通信,但通过驱动程序封装、内存映射等手段,可以简化外部设备的操作,使其看起来像是在操作内部存储器一样灵活。