STM32的位带操作是基于cortex内核自带的,而不是st公司独创。基本的思路就是用一个32位的地址空间访问一个bit,因为stm32只支持32位数据的读取,不像51单片机一样,是可以单独对一位操作的。因此,arm开发了位带技术,以提高位操作的速度。
stm32中SRAM地址范围=0x2000 0000~0x200F FFFF,共1MB
stm32中SRAM位带地址范围=0x2200 0000~0x23FF FFFF,共32MB
stm32中FLASH地址范围=0x4000 0000~0x400F FFFF,共1MB
stm32中FLASH位带地址范围=0x4200 0000~0x43FF FFFF,共32MB
位带技术就是用操作32位地址以代替操作1-bit的
举例:
运用位带访问GPIOB_BSRR的bit 5。
GPIOB_BSRR地址为0x4001 0C00 + 0x10,外设的基地址为0x4000 0000,所以GPIOB_BSRR与外设的基地址总共相差(0x4001 0C00-0x4200 0000)个字节(byte),每个字节8bit,额外加上5个bit
=(0x4001 0C00-0x4000 0000)*8+5个bit
回到位带运算中,位带区一个32bit,即4byte代表一个bit,增加一个bit,位带别名区的地址增加4个字节(即增加32bit),那么最终位带别名区的地址是:
0x4200 0000+((0x4001 0C00-0x4000 0000)*8+5)*4 = 0x4221 8014
0x4200 0000+((0x4001 0C00-0x4000 0000)*32 + 5*4 = 0x4221 8014
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
参考手册里有如下解释:
Cortex™-M3存储器映像包括两个位段(bit-band)区。这两个位段区将别名存储器区中的每个字映射到位段存储器区的一个位,在别名存储区写入一个字具有对位段区的目标位执行读-改-写操作的相同效果。
在STM32F10xxx里,外设寄存器和SRAM都被映射到一个位段区里,这允许执行单一的位段的写和读操作。
下面的映射公式给出了别名区中的每个字是如何对应位带区的相应位的:
bit_word_addr = bit_band_base + (byte_offset×32) + (bit_number×4)
其中:
bit_word_addr是别名存储器区中字的地址,它映射到某个目标位。
bit_band_base是别名区的起始地址。
byte_offset是包含目标位的字节在位段里的序号
bit_number是目标位所在位置(0-31)
例子:
下面的例子说明如何映射别名区中SRAM地址为0x20000300的字节中的位2:
0x22006008 = 0x22000000 + (0x300×32) + (2×4).
对0x22006008地址的写操作与对SRAM中地址0x20000300字节的位2执行读-改-写操作有着相
同的效果。
和上面的异曲同工之妙。