找回密码
 立即注册

QQ登录

只需一步,快速开始

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

抛砖引玉之位段操作

[复制链接]
跳转到指定楼层
楼主
ID:64689 发表于 2014-8-20 16:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
抛砖引玉之位段操作
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:51088 发表于 2014-8-20 17:00 | 只看该作者
Cortex?-M3存储器映像包括两个位段(bit-band)区。这两个位段区将别名存储器区中的每个字映射到位段存储器区的一个位,在别名存储区写入一个字具有对位段区的目标位执行读-改-写操作的相同效果。
在STM32F10xxx里,外设寄存器和SRAM都被映射到一个位段区里,这允许执行单一的位段的写和读操作。
下面的映射公式给出了别名区中的每个字是如何对应位带区的相应位的:
bit_word_addr = bit_band_base + (byte_offset x 32) + (bit_number × 4)
其中:
bit_word_addr是别名存储器区中字的地址,它映射到某个目标位。
bit_band_base是别名区的起始地址。
byte_offset是包含目标位的字节在位段里的序号
bit_number是目标位所在位置(0-31)

在 CM3  支持的位段中,有两个区中实现了位段。

其中一个是 SRAM 区的最低 1MB 范围, 0x20000000 ‐ 0x200FFFFF(SRAM 区中的最低 1MB);

第二个则是片内外设区的最低 1MB范围, 0x40000000 ‐ 0x400FFFFF(片上外设区中的最低 1MB)。

在 C 语言中使用位段操作

在 C编译器中并没有直接支持位段操作。比如,C 编译器并不知道对于同一块内存,能够使用不同的地址来访问,也不知道对位段别名区的访问只对 LSB 有效。欲在 C中使用位段操作,最简单的做法就是#define 一个位段别名区的地址。例如:

#define DEVICE_REG0 ((volatile unsigned long *) (0x40000000))

#define DEVICE_REG0_BIT0 ((volatile unsigned long *) (0x42000000))

#define DEVICE_REG0_BIT1 ((volatile unsigned long *) (0x42000004))

...

*DEVICE_REG0 = 0xab;        //使用正常地址访问寄存器

*DEVICE_REG0_BIT1 = 0x1;  

还可以更简化:

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

#define BITBAND(addr, bitnum)((addr & 0xF0000000)+0x2000000+((addr & 0xFFFFF)<<5)+(bitnum<<2))  
  //把该地址转换成一个指针

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

于是:

MEM_ADDR(DEVICE_REG0) = 0xAB;     //使用正常地址访问寄存器  

MEM_ADDR(BITBAND(DEVICE_REG0,1)) = 0x1;  //使用位段别名地址

注意:当你使用位段功能时,要访问的变量必须用 volatile 来定义。因为 C 编译器并不知道同一个比特可以有两个地址。所以就要通过 volatile,使得编译器每次都如实地把新数值写入存储器,而不再会出于优化的考虑 ,在中途使用寄存器来操作数据的复本,直到最后才把复本写回。

实际上,在写程序是都有这样的定义:

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

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

#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))

然后定义:#define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C

最后操作:#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出 ODR保存要输出的数据;IDR保存读入的数据
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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