历史上的今天
今天是:2025年08月12日(星期二)
2019年08月12日 | STM32-(06):位绑定的基础应用
2019-08-12 来源:eefocus
通过位绑定来快速实现位操作。
这些区域可以进行位绑定
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);
}
史海拾趣
|
请大家帮忙推荐一款带AD的FPGA开发板,14bit AD,xilinx FPGA,最好是spartan3e的, 哪位高手对此熟悉的话帮忙推荐一下,谢谢了~… 查看全部问答> |
|
大众运营市场是运营商多年来极力推广的一个市场,但实际推广得还不太好。国内大部分运营商参与这块市场,目前主要针对的不是普通用户和私人企业,而是政府用户为主。他们采取先垫资,然后向政府收取运营费用的方式进行,主要集中在公共场所监控领域 ...… 查看全部问答> |
|
我在做一个程控交换机的计费软件和能控制程控交换机的软件,是用串口通信的,牌子是国威的ws82(10),,请问通信的协议的什么,,格式是什么。。。。 有没有人知道啊… 查看全部问答> |
|
创建的纯资源DLL(电量图标)系统始终加载不上是什么原因?内付代码 首先是注册表的修改: [HKEY_LOCAL_MACHINE\\Security\\ResOver\\Bitmaps] \"BaseDll\"=string:\"batteryIcon.dll\" \"BatteryIconIdStart\"=dword:100 \"BatteryIconLevels\"=dword:1 BaseDll points to the DLL from which overridden bi ...… 查看全部问答> |
|
正版软件实在太贵,个人买恐怕负担不起的, KEIL C166 V6正版42000元 TASKING C166 V8.5我们公司几个人用花了10000多元 现在我把公司买的正版TASKING C166 V8.5与大家分享一下. 如果谁有KEIL C166 V6的我希望也和大家分享一下, 共同使用,共同学 ...… 查看全部问答> |
|
现做两单片机之间的串行通信仿真实验,当我用共阴极LED时,其显示发生错误,但是当我换成共阳极LED时,其显示正确。用共阴极或共阳极时,其显示段码也换成相应的显示段码。段码应该没有错,因为我用它做LED静态或动态显示时是正确的。 代码如下: ...… 查看全部问答> |
|
请帮忙看看,我的uart0串口中断程序哪里错在哪里?按理说只要收到一个字节就应该进中断,可调试过程中只能进一次中断而且收到的数据不对,请大家指点。 void US0_handler (void) { unsigned short status,data; st ...… 查看全部问答> |
|
自从 Xilinx 推出 FPGA 二十多年来,研发工作大大提高了 FPGA 的速度和面积效率,缩小了 FPGA 与 ASIC 之间的差距,使 FPGA 成为实现数字电路的优选平台。今天,功耗日益成为 FPGA 供应商及其客户关注的问题。 降低 FPGA 功耗是缩减封装和散热成本 ...… 查看全部问答> |




