OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6657|回复: 2

位带的计算,不知道我的理解对吗,希望大家一块交流啊。

[复制链接]

16

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
154
金钱
154
注册时间
2013-9-23
在线时间
0 小时
发表于 2014-8-25 15:21:48 | 显示全部楼层 |阅读模式

       今天我看来看关于位带的操作啊,自己有了点想法。其它低处理器里面没有位带操作。而STM32里有。而关于位带的计算我看了一会刚开始也是很迷不知道怎么计算。后来自信想想终于明白了。所以就给大家分享一下。

       大家不要被它那复杂的计算公式给迷惑了。按步骤的理解理解就可以了。

      首先它固定支持位带操作的区:

       支持位带操作的两个内存区的范围是:0x2000_0000‐0x200F_FFFF(SRAM区中的最顶1MB)和0x4000_0000‐0x400F_FFFF(片上外设区中的最低1MB)

     它的位带思路就是把这2个区里边的每一位,也就是每一比特用一个32位的字给重新表示出来,其实给映射差不都。只不过是一个比特映射一个字。你只要把这一点给记住了。理解计算方法就很是简单了。

 别名地址=0x2200000+((A-0x20000000)*8+n)*4= 0x22000000+ (A0x20000000)*32 + n*4 咱就来一步一步的分析它怎么得来的。

A-0x20000000:获得与0x20000000的字节偏移量。

(A-0x20000000)*8:表示该位在的字节前与0x20000000的第一个位之间有多少位。

(A-0x20000000)*8+n:到这里就算出来与0x20000000的第一位总共偏移的位。

((A-0x20000000)*8+n)*4:以为每一位映射到新的地址空间的时候被作为一个字了。所以他的地址不能单纯的把位的个数当成字节数,而是当成了字数,要想当成字节那就要乘以4,因为每个字里面有4个字节。

0x2200000+((A-0x20000000)*8+n)*4:加上映射过去的首地址,不就是该位映射过去的新的字地址了吗。


我也不知道我理解的对不对希望我们共同交流啊。

我自信,我努力,我成功
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2014-8-25 23:29:52 | 显示全部楼层
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

16

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
154
金钱
154
注册时间
2013-9-23
在线时间
0 小时
 楼主| 发表于 2014-8-26 16:28:26 | 显示全部楼层
其实我在写这个的时候想了想位带的使用。费这么大的劲到底给我的编程带来那些好处呢?
如果你要是用过51你就知道了。我们在操作51的时候对每个引脚是不是能直接操作。比如P0^1.但是我们在STM32里面的端口如果没有用位带比如我们仍要操作B10的输出ODR。我们要这么做:为1时GPIOB_ODR |=1<<10,为0时GPIOB_ODR &= ~(1<<10);
但是如果我们用了位带我们可以这样做:
#defined led Bout(10)
    led = 1;  //赋值为1
led = 0;  //赋值为0
简单多了吧。这就是原因。


代码跟踪:
PBout(10)<--PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n):
BIT_ADDR是位带:BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))
MEM_ADDR(addr)  *((volatile unsigned long  *)(addr));BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
所以可以看出来BIT_ADDR的作用是把addr字节地址里面的bitnum(表示的一个为0-7)用一个32位的字来重新表示。
④GPIOB_ODR_Addr<---- GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C
表示的是B口的ODR寄存器的地址。
所以上面那个PBout(10)就代表把B口的ODR寄存器的第10位给位带操作了。
我自信,我努力,我成功
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 23:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表