文章目录[隐藏]
位带操作
在STM32中有一块位带别名区(Bit band alias),对这个区域进行操作等于直接对寄存器中的位(位带区:Bit Band region)进行操作;其中位带区中的每一个位在位带别名区会被膨胀成 4 个byte,也就是下图中 1M 膨胀成 32M
1.外设位带区和外设位带别名区
外设位带区起始 地址从0x40000000开始,0x400FFFFF结束
外设位带别名区起始 地址从0x42000000开始,0x43FFFFFF结束
2.SRAM位带区和SRAM位带别名区
SRAM位带区起始 地址从0x20000000开始,0x200FFFFF结束
SRAM位带别名区起始 地址从0x22000000开始,0x23FFFFFF结束
3.位带区和位带别名区的地址转换:
AliasAddr = 0x42000000 + ( A - 0x40000000 ) * 8 * 4 + n * 4
AliasAddr = 0x22000000 + ( A - 0x20000000 ) * 8 * 4 + n * 4
AliasAddr:位带别名区地址
A:位所在寄存器地址
( A - 0x40000000 ) * 8:偏移地址的字节数所占的位数
( A - 0x20000000 ) * 8 * 4:偏移地址的字节数所占的位数膨胀后所占的字节偏移量
n * 4:第n个位所偏移的字节
4.地址转换的代码实现
/*
addr:位带区对应的寄存器地址
bitnum:位号
*/
/*
(addr&0xf0000000)+0x02000000 对应 SRAM/外设 别名区地址
(addr&0x000fffff)<<5 对应 (A - 0x40000000) * 8 * 4
(bitnum<<2) 对应 n * 4
*/
/* 求出位带别名区地址 */
#define BITBAND(addr, bitnum) ((addr&0xf0000000)+0x02000000+((addr&0x000fffff)<<5)+(bitnum<<2))
/* 32位编译器中,int和long都是占4个字节,unsigned int和unsigned long并没有区别 */
/* 对地址进行指针操作 */
#define MEM(addr) (*(unsigned long *)(addr))
/* 对位带别名区的内存进行指针操作 */
#define BIT_ADDR(addr, bitnum) (MEM(BITBAND(addr, bitnum)))
/* 求GPIOE_ODR的地址 */
#define GPIOE_ODR_addr (GPIOE_BASE+0x14)
/* 对GPIO_ODR的位带别名区进行宏定义,可以直接通过PEout(n)直接对其ODR的对应位进行操作(位带操作) */
#define PEout(n) (BIT_ADDR(GPIOE_ODR_addr,n))
版权声明:本文为CSDN博主「Thui1」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wu_wen_/article/details/121927605
暂无评论