你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32如何进行位绑定

[复制链接]
huachuixuezhiwu 发布时间:2020-2-21 13:02
在我们学习51单片机的时候,对IO的操作可直接使用P0^1=0,P0^2=1,控制某个IO口就可以单独的对某个端口的IO口进行操作,但在STM32中是不能直接这样用的,为了可以像使用51单片机一样对某个端口的IO口进行直接操作方便我们使用,就出现了位带操作。

2 S4 X, {0 N. U. g  {
位绑定理解:

' L' f8 B; `8 z- `7 ?8 D/ D' q4 ?
STM32对外设端口的操作是通过配置相应的寄存器的位来完成的,位绑定就是把对寄存器某一位的操作映射到某个内存地址,通过位绑定后我们可以使我们的的代码效率更高,对外设的操作更加方便。
下图显示了Cortex-M3 存储器的映射

9 X5 J; [! z6 A, T
11.png

6 @/ q& l1 M3 a. B% ~3 U0 ]5 ?1 h
从图中我们可以看出STM32存储映射区包括两个位绑定区(bit band区)。分别为SRAM区域中的低1MB地址即(0X20000000~0x200FFFFF)和外设存储区的低 1MB地址处(0x4000 0000 ~ 0x400F FFFF)。我们都知道STM32是32的,最快捷的操作方法就是操作一个32的地址,所以STM32有设计出了别名区,对32MB SRAM的别名区的访问映射为1M SRAM位绑定区(Bit Band)的访问,对 32MB 外设别名区的访问映射为对 1MB 外设位绑定区(Bit Band)区的访问。为什么别名区会是位带区的32倍呢?因为位带区是以位为单位,每八个位为一个地址,而别名区是以字为单位,每个字等于4个字节,就是32位。

/ @! v# o. Y8 P
位绑定区的地址映射如下所示:

6 A' X1 ^0 n3 f9 v
22.png
  G3 Q0 z6 _  y' Y- ~& i
从上图中可以看出位带区0x20000000的第0位对应的地址是0x22000000-0X22000003 这4个字节,这里我们需要注意的是只有起始的地址0x2200000,0x22000004,这样4的倍数的地址才能被访问。所以就有了以下的对应地址:

& G! Y( a4 {" ?( U" K
33.png
5 x5 R; u+ R7 p8 t; s
映射的算法:

7 f. j4 ]6 f" c6 |  k3 T6 u0 F
对于位绑定的公式官方给出的如下:

. ?; l/ `3 |. |5 l1 s
44.png

4 K% ?) {5 u/ w
比如我们要访问的内存寄存器的地址为add;n为对应的每一位
SRAM区映射的地址 =0x22000000 + ((add- 0x20000000) * 8 + n) * 4 = 0x22000000 + ((add - 0x20000000)* 32 + n * 4
片上外设区映射的地址 = 0x42000000 + ((add -0x40000000) * 8 + n) * 4= 0x42000000 + ((add - 0x40000000) * 32 + n * 4
n*4是因为1位要用4个地址单元即前面说的只有4的倍数的地址才能被访问。
byte_offset*32(add- 0x20000000)*32因为位带区的一个位要扩张到别名区的32个位,byte_offset*32是前面已经占用的地址。
  ^) d: V5 j; t2 A& h
程序实现:
0 S+ Z) E$ |4 m' U2 {) x3 A5 K
#define BITBAND(addr, bitnum) ((addr &0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsignedlong *)(addr))
#define BIT_ADDR(addr, bitnum)MEM_ADDR(BITBAND(addr, bitnum))
#define GPIOA_ODR_Addr (GPIOA_BASE+20)
#define GPIOA_IDR_Addr (GPIOA_BASE+16)//0x40020010

( `' w, J: i0 \4 `8 |
对IO口操作

: l$ C5 }6 j% ^9 [* K
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n)//输出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n)//输入
因为不知道其是SRAM还是片上外设的映射,所以我们取其高位addr & 0xF0000000,然后加上0x2000000,
这样无论是SRAM还是片上外设的映射都可以得到其对应的别名区基地址,addr &0xFFFFF(add=0x2000_0000‐0x200F_FFFF0x4000_0000‐0x400F_FFFF)屏蔽高三位就相当于与add- 0x20000000和add - 0x40000000
<<5就相当于乘32,<<2就是乘以4,因为左移的速度比乘的要快,所以把乘都改为了左移。

% k+ N# @4 @8 V2 s
赞 收藏 1 评论2 发布时间:2020-2-21 13:02

举报

2个回答
Kevin_G 回答时间:2020-2-22 19:56:24
收藏
aiherong 回答时间:2020-2-23 02:26:56
好像ST将位带从后续产品中删除了,可以同时用与非两操作绑定位!! J0 ^# |: G# b4 j8 [
比如: |=0x0003和&=0xFFFC就置位第0,1两位
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版