赞
踩
存储器映射
程序存储器、数据存储器、寄存器和 I/O 端口排列在同一个顺序的 4 GB 地址空间内。也就是被总线连接的部分。我们在编程的时候,也是对这些功能部件进行操作。存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配,给存储器分配地址的过程称为存储器映射,如果再分配一个地址就叫重映射。
各字节按小端格式在存储器中编码。字中编号最低的字节被视为该字的最低有效字节,而编号最高的字节被视为最高有效字节。
可寻址的存储空间分为 8 个主要块,每个块为 512 MB。未分配给片上存储器和外设的所有存储区域均视为“保留区”。这个容量是非常大的,因此芯片厂商就在每块容量范围内设计各自特色的外设,要注意一点每块区域容量占用越大,芯片成本就越高,所以说我们使用的 STM32 芯片都是只用了其中一部分。ARM 在对这 4GB 容量分块的时候是按照其功能划分,每块都有它特殊的用途。
在这 8 个 Block 里面,Block0、Block1 和 Block2 这 3 个块是我们最为关心的。因为它包含了 STM32 芯片的内部 Flash、RAM 和片上外设。
寄存器映射
在上一节存储器映射中我们知道Block2 这片区域是用来设计片上外设的,由于Cortex-M4 内核是32 位的,所以存储器内部是以四个字节为一个单元,每一个单元对应不同的功能,当我们控制这些单元时也就可以控制外设。每一个单元还对应一个地址,我们要操作这些单元,也就是通过对应的地址来访问。由于STM32 外设非常多而且复杂,如果每操作一个外设就要写一大串对应的存储单元地址,显然是非常麻烦的而且还极容易出错。因此我们就把每个单元的功能作为名,给这个内存取一个别名,这个别名是我们经常说的寄存器。然后通过C语言指针来操作这些寄存器即可。那什么是寄存器映射呢?给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射。
通过:总线基地址->GPIO基地址->相对GPIO基地址的偏移的流程实现寄存器映射。
简化的编程:
/*======================== C 语言 对寄存器的封装===================== */ typedef unsigned int uint32_t; typedef unsigned short int uint16_t; typedef struct { uint32_t MODER; uint32_t OTYPER; uint32_t OSPEEDR; uint32_t PUPDR; uint32_t IDR; uint32_t ODR; uint32_t BSRR; uint32_t LCKR; uint16_t AFRL; uint16_t AFRH; }GPIO_TypeDef; #define GPIOA_BASE (0x40020000) #define GPIOB_BASE (0x40020400) #define GPIOC_BASE (0x40020800) #define GPIOD_BASE (0x40020C00) #define GPIOE_BASE (0x40021000) #define GPIOF_BASE (0x40021400) #define GPIOA (GPIO_TypeDef *)GPIOA_BASE #define GPIOB (GPIO_TypeDef *)GPIOB_BASE #define GPIOC (GPIO_TypeDef *)GPIOC_BASE #define GPIOD (GPIO_TypeDef *)GPIOD_BASE #define GPIOE (GPIO_TypeDef *)GPIOE_BASE #define GPIOF (GPIO_TypeDef *)GPIOF_BASE
参考:《STM32F4x中文参考手册》、《STM32F4x英文数据手册》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。