STM32学习笔记3——位带操作

学习资料:《野火零死角玩转STM32——F103》

STM32可以像51一样对寄存器的某一个位进行操作,即位操作。

位带区在片上外设和片上SRAM中,各1MB。位带别名区把每个位膨胀成32位的字。

STM32的全部寄存器都可以通过访问位带别名区的方式访问原始寄存器比特位的效果。

转换公式:

A =  addr & 0xF0000000)+0x02000000+((addr & 0x00FFFFFF)<<5)+(n <<2))

其中 ,addr为寄存器的地址;n为寄存器比特位。

 

位带操作点亮LED灯——GPIO口的输入和输出

头文件与STM32学习笔记2的相同,主函数如下:

main.c

#include "stm32f10x.h" 
#include "bsp_led.h"   //led的控制头文件
#include "bsp_key.h"   //key的控制头文件
//位带操作转换公式
#define BITBAND(addr, n)    *(unsigned int*)((addr & 0xF0000000)+0x02000000+((addr & 0x00FFFFFF)<<5)+(n <<2))

#define GPIOA_ODR_Addr      (GPIOA_BASE+12) //0x4001080C 
#define GPIOB_ODR_Addr      (GPIOB_BASE+12) //0x40010C0C 
#define GPIOC_ODR_Addr      (GPIOC_BASE+12) //0x4001100C 
#define GPIOD_ODR_Addr      (GPIOD_BASE+12) //0x4001140C 
#define GPIOE_ODR_Addr      (GPIOE_BASE+12) //0x4001180C 
#define GPIOF_ODR_Addr      (GPIOF_BASE+12) //0x40011A0C 
#define GPIOG_ODR_Addr      (GPIOG_BASE+12) //0x40011E0C 
 
#define GPIOA_IDR_Addr      (GPIOA_BASE+8) //0x40010808 
#define GPIOB_IDR_Addr      (GPIOB_BASE+8) //0x40010C08 
#define GPIOC_IDR_Addr      (GPIOC_BASE+8) //0x40011008 
#define GPIOD_IDR_Addr      (GPIOD_BASE+8) //0x40011408 
#define GPIOE_IDR_Addr      (GPIOE_BASE+8) //0x40011808 
#define GPIOF_IDR_Addr      (GPIOF_BASE+8) //0x40011A08 
#define GPIOG_IDR_Addr      (GPIOG_BASE+8) //0x40011E08

 // 单独操作 GPIO 的某一个 IO 口,n(0,1,2...16),n 表示具体是哪一个 IO 口
#define PAout(n)    BITBAND(GPIOA_ODR_Addr,n) //输出 
#define PAin(n)     BITBAND(GPIOA_IDR_Addr,n) //输入 

#define PBout(n)    BITBAND(GPIOB_ODR_Addr,n) //输出 
#define PBin(n)     BITBAND(GPIOB_IDR_Addr,n) //输入 

#define PCout(n)    BITBAND(GPIOC_ODR_Addr,n) //输出 
#define PCin(n)     BITBAND(GPIOC_IDR_Addr,n) //输入 
 
#define PDout(n)    BITBAND(GPIOD_ODR_Addr,n) //输出 
#define PDin(n)     BITBAND(GPIOD_IDR_Addr,n) //输入 

#define PEout(n)    BITBAND(GPIOE_ODR_Addr,n) //输出 
#define PEin(n)     BITBAND(GPIOE_IDR_Addr,n) //输入 
 
#define PFout(n)    BITBAND(GPIOF_ODR_Addr,n) //输出 
#define PFin(n)     BITBAND(GPIOF_IDR_Addr,n) //输入 
 
#define PGout(n)    BITBAND(GPIOG_ODR_Addr,n) //输出 
#define PGin(n)     BITBAND(GPIOG_IDR_Addr,n) //输入



#if 0
void Delay( uint32_t count ) //软件延迟
{
  for(; count!=0; count-- );
}

 int main(void)
 {
	 LED_GPIO_Config(); 
 //初始化后引脚全部置0,RGB全亮,故需把它们关闭
	   PBout(5) = 1;      
	   Delay(0xFFFFF);
	   PBout(0) = 1; 
		 Delay(0xFFFFF);
		 PBout(1) = 1; 
		 Delay(0xFFFFF);
//流水灯循环
	 while(1)
	 {
		 //红
		 PBout(5) = 0; 
		 Delay(0xFFFFFF);
		 PBout(5) = 1; 	
		 //绿
		 PBout(0) = 0;
		 Delay(0xFFFFFF);
		 PBout(0) = 1;
		 //蓝		 
		 PBout(1) = 0;
		 Delay(0xFFFFFF); 
		 PBout(1) = 1;
		 //黄
		 PBout(5) = 0;
		 PBout(0) = 0;
		 Delay(0xFFFFFF);
		 PBout(5) = 1; 
		 PBout(0) = 1;
		 //淡蓝
		 PBout(0) = 0;
		 PBout(1) = 0;
		 Delay(0xFFFFFF);
		 PBout(0) = 1;
		 PBout(1) = 1;
		 //紫
		 PBout(5) = 0;
		 PBout(1) = 0;
		 Delay(0xFFFFFF);
		 PBout(5) = 1; 
		 PBout(1) = 1;
		 //白
		 PBout(5) = 0;
		 PBout(0) = 0;
		 PBout(1) = 0;
		 Delay(0xFFFFFF);
		 //关闭
		 PBout(5) = 1; 
		 PBout(0) = 1;
		 PBout(1) = 1;
		 Delay(0xFFFFFF);		 		 
	 }	 
 }
 #else
 int main(void)
 {
	 LED_GPIO_Config(); 
	 KEY1_GPIO_Config(); 
	   PBout(5) = 1;      
	   PBout(0) = 1; 
		 PBout(1) = 1; 
	 while(1)
   {
	   if (PAin(0)==1)   //按键检测
	   {
			 while(PAin(0)==1){};  //松手检测
 		   LED_G_TOGGLE;
       LED_B_TOGGLE;			 
	   }
   }
 }
 #endif

 

你可能感兴趣的:(STM32学习笔记3——位带操作)