这里写自定义目录标题
- 一、位带操作的基本含义及作用
- 二、以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_Adrbit_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)