关于GPIO(一):开漏、推挽、浮空等模式详解
开漏、推挽、浮空等IO模式详解
作为单片机中最基础的部分,一开始学习和使用时并没有深层次的去了解过,导致后面做项目的时候走过不少坑。下面以STM32单片机为例对这部分做一个比较详细的总结。
下面为STM32F1系列单片机的IO基本结构图,本文参考此结构进行解析。
整体介绍
- 此部分为单片机IO引脚,其中VDD为单片机电源,VSS为单片机地。图中的二极管为保护作用,当IO引脚的电平大于VDD并且压差大于此二极管的导通电压时,电流会经过此二极管直接到VDD,保证单片机不被损坏。下面的二极管作用相同。此外部分IO引脚会有VDD_FT标识,此标志代表当前IO兼容5V。
- 此部分为单片机的上下拉电阻,当单片机作为输入模式时,如果没有上下拉电阻会让单片机IO处于浮空状态,此时IO的电平极易受到外部干扰,所以在使用单片机的输入模式时一般会配置为输入上拉(默认高电平)和输入下拉(默认低电平)。注意通常情况下上下拉电阻的阻值都是比较大的。
- 此部分为单片机的输出端,由两个MOS管构成,其MOS管的G级由输出控制,具有推完输出、开漏输出和当PMOS导通NMOS关闭时,相当于IO口直接接VDD,当NMOS导通PMOS关闭时,相当于IO口直接接GND。一般MOS管导通时会有mΩ级别的导通电阻,其具体值与制造工艺及种类相关。
- TTL肖特基触发器,由肖特基管构成的施密特触发器,用于对输入信号整形,采用TTL电平。
- 输入数据寄存器,存储当前IO口状态。读此寄存器返回值为上次采样的IO状态。
- 输出数据寄存器,用于控制当前IO状态。读此寄存器返回值为上次写入的值。
- 位设置/清除寄存器,改变单个引脚状态不影响其他引脚。
分类介绍
输入模式状态图
─ 输入浮空(GPIO_Mode_AIN)
─ 输入上拉和输入下拉
输入模式下,IO的电平状态完全由外部决定,由于外部电平有极大地不确定性。所以一般情况下设置为输入状态时都会增加上拉或下拉电阻。简单的举一个按键IO的例子(一般使用时会有外部上下拉和消抖,此处仅做演示)。
如上图所示,当按键按下时IO口的电平被拉低。但是当按键没有按下时,此时IO处于悬空状态。会出现电平不稳定,在0-VCC之间来回跳动。为了防止在IO设置为输入状态后外界不能提供一个稳定的电平导致电平不稳定,我们在设置IO模式时可以对其增加内部的上拉电阻。这样在按键没有被按下时IO就是一个高电平,按键按下时出现下降沿变成低电平。不会出现IO电平不稳定的情况。
─ 模拟输入
模拟输入,一般ADC功能使用此模式。设置成模拟输入后肖特基触发器被关闭,输出值被强制置0。直接采样当前IO的实际电平值。
输出模式状态图
─ 开漏输出
开漏输出可理解为漏极开路(OD门,针对MOS管)或集电极开路(OC门,针对三极管)。
开漏输出时,图中P-MOS被关闭。此时IO电平由N-MOS和外界控制。当输出低电平时,N-MOS导通,IO电平被拉低。输出高电平时,N-MOS关闭,此时IO状态由外部决定。所以开漏输出无法真正的输出高电平,想让其输出高电平必须外接上拉电阻。可以通过读输入数据寄存器来确定当前引脚状态。简单介绍一下常用此配置的情况。
- 可以控制其他电平逻辑。例如想要控制一个高电平为12V,低电平为0V的逻辑,可以通过外加一个上拉电阻,接到12V电源上。这时候输出低电平时正常输出0,输入高电平时由外部上拉把电平控制在12V。
- 可以实现线与功能(需要外部上拉)。
- 输出高电平时可当做输入口使用。可以通过读输入数据寄存器来确定当前状态。
─ 推挽式输出
一般推挽输出为IO使用最多的模式,此状态下IO具有真正的输出高低电平能力。由于此模式输出高低电平时等同于VCC和GND,所以使用时需要多加注意。当多个IC的IO连接时,需要看情况增加限流电阻,防止出现推挽模式下高低电平直连的情况。
一般单片机对IO口灌电流和拉电流的大小会有说明,设计电路是应考虑IO的驱动能力,防止灌/拉电流过大损坏IO口。
─ 复用功能
本篇对次不做介绍。
写在最后:
本来打算写的深入一点的,但是好多东西整理起来比较麻烦,感觉没有说的很透彻,以后有时间再更新吧。笔者自身也在学习阶段,对上述内容不敢保证百分百正确,文中若有错误之处欢迎指正。
小一啊 2023.10.31
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?