Chapter 13 GPIO——位带操作
位带简介
STM32 中,两个地方实现了位带,
- SRAM 区的最低 1MB 空间
- 外设区的最低 1MB 空间
外设位带区
| 0x40000000 ~ 0x40100000
0x42000000 ~ 0x43FFFFFF
0x40000000 ~ 0x40029FFF
|
SRAM 位带区
| 0x20000000 ~ 0x20100000
0x22000000 ~ 0x23FFFFFF
|
位带区和位带别名区的地址转换
1、外设位带别名区地址
对于片上外设位带区的某个位,记它所有字节的地址为 A,位序号为 n =[0, 7],则该位在别名区的地址为:
| AliasAddr = 0x42000000 + (A - 0x40000000)*8*4 + n*4
|
2、SRAM 位带别名区地址
| AliasAddr = 0x22000000 + (A - 0x20000000)*8*4 + n*4
|
3、统一公式
|
AliasAddr = (addr & 0xF0000000) + 0x02000000 + ((addr & 0x00FFFFFF)<<5) + (bitnum<<2)
|
| #define BITBAND(addr, bitnum) ((addr & 0xF0000000) + 0x02000000 + ((addr & 0x00FFFFFF)<<5) + (bitnum<<2))
|
4、通过指针的形式操作这些位带别名区地址,最终实现位带区的操作
| #define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR( BITBAND(addr, bitnum) )
|
GPIO 位带操作
演示 GPIO 中的 ODR 和 IDR 这两个寄存器的位操作
ODR 和 IDR 这两个寄存器对应的 GPIO 基地址偏移是 12 和 8
1、GPIO 寄存器映射
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #define GPIOA_ODR_Addr (GPIOA_BASE + 12) #define GPIOB_ODR_Addr (GPIOB_BASE + 12) #define GPIOC_ODR_Addr (GPIOC_BASE + 12) #define GPIOD_ODR_Addr (GPIOD_BASE + 12) #define GPIOE_ODR_Addr (GPIOE_BASE + 12) #define GPIOF_ODR_Addr (GPIOF_BASE + 12) #define GPIOG_ODR_Addr (GPIOG_BASE + 12)
#define GPIOA_IDR_Addr (GPIOA_BASE + 8) #define GPIOB_IDR_Addr (GPIOB_BASE + 8) #define GPIOC_IDR_Addr (GPIOC_BASE + 8) #define GPIOD_IDR_Addr (GPIOD_BASE + 8) #define GPIOE_IDR_Addr (GPIOE_BASE + 8) #define GPIOF_IDR_Addr (GPIOF_BASE + 8) #define GPIOG_IDR_Addr (GPIOG_BASE + 8)
|
2、GPIO 位操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #define PAout(n) BIT_ADDR(GPIOA_ODR_Addr, n) #define PAin(n) BIT_ADDR(GPIOA_IDR_Addr, n) #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr, n) #define PBin(n) BIT_ADDR(GPIOB_IDR_Addr, n) #define PCout(n) BIT_ADDR(GPIOC_ODR_Addr, n) #define PCin(n) BIT_ADDR(GPIOC_IDR_Addr, n) #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr, n) #define PDin(n) BIT_ADDR(GPIOD_IDR_Addr, n) #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr, n) #define PDin(n) BIT_ADDR(GPIOD_IDR_Addr, n) #define PEout(n) BIT_ADDR(GPIOE_ODR_Addr, n) #define PEin(n) BIT_ADDR(GPIOE_IDR_Addr, n) #define PFout(n) BIT_ADDR(GPIOF_ODR_Addr, n) #define PFin(n) BIT_ADDR(GPIOF_IDR_Addr, n) #define PGout(n) BIT_ADDR(GPIOG_ODR_Addr, n) #define PGin(n) BIT_ADDR(GPIOG_IDR_Addr, n)
|
3、main 函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
int main(void) { LED_GPIO_Config(); while(1) { PAout(5) = 1; SOFT_DELAY; PAout(5) = 0; SOFT_DELAY; } }
|