赞
踩
以往我们在使用暂存器时,都是在操作该暂存器32bits(4bytes)的储存地址,要对其中单一bit进行操作,可以仰赖bit operation来完成。而bit-banding(位带操作)的目的就是实现直接操作单一比特位
为了达成这个目的首先我们有必要理解STM32的特殊存储区段位带区与位带别名区。
下图中的红色方框代表位带区的范围,可以看到SRAM中位带区佔有1MB,外设区段部分,1MB的储存范围刚好涵盖了AHB, APB1, APB2,可以说我们使用的大部分外设,例如GPIO, UART, SPI等等都在位带区当中
外设的位带区地址范围: 0x40000000~0x400F0000
SRAM的位带区地址范围: 0x20000000~0x200FFFFF
位带区不仅可以用来储存暂存器数据外还有一个膨胀32倍位带别名区,这个位带别名区就是操作单一比特位的关键。首先我们来看看为何位带别名区是位带区的32倍
如图所示,每个比特位都可以用一个完整的32bits地址来代替,有就是说一个32bits的暂存器在位带别名区会被扩展成32*32=1024bits,因此位带别名区的储存空间为1MB的位带区空间乘上32等于32MB。由此可知,我们可以直接操作位带别名区地址来达到操作位带区单一比特位的目的
需要注意膨胀过后的位带别名区只有LSB(最低位)比特位有效
不过要操作位带别名区之前须要先知道位带区与位带别名区之间的关係,幸好地址之间的转换是有迹可循的:
0x42000000 + (A-0x40000000)*32+n*4
0x22000000 + (A-0x20000000)*32+n*4
上述公式可以拆解成: 位带别名区地址 = 位带别名区首地址 + (目标位带区地址 - 位带区首地址)*32 + 第n个比特位*4
该转换公式简单来说就是地址膨胀后的位置运算,各个位带别名区的起始位置为:
0x42000000
0x22000000
为了在运算当中不用在程式中编写两个不同的运算式,我们试着将两个公式用一条语句来完成:
(bit_band_addr & 0xf0000000) + 0x02000000 + ((bit_band_addr & 0x000fffff << 5) + n << 2)
位带操作的实作非常简单,主要就下列4个步骤,其中最重要的就是地址转换以及转换成指标类型
因为我们计算出来的"地址"充其量也就只是一个整数值而已,必须经过类型转换告诉编译器它是一"地址",引此我们使用macro来处理运算出来的位带别名区数值
下列程式码我们只要使用macroBIT_GPIOH(暂存器地址, 比特位)
就可以成功转换成位带别名区地址:
#define BITBAND(addr
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。