stm32学习之路——八种GPIO口工作模式

目录

一、GPIO基本功能

二、GPIO工作模式

三、GPIO硬件结构

四、GPIO寄存器

五、GPIO库函数配置

六、GPIO应用实例

七、开漏输出细说

什么是开漏输出?

为什么需要开漏输出?

总结

八、好奇问题解决


一、GPIO基本功能

  1. 输出功能:STM32的GPIO口可以控制引脚输出高电平或低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等。
  2. 输入功能:GPIO口可以读取引脚的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等。
  3. 复用功能:GPIO口还可以作为STM32其他片上外设的功能引脚,实现更复杂的通信和控制功能。

二、GPIO工作模式

STM32的GPIO共有8种工作模式,分为4种输入模式和4种输出模式:

  1. 输入模式

    • 浮空输入:引脚既不接高电平也不接低电平,电平状态由外部输入决定。适用于电平不稳定的输入信号,如按键输入。
    • 上拉输入:引脚内部通过一个上拉电阻与VDD相连,无信号输入时默认电平为高电平。适用于需要稳定高电平输入的场合。
    • 下拉输入:引脚内部通过一个下拉电阻与GND相连,无信号输入时默认电平为低电平。适用于需要稳定低电平输入的场合。
    • 模拟输入:引脚直接输入模拟信号,不进行数字化处理。适用于ADC采集电压等需要原始模拟信号的场合。
  2. 输出模式

    • 推挽输出:可以输出高电平或低电平,连接数字器件。推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通时另一个截止。
    • 开漏输出:只能输出低电平,高电平时引脚为高阻态,需要外部上拉电阻才能输出高电平。适用于I2C等需要"线与"功能的总线电路。
    • 推挽复用输出:GPIO口被复用为其他外设的输出引脚,工作于推挽输出模式。
    • 开漏复用输出:GPIO口被复用为其他外设的输出引脚,工作于开漏输出模式。

三、GPIO硬件结构

  1. 保护二极管:STM32的GPIO引脚内置两个保护二极管,用于防止引脚外部过高或过低的电压输入损坏芯片。
  2. 施密特触发器:用于对输入信号进行整形,消除脉冲噪声的影响。
  3. 上拉/下拉电阻:可通过配置寄存器启用或禁用,以控制引脚的默认电平状态。
  4. 输出驱动器:由P-MOS和N-MOS管组成,根据输出模式控制引脚的电平状态。

四、GPIO寄存器

STM32的每组GPIO都包含多个寄存器,用于配置和控制GPIO口的工作状态:

  1. 端口配置低/高寄存器(GPIOx_CRL/GPIOx_CRH):用于配置GPIO引脚的工作模式(输入、输出、复用、模拟等)和端口输出速度。
  2. 端口输入数据寄存器(GPIOx_IDR):只读寄存器,用于读取GPIO引脚当前的输入电平状态。
  3. 端口输出数据寄存器(GPIOx_ODR):用于设置GPIO引脚当前的输出电平状态。
  4. 端口位设置/清除寄存器(GPIOx_BSRR):可以直接置位或复位指定的GPIO引脚,而不影响其他引脚的状态。
  5. 端口位清除寄存器(GPIOx_BRR):用于清除指定的GPIO引脚的状态。
  6. 端口配置锁定寄存器(GPIOx_LCKR):用于锁定GPIO端口的配置,防止被意外修改。

五、GPIO库函数配置

STM32的HAL库或标准外设库提供了丰富的GPIO库函数,方便用户进行GPIO口的配置和控制。以下是一些常用的GPIO库函数:

  1. 初始化函数(GPIO_Init):用于初始化一个或多个GPIO口的工作模式和速度。
  2. 设置输出电平函数(GPIO_WriteBit/GPIO_Write):用于设置GPIO引脚的输出电平。
  3. 读取输入电平函数(GPIO_ReadInputDataBit/GPIO_ReadInputData):用于读取GPIO引脚的输入电平状态。
  4. 翻转引脚电平函数(GPIO_ToggleBits):用于翻转指定GPIO引脚的电平状态。

六、GPIO应用实例

GPIO口在STM32的应用中非常广泛,以下是一些常见的应用实例:

  1. 控制LED灯的亮灭:将GPIO口配置为推挽输出模式,通过控制GPIO引脚的电平状态来控制LED灯的亮灭。
  2. 读取按键输入:将GPIO口配置为输入模式(如上拉输入或下拉输入),通过读取GPIO引脚的电平状态来检测按键是否被按下。
  3. I2C通信:将GPIO口配置为开漏输出模式,并复用为I2C总线的SCL和SDA引脚,实现与其他I2C设备的通信。
  4. ADC采集电压:将GPIO口配置为模拟输入模式,连接外部模拟信号源,通过ADC模块采集电压值。

七、开漏输出细说

