1.首先谈下为什么要使用位带?
在学习51单片机时就已经使用过位操作,比如使用sbit对单片机IO口的定义,但是STM32中并没有这类关键字,而是通过访问位带别名区来实现,即通过将每个比特位膨胀成一个32位字,当访问这些字的时候就达到了访问比特的目的。比方说BSRR寄存器有32个位,那么可以映射到32个地址上,当我们去访问这32个地址就达到访问32个比特的目的,也就是说我们可以通过位带轻松的去控制某一位。
2.存储单元和存储地址的相关概念
在计算机中最小的信息单位是bit,也就是一个二进制位,8个bit组成一个Byte,也就是字节。一个存储单元可以存储一个字节,也就是8个二进制位。计算机的存储器容量是以字节为最小单位来计算的,对于一个有128个存储单元的存储器,可以说它的容量为128字节。如果有一个1KB的存储器则它有1024个存储单元,它的编号为从0-1023。存储器被划分成了若干个存储单元,每个存储单元都是从0开始顺序编号,如一个存储器有128个存储单元,则它的编号就是从0-127。
存储地址一般用十六进制数表示,而每一个存储器地址中又存放着一组二进制(或十六进制)表示的数,通常称为该地址的内容。值得注意的是,内储单元的地址和地址中的内容两者是不一样的。前者是存储单元的编号,表示存储器总的一个位置,而后者表示这个位置里存放的数据。正如一个是房间号码,一个是房间里住的人一样。
存放一个机器字的存储单元,通常称为字存储单元,相应的单元地址叫字地址。而存放一个字节的单元,称为字节存储单元,相应的地址称为字节地址。如果计算机中可以编址的最小单元是字存储单元,则该计算机称为按字寻址的计算机。如果计算机中可编址的最小单位是字节,则该计算机称为按字节寻址的计算机。如果机器字长等于存储器单元的位数,一个机器字可以包含数个字节,所以一个存储单元也可以包含数个能够单独编址的字节地址。例如一个16位二进制的字存储单元可存放两个字节,可以按字地址寻址,也可以按字节地址寻址。当用字节地址寻址时,16位的存储单元占两个字节地址。(摘自百度百科)
以STM32来说,STM32是一个32位的微控制器,它是按字存储单元;每一个寄存器都是占用4个字节即32位,这点将在下面位带和位带别名地址换算的时候用到
3.Cortex-M3位带区和位带映射区对应关系
STM32位带及位带别名区域支持位带操作的区域是SRAM 区的最低1MB 范围(APB1/2,AHB1外设)和片内外设区的最低1MB范围。
对于SRAM/GPIO位带区的某个比特(bit),记它所在的字节地址为A,位序号为n(0<=n<=7)(如果是GPIO则n<=16),则该比特在位带别名区中的地址为:
AliasAddr=0x22000000+((A-0x20000000)*8+n)*4
上式中‘8’表示每个字节中有8个比特,‘4’表示4个字节(因为CM3是32位机,机器字为4个字节)。
(A-0x20000000)表示一共用这么多个字节,(A-0x20000000)*8+n表示一共有这么多位,在别名区中,每个位占4个字节地址,故((A-0x20000000)*8+n)*4表示该位在别名区中的偏移字节地址。偏移地址加上基地址就是该比特在位带别名区中的地址