一、位带操作的基本概念
1,位带别名区,
1MB
的空间的每一个位膨胀成一个
32
位的字,当访问位带别名区的这些
字时,就可以达到访问位带区某个比特位的目的;
2,位带别名区,分为两个部分:①外设别名;②SRAM别名
3,
虽然变大到
4
个字节,但是还是
LSB
才有效
二、位带区与位带别名区转化
这边主要说,外设别名区的转化到位带,本质上在转化完成的区域对32位区域操作,继而实现对外设区域的某一位的操作;
具体转化规则:
AliasAddr =0x42000000+ (A-0x40000000)*8*4 +n*4
其中,0x42000000是别名区的起始地址,0x40000000是外设区的起始地址,n是所在寄存器的位
转化之后的操作,在转化后的别名区,对该地址内的数据进行操作,并且只有最低字节是有效的
AliasAddr =0x42000000+ (A-0x40000000)*8*4 +n*4;
newbang =*(uint32*)AliasAddr ;
newbang=1;
newbang=0;
实际上在stm32中的位带区转化公式(考虑到SARM的转化)
#define BITBAND(addr, bitnum)
*(uint32_t *)((addr & 0xF0000000)+0x02000000+\
((addr &0x00FFFFFF)<<5)+(bitnum<<2))
三、举例
位带区操作LED点亮
初始化GPIO
#include "led.h"
void LED_config(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin=LED_G;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init( LED_PORT, &GPIO_InitStruct);
}
主函数操作
void delay(uint32_t count)
{
while(count)
{
count--;
}
}
int main(void)
{
LED_config();
while(1)
{
BITBAND(GPIOB_BASE+0x0c,5)=0;
delay(0xfffff);
BITBAND(GPIOB_BASE+0x0c,5)=1;
delay(0xfffff);
}
}