位带简介

位操作就是可以单独的对一个比特位读和写, 51 单片机中通过关键字 sbit 来实现位定义, STM32 没有这样的关键字,而是通过访问位带别名区来实现。
在 STM32 中,有两个地方实现了位带,一个是 SRAM 区的最低 1MB 空间,令一个是外设区最低 1MB 空间。这两个 1MB 的空间除了可以像正常的 RAM 一样操作外,他们还有自己的位带别名区,位带别名区把这 1MB 的空间的每一个位膨胀成一个 32 位的字,当访问位带别名区的这些字时,就可以达到访问位带区某个比特位的目的
位带地址转换
位带区的一个位,对应位带别名区的四个字节。一个字节对应一个地址。
8表示一个地址对应一个字节,一个字节有8个位,4表示1位对应4个别名区的字节(地址)

使用位带方式访问寄存器
main.c
#include "stm32f10x.h"#include "bsp_led.h"#include "bsp_key.h"#define GPIOB_ODR_Addr (GPIOB_BASE+ 0x0C)#define PBout(n) *(unsigned int*)((GPIOB_ODR_Addr & 0xF0000000)+0x02000000+((GPIOB_ODR_Addr & 0x00FFFFF)<<5)+(n<<2))#define GPIOA_IDR_Addr (GPIOA_BASE+ 0x08)#define PAin(n) *(unsigned int*)((GPIOA_IDR_Addr & 0xF0000000)+0x02000000+((GPIOA_IDR_Addr & 0x00FFFFF)<<5)+(n<<2))#define GPIOC_IDR_Addr (GPIOC_BASE+ 0x08)#define PCin(n) *(unsigned int*)((GPIOC_IDR_Addr & 0xF0000000)+0x02000000+((GPIOC_IDR_Addr & 0x00FFFFF)<<5)+(n<<2))void Delay( uint32_t count){for(;count != 0;count--);}//void GreenLed(uint32_t t)//{// LED_G(ON);// LED_B(OFF);// LED_R(OFF);// Delay(t);//}//void BlueLed(uint32_t t)//{// LED_G(OFF);// LED_B(ON);// LED_R(OFF);// Delay(t);//}//void RedLed(uint32_t t)//{// LED_G(OFF);// LED_B(OFF);// LED_R(ON);// Delay(t);//}int main(void){LED_G_GPIO_Config();LED_B_GPIO_Config();KEY1_GPIO_Config();KEY2_GPIO_Config();#if 0while(1){PBout(0) = 1;PBout(1) = 1;Delay(0xFFFFF);PBout(0) = 0;Delay(0xFFFFF);PBout(0) = 1;Delay(0xFFFFF);PBout(1) = 0;Delay(0xFFFFF);PBout(1) = 1;Delay(0xFFFFF);PBout(0) = 0;PBout(1) = 0;Delay(0xFFFFF);}#elsewhile(1){// if(Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_Pin) == KEY_ON)// {// LED_G_TOGGLE;//// }//// if(Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_Pin) == KEY_ON)// {// LED_B_TOGGLE;//// }if(PAin(0) == KEY_ON){while(PAin(0) == KEY_ON);LED_G_TOGGLE;}if(PCin(13) == KEY_ON){while(PCin(13) == KEY_ON);LED_B_TOGGLE;}}#endif}
