STM32-(06):位绑定的基础应用

上一篇:STM32-(05):GPIO原理与操作下一篇:STM32-(07):串行通信基础(164芯片)

通过位绑定来快速实现位操作。

这些区域可以进行位绑定
SRAM区:0x2000 0000 ~ 0x200f ffff 1M
公式:A的范围(0x2000 0000 ~ 0x200f ffff) n的范围(0~7),表示第几位 ,AliasAddr表示位绑定的地址
AliasAddr = 0x22000000 + ((A-0x20000000)*8 + n)*4
     = 0x22000000 + (A-0x20000000)32 + n4
     
片上外设:0x4000 0000 ~ 0x400f ffff 1M
公式:A的范围(0x4000 0000 ~ 0x400f ffff) n的范围(0~7),表示第几位,AliasAddr表示位绑定的地址
AliasAddr = 0x42000000 + ((A-0x40000000)*8 + n)*4
     = 0x42000000 + (A-0x40000000)32 + n4
     
拿如下一小段代码举例:

		if((GPIOA->IDR & 0x0800) == 0x0800)		GPIOA->ODR = GPIOA->ODR | 0x08;		
		else						GPIOA->ODR = GPIOA->ODR & (~0x08);

首先看GPIOA->ODR的地址是多少

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
GPIOA_ODR:
A = GPIO_ODR的地址= GPIOA_BASE+ODR偏移地址 = GPIOA_BASE+0x0C (0Ch中的h表示16进制)
n = 3 (0x08表示操作的是第三位)

GPIOA_IDR:(地址查询方法同ODR)
A = GPIO_ODR的地址= GPIOA_BASE+ODR偏移地址 = GPIOA_BASE+0x09 (0Ch中的h表示16进制)
n = 3 (0x0800表示操作的同样是第三位,范围0-7)

int  main(void)
{
//ODR 和 IDR 这里属于片内外设
//ODR的地址:即A=(0x4000000 + 0x10000 + 0x0800 + 0x0c)= 0x4001080c   n=3
u32 *PAO3 = (u32*)(0x42000000 + (0x4001080c - 0x40000000)*32 + 3*4)   //PAO3表示GPIOA输出第3位
//IDR的地址:即A=(0x4000000 + 0x10000 + 0x0800 + 0x09)= 0x40010809   n=3
u32 *PAI11 = (u32*)(0x42000000 + (0x40010809 - 0x40000000)*32 + 3*4)   //PAI11表示GPIOA输入第11位
//或者:u32 *PAI11 = (u32*)(0x42000000 + (0x40010808 - 0x40000000)*32 + 11*4)

//	1、PA.0 ~ PA.7 输出、50Mhz	  PA.8 ~ PA.15 输入(PA.0用到CRL, PA.8用到CRH)
	GPIOA->CRL = 0x33333333; 	//PA.0 ~ PA.7 输出、50Mhz
	GPIOA->CRL = 0x44444444; 	//PA.8 ~ PA.15 输入(选择浮空输入,因为模拟输入与复用输入不经过输入数据寄存器)
//	2、PA.8 ~ PA.15 引脚输入状态影响PA.0 ~ PA.7 引脚输出状态
	while(1)
	{	
		//if((GPIOA->IDR & 0x0800) == 0x0800)		GPIOA->ODR = GPIOA->ODR | 0x08;		
		//else						GPIOA->ODR = GPIOA->ODR & (~0x08);
		//简化为:
		if(*PAI11 == 1)		*PAO3 = 1;	//写1直接置1	
		else			*PAO3 = 0;	//清零直接置0
								
	}
	return(1);
}

继续简化:
1.定义地址
2.定义公式

#define GPIOA_ODR_A	(GPIOA_BASE+0x0C)
#define GPIOA_IDR_A	(GPIOA_BASE+0x08)
#define GPIOA_ODR_B	(GPIOB_BASE+0x0C)
#define GPIOA_IDR_B	(GPIOB_BASE+0x08)
#define GPIOA_ODR_C	(GPIOC_BASE+0x0C)
#define GPIOA_IDR_C	(GPIOC_BASE+0x08)
#define GPIOA_ODR_D	(GPIOD_BASE+0x0C)
#define GPIOA_IDR_D	(GPIOD_BASE+0x08)
#define GPIOA_ODR_E	(GPIOE_BASE+0x0C)
#define GPIOA_IDR_E	(GPIOE_BASE+0x08)

//0x22000000 + (A-0x20000000)*32 + n*4
//0x42000000 + (A-0x40000000)*32 + n*4
//合并为 ((A&0xF0000000) +0x2000000+ ((A&0xfffff)*32) + n*4)
#define BitBand(Addr,BitNum)		* ((volatile unsigned long *)((Addr&0xF0000000) +0x2000000+ ((Addr&0xfffff)<<5) + BitNum*<<2))
#define PAout(n)	BitBand(GPIOA_ODR_A,n)
#define PAin(n) 	BitBand(GPIOA_IDR_A,n)

int  main(void)
{
//	1、PA.0 ~ PA.7 输出、50Mhz	  PA.8 ~ PA.15 输入(PA.0用到CRL, PA.8用到CRH)
	GPIOA->CRL = 0x33333333; 	//PA.0 ~ PA.7 输出、50Mhz
	GPIOA->CRL = 0x44444444; 	//PA.8 ~ PA.15 输入(选择浮空输入,因为模拟输入与复用输入不经过输入数据寄存器)
//	2、PA.8 ~ PA.15 引脚输入状态影响PA.0 ~ PA.7 引脚输出状态
	while(1)
	{	
		//if((GPIOA->IDR & 0x0800) == 0x0800)		GPIOA->ODR = GPIOA->ODR | 0x08;		
		//else						GPIOA->ODR = GPIOA->ODR & (~0x08);
		//简化为:	
		//if(*PAI11 == 1)		*PAO3 = 1;	//写1直接置1	
		//else			*PAO3 = 0;	//清零直接置0
		
		//再简化为:
		if(PAin(11) == 1)		PAout(3) = 1;	//写1直接置1	
		else			PAout(3)  = 0;	//清零直接置0											
	}
	return(1);
}
上一篇:STM32-(05):GPIO原理与操作下一篇:STM32-(07):串行通信基础(164芯片)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值