1.概念理解
位带操作实际就是通过将寄存器的一个位(bit)映射到某一个区域的字(32位)上,这些区域的字已经由官方设定好,我们通过对这些字的操作就能够实现对寄存器的某个位操作。图像如下
stm32一个字有4个字节共32个位,膨胀之后为在别名区为4*8=32个字。所以接下来要做的就是根据位带区地址找到位带别名区的字地址。
以GPIOF—ODR寄存器的bit9为例,该寄存器地址为0x4002 1414,相对GPIO偏移量为0x21414,膨胀为字后的别名区地址为0x2141448=0x428280,所以在位别名区从0x42428280开始的32个字区域均是ODR寄存器膨胀,由于4个字节组成一个字,对于bit0偏移为0,bit9就是9*4,也即是0x24,所以最终的地址计算公式如下:
Addr = 0x4200 0000+(A - 0x4000 0000)48 +bit*4
其中A是寄存器地址。0x4200 0000是外设位带别名区起始地址。
将SRAM和片上外设结合起来公式如下:
Addr = (addr&0xF000 0000)+0x200 0000+(addr&0x00FF FFFF)<<5+(bit<<2)
2.代码实现
找到ODR输出寄存器的地址,再找到对应位带别名区的地址,并定义一个带参函数如下:
代码:
#define AddrB_ODR (GPIOB_BASE+0x0C)
#define PBout(n) *(unsigned int*)((AddrB_ODR & 0xF0000000)+0x2000000+((AddrB_ODR & 0x00FFFFFF)<<5)+(n<<2))
其中对地址应该强制类型转换为指针,再对指针进行操作。
主函数控制代码如下:
int main(void)
{
GPIO_LED_Config();
while(1)
{
//实现灯的闪烁
PBout(0) = 1;
Delay(0xFFFFF);
PBout(0) = 0;
Delay(0xFFFFF);
}
}
void Delay(uint32_t count)
{
for(;count !=0;count--);
}
值得一提的是,尽管一个位bit膨胀为位带别名区的 一个字,但是这个字仅仅最低位有效。这么操作是因为stm32系统总线是32位,这样处理效率更高。
标签:位带,32,ODR,别名,地址,理解,寄存器,操作 From: https://www.cnblogs.com/manchestercity/p/17843328.html