开发者社区> 杨奉武> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

STM32 中 BIT_BAND(位段/位带)和别名区使用入门(转载)

简介: 一、 什么是位段和别名区 是这样的,记得MCS51吗? MCS51就是有位操作,以一位(BIT)为数据对象的操作,MCS51可以简单的将P1口的第2位独立操作: P1.2=0;P1.2=1 ;这样就把P1口的第三个脚(BIT2)置0置1。
+关注继续查看

一、 什么是位段和别名区

是这样的,记得MCS51吗? MCS51就是有位操作,以一位(BIT)为数据对象的操作,MCS51可以简单的将P1口的第2位独立操作: P1.2=0;P1.2=1 ;这样就把P1口的第三个脚(BIT2)置0置1。而现在STM32的位段、位带别名区就为了实现这样的功能。

它的对象可以是SRAM、I/O和外设空间。要实现对这些地方的某一位的操作。它是这样做的:在寻址空间(32位对应的地址空间为 4GB )的另一地方,取个别名区空间,从这个地址开始处,每一个字(32BIT)对应SRAM或I/O的一位。 
这样,1MB SRAM 就可以有 32MB 的对应别名区空间,就是1位膨胀到32位(1 BIT 变为1个字节)。我们对这个别名区空间内的某一字操作(置0或置1),就等于它映射的 SRAM 或 I/O 相应的某地址的某一位的操作。

二、 使用位段的好处 

简单来说,可以把代码缩小, 速度更快,效率更高,更安全。 一般操作要6条指令,而使用位带别名区只要4条指令。一般操作是 读-改-写 的方式, 而位带别名区是 写 操作。防止中断对 读-改-写 的方式的影响。

三、应用说明

支持了位带操作(bit_band),有两个区中实现了位带。其中一个是SRAM 区的最低1MB 范围,第二个则是片内外设区的最低1MB 范围。这两个区中的地址除了可以像普通的RAM 一样使用外,它们还都有自己的“位带别名区”,位带别名区把每个比特膨胀成一个 32 位的字。 每个比特膨胀成一个32 位的字,就是把 1M 扩展为 32M 。

于是,位于 RAM 地址 0X200000000 的一个字节扩展为8个32 位的字,扩展后每位相对应的的地址是:0X220000000,0X220000004,0X220000008,0X22000000C,0X220000010,0X220000014, 0X220000018,0X22000001C

支持位带操作的两个内存区的范围是:

0x2000 0000‐0x200F FFFF(SRAM 区中的最低1MB) 
0x4000 0000‐0x400F FFFF(片上外设区中的最低1MB)

对 SRAM 位带区的某个比特,记该比特所在字节的地址为A,位序号为 n (0<=n<=7),则它在别名区的地址为:

AliasAddr = 0x22000000 + ((A‐0x20000000)*8+n)*4 =0x22000000 + (A‐0x20000000)*32 + n*4

对于片上外设位带区的某个比特,记该比特所在字节的地址为A,位序号为 n (0<=n<=7),则该比特在别名区的地址为:

AliasAddr = 0x42000000 + ((A‐0x40000000)*8+n)*4 = 0x42000000 + (A‐0x40000000)*32 + n*4

上式中,“*4”表示一个字为 4 个字节,“*8”表示一个字节中有 8 个比特。

把“位带地址+位序号”转换别名地址宏为:

#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000 + ((addr &0xFF FFF)<<5) + (bitnum<<2))

把该地址转换成一个指针:

#define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) 
MEM_ADDR(BITBAND( (u32)&CRCValue,1)) = 0x1;

例如点亮LED

使用STM32库: 
GPIO_ResetBits(GPIOC, GPIO_Pin_4); //关LED5 
GPIO_SetBits(GPIOC, GPIO_Pin_7);  //开LED2

一般读操作: 
STM32_Gpioc_Regs->bsrr.bit.BR4 =1;// 1:清除对应的ODRy位为0 
STM32_Gpioc_Regs->bsrr.bit.BS7 =1;// 1:设置对应的ODRy位为1

如果使用位带别名区操作: 
STM32_BB_Gpioc_Regs->BSRR.BR[4] =1;// 1:清除对应的ODRy位为0 
STM32_BB_Gpioc_Regs->BSRR.BS[7] =1;// 1:设置对应的ODRy位为1

代码比STM32库高效十倍 !

对内存变量的位操作:

SRAM 变量:long CRCValue;

把“位带地址+位序号”转换别名地址宏:

#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))