什么是开漏输出?
  1. 只能输出低电平
    • 这意味着,当这个输出想要表示"0"或者低电平时,它可以直接做到,没有问题。
  2. 高电平时引脚为高阻态
    • 但是,当它想要表示"1"或者高电平时,它并不会像普通的输出那样直接输出高电平。相反,它会进入一个叫做"高阻态"的状态。
    • "高阻态"可以想象成这个输出"断开"了,既不输出高电平,也不输出低电平,而是像一个"悬浮"的状态。
  3. 需要外部上拉电阻才能输出高电平
    • 由于开漏输出在高电平时不能自己输出高电平,所以我们需要一个外部的上拉电阻来帮忙。
    • 上拉电阻会连接到电源(通常是Vcc或VDD),这样当输出进入高阻态时,通过上拉电阻,这个引脚就会被"拉"到高电平。
为什么需要开漏输出?
  • 线与功能
    • 开漏输出的一个主要优点是它允许多个设备共享同一根线(也就是"线与"功能)。
    • 在I2C等总线电路中,可能会有多个设备需要同时控制同一根数据线。如果每个设备都直接输出高电平或低电平,那么它们之间可能会产生冲突。
    • 但是,由于开漏输出在高电平时是"悬浮"的,所以只有当所有设备都想要输出低电平时,这根线才会真正变成低电平。如果有一个设备想要输出高电平,而其他设备都保持高阻态,那么通过上拉电阻,这根线就会被拉到高电平,而不会产生冲突。
总结

所以,开漏输出就是一种特殊的输出方式,它只能直接输出低电平,而在需要输出高电平时则进入高阻态,并依赖外部的上拉电阻来"拉"到高电平。这种方式特别适用于需要多个设备共享同一根线(即"线与"功能)的场合,比如I2C总线电路。

八、好奇问题解决

对于开漏输出(Open-drain output)来说,其特性是只能主动地将输出引脚拉低(即输出低电平),而不能直接将其拉高至电源电压(即不能直接输出高电平)。当开漏输出端口被编程为置1(高电平)时,输出引脚实际上会进入高阻态,也就是说,它不会主动地向外部电路提供电流或电压,而是相当于一个断开的开关。

现在,我们来看看当你对上拉电阻连接的开漏输出端口进行编程时,会发生什么:

  1. 置0(输出低电平)
    • 当你通过编程将开漏输出端口置0时,内部的晶体管(通常是N型MOSFET或NPN型双极型晶体管)会被导通,从而将输出引脚拉低到地电位(GND)。
    • 在这种情况下,无论外部上拉电阻的阻值是多少,输出引脚都会被可靠地拉低,因为内部的晶体管提供了一个低阻抗的通路到地。
  2. 置1(输出高电平,但实际上是高阻态)
    • 当你通过编程将开漏输出端口置1时,内部的晶体管会被关断,输出引脚进入高阻态。
    • 此时,输出引脚上的电平将由外部电路决定。如果外部电路中有上拉电阻连接到电源电压(VCC),那么输出引脚会被上拉电阻拉到高电平(接近VCC)。
    • 如果没有外部上拉电阻或者上拉电阻的阻值非常大,那么输出引脚可能会漂浮在一个不确定的电平上,容易受到外部噪声或干扰的影响。

在开漏输出的应用中,特别是像I2C这样的总线电路中,上拉电阻是必需的。因为I2C总线允许多个设备共享同一对数据线(SDA和SCL),而这些设备可能需要同时向总线发送信号。由于开漏输出只能拉低电平而不能拉高电平,所以使用上拉电阻可以确保当没有设备拉低总线时,总线能够保持在高电平状态。这样,即使多个设备同时尝试发送信号,也不会导致总线上的电平冲突或不确定状态。

相关推荐
XH华21 分钟前
初识C语言之二维数组(下)
c语言·算法
南宫生42 分钟前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
sanguine__1 小时前
Web APIs学习 (操作DOM BOM)
学习
析木不会编程1 小时前
【小白51单片机专用教程】protues仿真独立按键控制LED
单片机·嵌入式硬件·51单片机
数据的世界013 小时前
.NET开发人员学习书籍推荐
学习·.net
四口鲸鱼爱吃盐3 小时前
CVPR2024 | 通过集成渐近正态分布学习实现强可迁移对抗攻击
学习
Uu_05kkq4 小时前
【C语言1】C语言常见概念(总结复习篇)——库函数、ASCII码、转义字符
c语言·数据结构·算法
枯无穷肉5 小时前
stm32制作CAN适配器4--WinUsb的使用
stm32·单片机·嵌入式硬件
OopspoO6 小时前
qcow2镜像大小压缩
学习·性能优化
不过四级不改名6776 小时前
基于HAL库的stm32的can收发实验
stm32·单片机·嵌入式硬件