购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1. 4.2 位带操作

1.位带概念

位带(bit-band)操作更像C语言中的union与struct相结合后的位操作。为了更好地理解它,下面先举一个例子:

由上述程序可知,通过myBitband. Bitband_Alias_Bits. Alias0 的访问是通过对myBitBand. BitBand的第 0 位操作实现的。

Cortex-M3 的位带操作类似于上面的C语言操作方式,但区别在于BitBand与Bitband_Alias_Bits是两块独立的内存地址,而且位带操作中的Alias0 代表一个 32 位的数据,但只有最低 0 位是有效数据。

Cortex-M3 支持了位带操作后,可以使用普通的加载/存储指令来对单一的比特进行读/写。在Cortex-M3 中,有两个区中实现了位带:一个是 SRAM区的最低 1MB范围(0x20000000-0x200FFFFF),对应的位带别名区是 0x22000000~0x23FFFFFF;第二个则是片内外设区的最低 1MB范围(0x40000000~0x400FFFFF),对应的别名区是 0x42000000~0x43FFFFFF。

映射公式显示如何将别名区中的字与 bit-band 区中的对应位或目标位关联。映射公式举例:

这里:

如图 1-6 所示为SRAM位带区与对应的别名区之间的关系图。图 1-6 中箭头所指映射的转换关系如下:

图 1-6 SRAM位带区与对应的别名区之间的关系图

2.位带操作方法

向别名区中的一个字执行写操作会更新位带区中的单个位。但并不是别名区的所有位都有效,别名区的一个字的第0位是有效的,会影响对应位带区的数值,即向别名区中的一个字写入值的位[0]决定了写入位带区中目标位的值:写入一个位[0]设为 1 的值,则会向位带位写入一个 1;写入一个位[0]设为 0 的值,则会向位带位写入一个 0。

注意: 别名字的位[31:1]对位带位无影响,写入 0x01 与写入 0xFF效果相同,写入 0x00与写入 0x0E效果相同。

读取别名区中的一个字,如读取数据为

(1)0x00000000,表示位带区中的目标位被设为 0;

(2)0x00000001,表示位带区中的目标位被设为 1。

位带区的访问可通过字节、半字、字的方式进行访问。

通过C语言实现对Cortex-M3 的位带操作一般使用宏定义方式进行,并通过“1 位带概念”中的位带与别名区映射公式进行。下列代码给出的定义中采用了右移代替乘法运算。

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

小知识: 对于volatile声明的变量,编译器在访问该变量的代码时不再进行优化,从而可以提供对特殊地址的稳定访问。

下列程序演示了通过位带方式操作SPI控制寄存器的过程。

3.位带操作的用途

对应于LPC17XX的外设,所有外设(除了以太网、USB、DMA、GPIO以外)都位于位带操作区域。APB 0与APB1 对应的外设内存都属于位带区域。

注意: 由于GPIO不属于位带区,所以如果经常需要设置引脚状态时,不能通过位带方式进行操作。 /vRpQPu41YINKv2fNGaCFM658ZQ4atpTUiu91VfsHvlNJ+N6b/SFA6kA+Bw9HfHJ

点击中间区域
呼出菜单
上一章
目录
下一章
×