GPIO的寄存器以及ODR和BSRR的区别

发布于:2024-11-29 ⋅ 阅读:(25) ⋅ 点赞:(0)

一、GPIO的寄存器

1. MODER (模式寄存器)

MODER 寄存器控制每个引脚的工作模式。每两个连续的位配置一个引脚的模式。支持的模式包括输入、输出、复用功能、模拟模式。

2. OTYPER (输出类型寄存器)

OTYPER 寄存器控制引脚的输出类型。每个位对应一个引脚的输出类型。可以选择推挽输出(标准输出)或开漏输出(适用于需要外部上拉电阻的场景)。

3. OSPEEDR (输出速度寄存器)

OSPEEDR 寄存器用于配置引脚的输出速度。每两个连续的位配置一个引脚的输出速度,支持低、中、高、极高速选项。

4. PUPDR (上拉/下拉寄存器)

PUPDR 寄存器控制每个引脚的上拉或下拉电阻。每两个连续的位配置一个引脚的上拉或下拉电阻,支持没有电阻、上拉电阻、下拉电阻。

5. IDR (输入数据寄存器)

IDR 寄存器用于读取引脚的输入状态,返回每个引脚的电平状态(高或低)。

6. ODR (输出数据寄存器)

ODR 寄存器用于设置或读取引脚的输出状态。每一位对应一个引脚的输出电平,可以设置为高电平(1)或低电平(0)。

7. BSRR (位设置/复位寄存器)

BSRR 寄存器用于原子地设置或复位引脚的电平。低16位设置引脚为高电平(置1),高16位设置引脚为低电平(置1),此操作是原子性的,不会影响其他引脚。

8. LCKR (锁定寄存器)

LCKR 寄存器用于锁定引脚配置。这是一个16位寄存器,可以防止对特定引脚配置的进一步修改,通常用于保护配置。

9. AFR[0-1] (复用功能寄存器)

AFR[0]AFR[1] 寄存器用于配置引脚的复用功能,选择与外设连接的特定功能(如 UART、SPI、I2C 等)。每个引脚的复用功能通过这两个寄存器中的相应位进行配置。

二、ODR和BSRR的区别

1. ODR 寄存器(Output Data Register)

ODR 寄存器是一个16位寄存器,用于读取或设置 GPIO 引脚的输出状态。

  • 功能:

    • ODR 的每一位对应一个引脚的状态。
    • 通过设置 ODR 寄存器中的位为 1,可以将对应引脚设置为 高电平(1)。
    • 通过设置 ODR 寄存器中的位为 0,可以将对应引脚设置为 低电平(0)。
  • 特点:

    • 批量操作:可以通过一次操作修改多个引脚的状态,适合需要同时改变多个引脚的场景。
    • 可能影响其他引脚:如果修改了 ODR 寄存器中的某一位,可能会意外影响其他位的状态。
    • 不原子:在修改多个引脚时,可能会遇到状态的不一致,尤其是在中断或者多线程环境下。即,修改 ODR 时如果涉及多个引脚,有可能在更新过程中,某些引脚状态处于不一致的中间状态。

高低电平的设置:

2. BSRR 寄存器(Bit Set/Reset Register)

BSRR 寄存器也是一个32位寄存器,用于设置和重置 GPIO 引脚的电平状态。

  • 功能:

    • 低16位:用于 设置引脚为高电平,将对应的引脚置为 1。
    • 高16位:用于 设置引脚为低电平,将对应的引脚置为 0。
  • 特点:

    • 原子操作:每次对 BSRR 的写入会立即生效,并且不会影响其他引脚的状态,操作是独立且原子的。
    • 不会影响其他引脚:与 ODR 不同,BSRR 允许你精确控制某一引脚的电平状态,不会修改其它引脚的状态。
    • 适用于需要精确控制的场景:尤其在多任务或中断环境下,使用 BSRR 可以避免因批量操作引发的不一致问题。

高低电平的设置:

三、BSRR优势

BSRR优点体现:(同时写入PIN3,PIN4不会互相影响高低电平,原因是如果你想把某一位置为低电平你需要在对应的高十六位置1,如下图):

这样才能把PIN3置为低电平。这样有个疑问了,这里的BSRR的高十六位的第4位和低十六位的第四位都是1,不就高低电平冲突了吗?

实际情况是, 写高16位时会优先执行复位(低电平)操作,从而清除任何由低16位设置的高电平。