把该地址转换成一个指针:

#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))

对32位变量 的BIT1 置 1 :

MEM_ADDR(BITBAND( (u32)&CRCValue,1)) = 0x1;

对任意一位( 第23位 ) 判断:

if(MEM_ADDR(BITBAND( (u32)&CRCValue,23))==1) 
{

}

四、Cortex-M3中关于位段的定义

Cortex-M3 存储器映像包括两个位段(bit-band)区。这两个位段区将别名存储器区中的每个字映射到位段存储器区的一个位,在别名存储区写入一个字具有对位段区的目标位执行 读-改-写操 作的相同效果。

所有STM32F10x外设寄存器都被映射到一个位段(bit-band)区。这个特性在各个函数中对单个比特进行置1/置0操作时被大量使用,用以减小和优化代码尺寸。

映射公式映射

公式给出别名区中的每个字是如何对应位带区的相应位的,公式如下:

bit_word_offset = (byte_offset x 32) + (bit_number × 4) 
bit_word_addr = bit_band_base + bit_word_offset

其中: 
bit_word_offset是目标位在存取器位段区中的位置 
bit_word_addr 是别名存储器区中字的地址,它映射到某个目标位。 
bit_band_base 是别名区的起始地址。 
byte_offset 是包含目标位的字节在位段中的序号 
bit_number 是目标位所在位置(0-31)

 

注明:我是从http://blog.sina.com.cn/s/blog_9f27507501011gg1.html此博客转载而来,原作者不得而知,在此感谢原作者!

努力才可成功!信仰不是别人给你说一百遍的一句话,而是你被撞的头破血流后的幡然悔悟!有时候一个道理你会花几年才会明白。虽然这只是一个简单的道理!

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【古月21讲】ROS入门系列(4)——参数使用与编程方法、坐标管理系统、tf坐标系广播与监听的编程实现、launch启动文件的使用方法
【古月21讲】ROS入门系列(4)——参数使用与编程方法、坐标管理系统、tf坐标系广播与监听的编程实现、launch启动文件的使用方法
61 0
Python3 使用pli优化图片大小,相机或手机拍图片根据exif旋转、纠正方向
首先安装 pip install pillow 如果报错,请根据报错的信息去搜索一下,一般都能得到解决,未找到请升级pip python -m pip install --upgrade pip 或者 pip install --upgrade pip 那么写个方法 from PIL import.
780 0
亮风台2D AR算法新突破,夺冠世界权威评测 | ICRA 2108
亮风台提出的基于约束置信度的鲁棒跟踪算法(CCM),提高了在局部遮挡、光照变化和运动模糊等各种因素干扰情况下的鲁棒性。
376 0
wpa_supplicant对wep,wpa,wpa2的psk和隐藏ap的scan_ssid扫描配置
# 请不要修改下面这一行内容,否则将不能正常工作ctrl_interface=/var/run/wpa_supplicant# 确保只有root用户能读取WPA的配置ctrl_interface_group=0# 使用wpa_supplicant来扫描和选择APap_scan=1# 简单的情形:WPA-PSk密码验证方式,PSK是ASCII密码短语,所有合法的加密方式都允许连接network={ ssid="simple" psk="very secret passphrase" # 优先级越高,就能越早匹配到。
1887 0
【第三篇】Volley图片加载之NetworkImageView代码分析
在Volley的使用之加载图片讲过使用NetWorkImageView进行图片加载的例子,本文着重讲解NetWorkImageView内部是如何实现的,以及Volley这个控件有什么特性。   1,通过几个构造方法,可见NetworkImageView并没有添加自己的自定义属性,而是继承自Imageview的自定义属性。
739 0
使用 jQuery & CSS3 制作美丽的照片画廊
  在本教程中,我们将创建一个很好看的照片画廊效果。我们的想法是,以显示专辑作为一个滑块,而当这张专辑被选中,我们将使用一个美丽的照片堆栈展示专辑的图像。在照片堆栈视图,我们可以通过将最上面的图像移动到所有照片后面的方式浏览。
819 0
使用VS2010编译Webkit r116410 ( Nightly Build @ 2012-5-8 )
转载请注明出处:http://blog.csdn.net/horkychen   Webkit Night Build不能直接支持VS2010,需要自己多做些事情。
930 0
+关注
杨奉武
优秀不够,你是否无可替代;知识从未如此性感 --群1: 235371864 --群2: 607064330 --QQ:946029359 --淘宝 https://shop411638453.taobao.com/
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载