这里写自定义目录标题
- 一、位带操作的基本含义及作用
- 二、以STM32为例
- 三、位带别名区和位带区(寄存器地址位地址)的转换关系
- 四、使用例程
一、位带操作的基本含义及作用
位带别名区的设计主要是为了**方便对位带区单个比特位进行读写操作**。在某些应用场景下,
需要频繁地对位带区某个特定的比特位进行读写操作,但是由于处理器架构中并没有提供直接读写
位带区单个比特位的指令,因此需要使用一定的位运算来实现。但是,这样会使得代码复杂且容易出错。
位带别名区的出现,就是为了解决这个问题。它通过为位带区每个比特位分配一个独立的物理地址,以便能够
直接对某个特定的比特位进行读写操作,从而避免了手动进行位运算的麻烦和出错风险。实际上,位带别名区
就是在内存中专门开辟出来的一段空间,其中的每4个字节都与原始内存中的某个特定的比特位相映射,从而可
以直接对该比特位进行读写操作
二、以STM32为例
STM32就要两个位带区:一个是SRAM存储寄存器映射区,二是外设位带区
(把寄存器的每一个位映射成一个 32 位的字)
如上图所示:
一个是SRAM存储寄存器映射区:
0x2000 0000–0x2000 0FFF是SRAM(静态随机存取)的物理地址
0x20001000–0x3FFF FFFF是保留部分内存,它的目的就是为了以某一种关系把0x2000 0000–0x2000 0FFF的每一个位映射到0x20001000–0x3FFF FFFF的空间中,实现一个比特位转换为一个字的空间(STM32的一个地址存储一个4个字节(32位)的内容),这种关系下面再详细说明
二是外设位带区
0x4000 0000–0x4002 03F7是各种外设寄存器的物理地址
而0x4002 03F8–Ox5FFF FFFF是保留部分内存,功能和上面说得一样
三、位带别名区和位带区(寄存器地址位地址)的转换关系
下面是它们的转换公式:
(Base_Adr +0x02000000+ byte_offset * 32) + (bit_number * 4)
Base_Adr是位带区的基地址,
byte_offset 表示该比特位在位带区中的偏移量,如果知道某一寄存器的实际物理位置
为Reg_Adr,则byte_offset =Reg_Adr - Base_Adr
bit_number 则是该比特位在所在字节中的位偏移量。
对SRAM说:Base_Adr = 0x20000000u
对外设位带区说:Base_Adr = 0x40000000u
四、使用例程
#define GPIO_BITBAND_REG(Reg,Bit) (*((uint32_t volatile*)\
(0x40000000u +0x02000000u+ (((uint32_t)&(Reg) - (uint32_t)0x40000000u)\
<<5) + (((uint32_t)(Bit))<<2))))
//GPIO_OUT
#define PA0_OUT GPIO_BITBAND_REG(GPIOA->ODAT, 0)
#define PA1_OUT GPIO_BITBAND_REG(GPIOA->ODAT, 1)
#define PA2_OUT GPIO_BITBAND_REG(GPIOA->ODAT, 2)
#define PA3_OUT GPIO_BITBAND_REG(GPIOA->ODAT, 3)
#define PA4_OUT GPIO_BITBAND_REG(GPIOA->ODAT, 4)
#define PA5_OUT GPIO_BITBAND_REG(GPIOA->ODAT, 5)
#define PA6_OUT GPIO_BITBAND_REG(GPIOA->ODAT, 6)
#define PA7_OUT GPIO_BITBAND_REG(GPIOA->ODAT, 7)
#define PA8_OUT GPIO_BITBAND_REG(GPIOA->ODAT, 8)
#define PA9_OUT GPIO_BITBAND_REG(GPIOA->ODAT, 9)
#define PA10_OUT GPIO_BITBAND_REG(GPIOA->ODAT, 10)
#define PA11_OUT GPIO_BITBAND_REG(GPIOA->ODAT, 11)
#define PA12_OUT GPIO_BITBAND_REG(GPIOA->ODAT, 12)
#define PA13_OUT GPIO_BITBAND_REG(GPIOA->ODAT, 13)
#define PA14_OUT GPIO_BITBAND_REG(GPIOA->ODAT, 14)
#define PA15_OUT GPIO_BITBAND_REG(GPIOA->ODAT, 15)
#define PB0_OUT GPIO_BITBAND_REG(GPIOB->ODAT, 0)
#define PB1_OUT GPIO_BITBAND_REG(GPIOB->ODAT, 1)
#define PB2_OUT GPIO_BITBAND_REG(GPIOB->ODAT, 2)
#define PB3_OUT GPIO_BITBAND_REG(GPIOB->ODAT, 3)
#define PB4_OUT GPIO_BITBAND_REG(GPIOB->ODAT, 4)
#define PB5_OUT GPIO_BITBAND_REG(GPIOB->ODAT, 5)
#define PB6_OUT GPIO_BITBAND_REG(GPIOB->ODAT, 6)
#define PB7_OUT GPIO_BITBAND_REG(GPIOB->ODAT, 7)
#define PB8_OUT GPIO_BITBAND_REG(GPIOB->ODAT, 8)
#define PB9_OUT GPIO_BITBAND_REG(GPIOB->ODAT, 9)
#define PB10_OUT GPIO_BITBAND_REG(GPIOB->ODAT, 10)
#define PB11_OUT GPIO_BITBAND_REG(GPIOB->ODAT, 11)
#define PB12_OUT GPIO_BITBAND_REG(GPIOB->ODAT, 12)
#define PB13_OUT GPIO_BITBAND_REG(GPIOB->ODAT, 13)