位绑定(bit-band)

定义变量到指定的SRAM地址:

__align(8) uint32_t Var __attribute__((at(0x20016FF8))); //MDK中定义

__align(8) :8个字节对齐,即目标地址要能整除8;

防止数据出现不可预料的错误以及提高效率,对齐之后的数据就可以直接进行按位的四则运算了。

 

Cortex™-M4 存储器映像包括两个位带(bit-band)区,一个是SRAM区,另一个是片上外设区。由于不能直接对一个位进行操作,为了实现对寄存器进行快速的位操作,设计了两个别名区。两个位带区将别名区中的每个字映射到位带区的一个位,在别名区写入一个字具有对位带区的目标位执行读-改-写操作的相同效果。

 

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

位别名地址 = 位绑定地址 + (字节偏移×32) + (位偏移×4)。

其中:

位别名地址:位别名存储器区中字的地址,它映像到某个目标位。

位绑定地址:位别名区的起始地址(0x2200 0000和0x4200 0000)

字节偏移:包含目标位的字节在位带里的序号。SRAM位带区的偏移量为(X-0x2000 0000),片上外设区的偏移量为(X-0x4000 0000)。

位偏移:目标位所在位置(0-31)。

举例说明,若想对映射别名区中SRAM 地址为0x2000 0200 的字节中的位2 作位级操作:

位别名地址 = 0x2200 0000 + ((0x20000200-0x2000 0000)×32) + (2×4) = 0x2200 4008

 

应用:

#define GPIOA_ODR_Addr	(GPIOA_BASE+12)
#define GPIOB_ODR_Addr	(GPIOB_BASE+12)
#define GPIOC_ODR_Addr	(GPIOC_BASE+12)
#define GPIOD_ODR_Addr	(GPIOD_BASE+12)
#define GPIOE_ODR_Addr	(GPIOE_BASE+12)

#define GPIOA_IDR_Addr	(GPIOA_BASE+8)
#define GPIOB_IDR_Addr	(GPIOB_BASE+8)
#define GPIOC_IDR_Addr	(GPIOC_BASE+8)
#define GPIOD_IDR_Addr	(GPIOD_BASE+8)
#define GPIOE_IDR_Addr	(GPIOE_BASE+8)

#define BitBand(Addr, Num) (*(__IO uint32_t *)(((0xf0000000&Addr)+0x2000000) + ((Addr&0xfffff)<<5) + (Num<<2)))

#define PAout(n)	BitBand(GPIOA_ODR_Addr, n)
#define PBout(n)	BitBand(GPIOB_ODR_Addr, n)
#define PCout(n)	BitBand(GPIOC_ODR_Addr, n)
#define PDout(n)	BitBand(GPIOD_ODR_Addr, n)
#define PEout(n)	BitBand(GPIOE_ODR_Addr, n)
#define PAin(n)	BitBand((uint32_t)&(GPIOA->IPTDT), n)

PCout(2) ^= 1;		
PCout(3) ^= 1;
PCout(5) ^= 1;

更多关于AT32技术问题,欢迎加QQ群讨论:1053102037


版权声明:本文为Mrli2014原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。