找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5543|回复: 0
打印 上一主题 下一主题
收起左侧

对于STM32的位段和位带别名的理解

[复制链接]
跳转到指定楼层
楼主
ID:83710 发表于 2015-6-24 18:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

          是这样的,记得MCS51吗? MCS51就是有位操作,以一位(BIT)为数据对象的操作,
            MCS51可以简单的将P1口的第2位独立操作: P1.2=0;P1.2=1 ; 就是这样把P1口的第三个脚(BIT2)置0置。
            而现在STM32的位段、位带别名区就为了实现这样的功能。      
            对象可以是SRAM,I/O外设空间。实现对这些地方的某一位的操作。
            它是这样的。在寻址空间(32位地址是 4GB )另一地方,取个别名区空间,从这地址开始处,每一个字(32BIT)
            就对应SRAM或I/O的一位。
            
            这样呢,1MB SRAM就 可以有32MB的对应别名区空间,就是1位膨胀到32位(1BIT 变为1个字)
            我们对这个别名区空间开始的某一字操作,置0或置1,就等于它映射的SRAM或I/O相应的某地址的某一位的操作。

它有什么好处?
             简单来说,可以把代码缩小, 速度更快,效率更高,更安全。
             1.一般操作要6条指令,而使用位带别名区只要4条指令。   
            2.STM32支持了位带操作(bit_band),有两个区中实现了位带。位段的区域:一个是SRAM 区的最低1MB 范围,第二个则是片内外设
            3.区的最低1MB 范围。这两个区中的地址除了可以像普通的RAM 一样使用外,它们还都有自己的“位带别名区”,位带别名区
          4. 把每个比特膨胀成一个32 位的字。    一般操作是  读-改-写  的方式, 而位带别名区是写操作。防止中断对读-改-写  的方式的影响。
         5. 每个比特膨胀成一个32 位的字,就是把  1M  扩展为 32M
         6.支持位带操作的两个内存区的范围是:
         7.0x2000_0000‐0x200F_FFFF(SRAM 区中的最低1MB)
         8.0x4000_0000‐0x400F_FFFF(片上外设区中的最低1MB)
        9.RAM地址 0X200000000(一个字节)扩展到8个32
          位的字,它们是:(STM32中的SRAM依然是8位的,所以RAM中任一地址对应一个字节内容)
   
          0X220000000
         ,0X220000004,0X220000008,0X22000000C,0X220000010,0X220000014,
          0X220000018,0X22000001C
       10.计算公式
       对SRAM 位带区的某个比特,记它所在字节地址为A,位序号
      在别名区的地址为:
      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
      &0xFFFFF)<<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库 高效 十倍 !
      对内存变量的位操作。
         1. // SRAM  变量
         2.
         3. long CRCValue;
         4.
         5. // 把“位带地址+位序号”转换别名地址宏
         6. #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr
      &0xFFFFF)<<5)+(bitnum<<2))
         7. //把该地址转换成一个指针
         8. #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
         9.
        10. // 对32位变量 的BIT1 置 1 :
        11.
        12. MEM_ADDR(BITBAND( (u32)&CRCValue,1)) = 0x1;
        13.
        14. //对任意一位( 第23位 ) 判断:
        15.
        16. if(MEM_ADDR(BITBAND( (u32)&CRCValue,23))==1)
        17. {
        18.
        19. }



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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