由上篇博客可知:
存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配,给存储器分配地址的过程就称为存储器映射
相应的地址可以在相应的参考手册中查询
寄存器映射:
给已经有地址的寄存器起别名(宏定义)的过程叫寄存器映射。
外设地址有: PS peripheral 外围设备
PERIPH_BASE 外设基址
APB1PERIPH_BASE APB1基址
APB2PERIPH_BASE APB2基址
AHBPERIPH_BASE AHB基址
由图可知
外设基址 0x4000 0000;
APB1基址 0x4000 0000;
APB2基址 0x4001 0000;
AHB基址 0x4001 8000;
typedef unsigned int uint32_t;
#define PERIPH_BASE ((uint32_t)0x40000000)
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
调用寄存器的话就用*地址
如GPIOB中的寄存器
GPIOB地址为: 0x4001 0C00;
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
#define GPIOB_ODR (GPIOB_BASE+ 0xch) // 0xch 为地址偏移值,寄存器上都由与本外设基址的偏移值。
*GPIOB_ODR = 0x xxxx xxxx; //更改寄存器
C 语言中的结构体语法对寄存器进行封装
#define __IO volatile
typedef struct
{
__IO uint32_t CRL;//偏移0x00
__IO uint32_t CRH;//偏移0x04
__IO uint32_t IDR;//偏移0x08
__IO uint32_t ODR;//偏移0x0c
__IO uint32_t BSRR;//偏移0x10
__IO uint32_t BRR;//偏移0x14
__IO uint32_t LCKR;//偏移0x18
} GPIO_TypeDef;
//GPIOB
#define GPIOB ((GPIO_TypeDef*)GPIOB_BASE)
volatile 从原地址中提取数据,不进行优化。
volatile
将GPIOB_BASE强行转化成结构体的地址。
GPIOB->0DR;//调用