STM32 “位带地址+位序号” 转换成位带别名区地址的宏

这一篇知乎大佬的文章对于程序逻辑说的很透彻

GPIO — 位带操作 - 嵌入式职场的文章 - 知乎 https://zhuanlan.zhihu.com/p/389410483

这里再说一说自己的理解吧,如有错误,希望大家严加拷打!

在STM32中支持位带操作的有SRAM区的最低1MB范围和片内外设区的最低1MB范围

其中SRAM支持的位带区地址有一个共同特点就是0x200开头,位带别名区有一个共同特点都是0x220开头

GPIO类似,位带区都是以0x400开头,位带别名区都是以0x420开头

位带区地址类似于字节地址。STM32单片机寄存器一共32位也就是4个字节,所以相邻寄存器的位带区地址的递增值为4。(图中0x2000 0000、0x2000 0004、0x2000 0008...)

除了讨论相邻寄存器之间的位带区地址,其实每一个寄存器内部32bit一共4个字节也构成了4个位带区地址(位带区地址都是以字节为单位的)。

位带区可以对应“膨胀”到位带别名区,意思就是把位带区对应字节中的每一个位映射出一个地址,以上图STM32的SRAM位带区(位带区基地址0x2000 0000,位带别名区基地址0x2200 0000)为例,相邻位之间在位带别名区的地址递增关系是4,所以位带别名区地址的最后一位形成一种圆周循环的规律“0、4、8、C、0、4、8、C...”

举一个栗子,如果要得到SRAM区某一个寄存器(位带区地址为0x2000 0004)的第17位对应的位带别名区地址该如何操作呢?

首先计算该寄存器位带区地址相对于SRAM位带区基地址(0x2000 0000)的偏移量,0x2000 0004 - 0x2000 0000 = 4,也就是4个字节,对应偏移了4 * 8 = 32位 。再计算位带别名区的地址偏移量,刚才讲到位带别名区相邻位的地址递增量是4,所以32*4 = 128 对应16进制的0x80(图一中位带区地址0x2000 0004对应到位带别名区的地址0x2200 0080,你看最后两位正好就是0x80吧)

然后计算该寄存器的第17位在该寄存器位带别名区中地址偏移量,因为在位带别名区中位地址的递增值是4,所以有17 * 4 = 68。

综上,这个寄存器的第17位对应的位带别名区地址偏移量等于 128 + 68 = 196(0xC4)。而位带别名区的基地址是0x2200 0000 ,所以这个寄存器的第17位对应的位带别名区地址为 0x2200 0000 + 0xC4 = 0x2200 00C4

 在正点原子的System文件夹中关于GPIO位带操作的一个宏定义如下(已提前宏定义了addr):

#define BITBAND(addr,bitnum) ((addr & 0xF0000000) + 0x02000000 + ((addr & 0x000FFFFF) << 5) + (bitnum << 2))

 addr & 0xF000 0000 : 识别addr(寄存器的位带区地址)是SRAM还是片内外设,因为高四位是1111其他位是0,所以按位与运算结果就是保留addr的高四位,其他位置零。

再举一个栗子,如果是SRAM的话,开头说了位带区共同特点是头3位均为16进制200,对应二进制0010 0000 0000,SRAM相与结果就是0x2000 0000 对应二进制0010 0000 0000....如果是GPIO的话,位带区开头特点前三位是16进制400,所以相与结果就是 0x4000 0000。

addr & 0xF000 0000 的结果(以GPIO为例)就是0x4000 0000,再加上0x0200 0000 结果就是0x4200 0000 这正好就是GPIO对应的位带别名区基地址!

 addr & 0x000FFFFF:同理,由于位带区地址addr的16进制头三位400不变,这里相与的结果就是保留16进制后五位,这样就计算出了位带区的地址偏移量,左移五位就是乘以2的五次方等于32,是不是很熟悉呢,就是计算对应位带别名区的地址偏移量。

bitnum左移两位就是乘以2的二次方等于四,是不是依然很熟悉呢,当然就是计算寄存器具体的某一位在该寄存器位带别名区中的地址偏移量~

把上述所有的计算结果相加,就得到了具体GPIO的某一位对应的位带别名区地址了~

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值