首先来看CM3储存器的映射图
在地址0x2000 0000 ~ 0x2010 0000和0x2200 0000~ 0x23FF FFFF这两段地址都共同指向同一片内存区域。
那么要给0x4000 0000这个地址上的第二位置1,传统方法就是:
#define DEVICE_REG0 ((volatile unsigned long *) (0x40000000)) //指针DEVICE_REG0指向0x4000 0000这个地址
那当我们要往这个地址上的写0x0D这个值时,应该用语句:
*DEVICE_REG0 = 0x0D //0xAB就是0000 1101
如果要向这个地址上的第二位置1时:
*DEVICE_REG0 = *DEVICE_REG0 | 0x02;
当芯片支持位带操作后,我们就可以对地址上的某一位进行单独操作。
直观的来看:0x2000 0000这个地址上有八位,每次对这个地址进行操作时不能对上面某一位进行操作,只能整体进行。
当我们对地址0x2200 0000(是地址0x2000 0000的位带别名区)进行操作时,例如向这个地址上面写1。
#define DEVICE_REG0_BIT0 ((volatile unsigned long *) (0x42000000))
DEVICE_REG0_BIT0 = 0x01;
DEVICE_REG0_BIT0=0xFF; //两个的效果是一样,因为这个地址上的值只是LSB有效,并且这个地址上的值操作的就是对0x2000 0000这个地址上的第0位进行置1。
位带别名区和位带区之间的对应关系,也就是位带区某个地址上的某一位 :所对应的位带别名区上的某个地址上的整体值
公式如下:
对于C语言如何进行位带操作参考COTEX M3权威指南第五章。
CM3技术指导手册第四章储存器映射