STM32位带操作及别名区详解

这里写自定义目录标题

  • 一、位带操作的基本含义及作用
  • 二、以STM32为例
  • 三、位带别名区和位带区(寄存器地址位地址)的转换关系
  • 四、使用例程
  • 一、位带操作的基本含义及作用

    	位带别名区的设计主要是为了**方便对位带区单个比特位进行读写操作**。在某些应用场景下,
    	需要频繁地对位带区某个特定的比特位进行读写操作,但是由于处理器架构中并没有提供直接读写
    	位带区单个比特位的指令,因此需要使用一定的位运算来实现。但是,这样会使得代码复杂且容易出错。
    
       位带别名区的出现,就是为了解决这个问题。它通过为位带区每个比特位分配一个独立的物理地址,以便能够
       直接对某个特定的比特位进行读写操作,从而避免了手动进行位运算的麻烦和出错风险。实际上,位带别名区
       就是在内存中专门开辟出来的一段空间,其中的每4个字节都与原始内存中的某个特定的比特位相映射,从而可
       以直接对该比特位进行读写操作
    

    二、以STM32为例

    STM32就要两个位带区:一个是SRAM存储寄存器映射区,二是外设位带区
    (把寄存器的每一个位映射成一个 32 位的字)
    

    STM32物理内存映射

    如上图所示:
    一个是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)
    

    作者:琉璃惘蘩

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32位带操作及别名区详解

    发表评论