寄存器太多,以GPIOA来举例说明:
从STM32的存储映射图可以看到GPIOA的基地址是0x40010800。
GPIOA_CRL 地址:0x40010800 +0x00
GPIOA_CRH 地址:0x40010800 +0x04
GPIOA_IDR 地址: 0x40010800 +0x08
GPIOA_ODR 地址: 0x40010800 +0x0c
GPIOA_BSRR 地址: 0x40010800 +0x10
GPIOA_BRR 地址: 0x40010800 +0x14
GPIOA_LCKR 地址: 0x40010800 +0x18
可以看到地址是以+4递增的。
在看看结构体:
- typedef struct
- {
- __IO uint32_t CRL;
- __IO uint32_t CRH;
- __IO uint32_t IDR;
- __IO uint32_t ODR;
- __IO uint32_t BSRR;
- __IO uint32_t BRR;
- __IO uint32_t LCKR;
- } GPIO_TypeDef;
复制代码
结构体顾名思义就是定义一个固定的机构,或者说是一个模型。
-----------
| CRL | - 0-3BYTE
------------
| CRH | 4-7BYTE
-----------
| IDR | 8 -11BYTE
-----------
| ODR | 12 - 15BYTE
-----------
|BSRR | 16 - 19 BYTE
-----------
| BRR | 20 -23 BYTE
-----------
|LCKR | 24 -27BYTE
-----------
整个模板占用28个字节,即3个字空间。
再看宏定义:
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
大家都知道这里完成了一个强制转换,简单理解就是把模块扣在了无形的一个空间上,让他模型化。如下:
----------- ----------------
| CRL | - 0-3BYTE ____\ | GPIOA_CRL | 0x40010800
------------ / ----------------
----------- ----------------
| CRH | - 4-7BYTE ____\ | GPIOA_CRH | 0x40010800 +4
----------- / ----------------
| IDR | - 8-11BYTE ____\ | GPIOA_IDR | 0x40010800 +8
----------- / ----------------
| ODR | - 12-15BYTE ____\ | GPIOA_ODR | 0x40010800 +12
----------- / ----------------
| BSRR | - 16- 19BYTE ____\ | GPIOA_BSRR | 0x40010800+16
----------- / ----------------
| BRR | - 20-23BYTE ____\ | GPIOA_BRR | 0x40010800 +20
----------- ----------------
| LCKR | - 24-27BYTE ____\ | GPIOA_LCKR| 0x40010800 +24
------------ / ----------------
现在我们可以看到,模板也就是结构体与储存体(寄存器)完成了一一映射。
现在使用 GPIOA->CRL 当然就是操作 GPIOA_CRL寄存器了。 |