笔记来自:正点原子STM32连载
1、stm32寻址范围
0x0000 0000 ~ 0xFFFF FFFF
单片机内存地址访问的存储单元是按字节编址的
32位的地址的编号数为2^32个字节即4G(即内存大小)
(数据手册 Figure 9. Memory map)
2、存储器映射
存储器本身没有地址,对其分配地址的过程称为存储器映射
对于19根地址线,16根数据线的存储器,其能够寻址:
2^19个地址,每个地址能存储16位(2个字节)的数据
所以其大小为2*2^19=1MB
3、寄存器映射
给寄存器地址命名的过程
直接操作寄存器的地址 (即利用指针来直接赋值,32位的地址所以是 unsigned int)
4、寄存器地址计算
寄存器地址=BUS_BASE_ADDR+PERIPH_OFFSET+REG_OFFSET
如:GPIOA_ODR = 0x4001 0000+0x800+0x0C = 0x4001 080C
- 总线基地址(BUS_BASE_ADDR)
APB AHB (参考手册 Table 3. Register boundary addresses)
- 外设基于总线基地址的偏移量(PERIPH_OFFSET)
(参考手册 Table 3. Register boundary addresses )
- 寄存器相对于外设基地址的偏移量(REG_OFFSET)
(参考手册9.2.4)
5、通过结构体映射寄存器地址
5.1通过结构体映射
(GPIO的共有7个寄存器 参考手册9.2)
结构体内的地址是是连续的
所以 CRL为0x00 CRH为0x04 (uint32_t 32位 4个字节)
- 强转为结构体指针
其中 UL表示该值的类型为unsigned long
详见 stm32f103xe.h
其中AHB基地址的定义有所不同,直接跳到了DMA1的基地址处
5.2 结构体成员变量地址连续
#include <stdio.h>
typedef struct
{
unsigned int CRL;
unsigned int CRH;
unsigned int IDR;
unsigned int ODR;
unsigned int BSRR;
unsigned int BRR;
unsigned int LCKR;
} GPIO_TypeDef;
int main(){
GPIO_TypeDef gpio_a;
printf(" gpio_a %p\n",&gpio_a);
printf(" CRL: %p\n", &(gpio_a.CRL));
printf(" CRH: %p\n", &(gpio_a.CRH));
printf(" IDR: %p\n", &(gpio_a.IDR));
printf(" ODR: %p\n", &(gpio_a.ODR));
printf(" BSRR: %p\n", &(gpio_a.BSRR));
printf(" BRR: %p\n", &(gpio_a.BRR));
printf(" LCKR: %p\n", &(gpio_a.LCKR));
return 0;
}