GPIO的IDR寄存器、ODR寄存器以及BSRR寄存器

IDR (Input Data Register, 输入数据寄存器)

        每个GPIO端口对应一个IDR寄存器(如GPIOA一个IDR寄存器,GPIOB又一个寄存器),而每一个GPIO引脚(如GPIO_PIN_0)对应IDR寄存器的一位,IDR寄存器的位值对应该引脚的电平【0-0(逻辑低),1-1(逻辑高)】

        例如STM32为32位的处理器,其数据总线宽度、寄存器宽度和指令集都是32位的,故其IDR寄存器也是32位的。如果 GPIO 端口支持 16 个引脚(例如 GPIOA),IDR 的低 16 位(位 0 ~ 15)对应 GPIOA 的引脚 0 到引脚 15。剩余的高 16 位(位 16 ~ 31)是未使用的,在这种情况下,这些位通常是固定的 0。如下图所示则表示GPIO_PIN_15和GPIO_PIN_9为高电平,其余为低电平.

IDR寄存器
位数3130...161514131211109876543210
位值00...01000001000000000

实际应用示例:

补充:GPIO_PIN_13是位掩码,对应0x2000 = 0010 0000 0000 0000

#define    DATA_READ_GPIO          GPIOD                   
#define    DATA_READ_PIN           GPIO_PIN_13 

uint8_t Data=0;
//高位先行
for(int i=7;i--;i>=0)
{
    if(DATA_READ_GPIO->IDR&GPIO_PIN_13==1)Data|=1<<i;    
    else Data|=0<<i;
}


ODR 寄存器Output Data Register,输出数据寄存器)

        同IDR寄存器,每一个GPIO引脚(如GPIO_PIN_0)对应IDR寄存器的一位,IDR寄存器的位值对应该引脚的电平【0-0(逻辑低),1-1(逻辑高)】,也是32位。高16位为0,低16位一一对应,只不过ODR是输出,IDR是输入。

实际应用示例:

//精准控制
GPIOA->ODR|=GPIO_PIN_13;    //GPIOA的第13号引脚输出高电平
GPIOA->ODR|=~GPIO_PIN_13;   //GPIOA的第14号引脚输出低电平

//LED闪烁
GPIOA->ODR ^= GPIO_PIN_13;  // 翻转 LED 状态

BSRR 寄存器Bit Set/Reset Register,位设置/复位寄存器)

BSRR位结构
位数功能描述
0-15Set位写入 1 设置对应引脚为高电平(0-15号引脚)
16-31Reset位写入 1 设置对应引脚为低电平(0-15号引脚)

 

相对ODR寄存器的优点是:

通过一次写入寄存器的方式,可以同时设置多个引脚为高电平或低电平,避免因中断或任务切换导致的不一致问题。例如:可以同时设置 GPIO 引脚 13 为高电平,同时将 GPIO 引脚 14 拉低。

实际应用示例:

GPIOC->BSRR = GPIO_PIN_13;          // 写入 BSRR 的第 13 位(0~15),引脚 13 被置位
GPIOC->BSRR = GPIO_PIN_13 << 16;    // 写入 BSRR 的第 29 位(16~31),引脚 13 被复位

GPIOC->BSRR = GPIO_PIN_13 | (GPIO_PIN_14 << 16);  //将引脚13拉高,同时将引脚14拉低

如果BSRR 第0位和第16位同时置1。最终,GPIO_PIN_0设置复位操作会覆盖置位操作,GPIO_PIN_0 引脚的状态为 低电平.

【使用BSRR相对ODR的优点是能够避免竞态问题】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值