STM32 GPIO开漏输出和上拉电阻

 1、推挽输出和开漏输出

STM32 GPIO的输出模式有四种,推挽输出、开漏输出,以及复用推挽输出和复用开漏输出。暂时不考虑两种复用模式(引脚复用见下一篇帖子),讲一下推挽输出和开漏输出的关系。

根据stm32f10xxx参考手册,stm32的GPIO口的输出模式的硬件结构下图输出驱动器所示。输出驱动器中存在PMOS和NMOS两个MOS管,PMOS连接至高电平VDD,NMOS连接至低电平VSS。对应于两个MOS管的导通和关断,GPIO口存在以下四种可能状态:

(1)PMOS导通,NMOS关断:引脚输出高电平;

(2)PMOS关断,NMOS导通:引脚输出低电平;

(3)PMOS和NMOS全部关断:引脚处于高阻态;

(4)PMOS和NMOS全部导通:两个管子会形成通路,造成两个管子短路烧毁,因此这种状态是被禁止的。

对于推挽输出,同时具备高电平、低电平和高阻态三种工作状态。推挽输出同时具有较强的高电平和低电平驱动能力。

对于开漏输出,PMOS管常闭,只有低电平和高阻态两种工作状态。这时为了输出高电平,需要再外接一个上拉电阻。开漏输出只具有较强的低电平驱动能力,高电平驱动能力较弱,这一点后文再解释。

2、开漏输出+上拉电阻输出模式的线与特性

前边讲到,开漏输出需要外接上拉电阻以输出高电平。这种做法使得开漏输出具有线与特性,正是这个特性,使得开漏输出具有特殊的应用价值。

线与特性在通信协议中有十分重要的应用,比如用于I2C总线多主机模式下的总线仲裁。所谓线与特性,是指总线中只要有一个设备输出低电平(逻辑0),总线就呈现低电平状态(逻辑1)。在空闲状态时,总线由上拉电阻上拉至高电平。

3、开漏输出+上拉电阻输出模式的工作原理

首先明确,实际的元件和线路都会有寄生电容。因为电容模型可以简单地理解为两个相互靠近的导体,中间有介质填充,就能形成一个电容。

GPIO的输出电平正是由这个寄生电容充放电决定的,GPIO高低电平的交替过程就是由这个寄生电容反复充放电的交替过程。GPIO口由低电平跳变至高电平时(上升沿),VCC通过上拉电阻给电容充电,GPIO口电压逐渐上升至高电平,电容充电的速度决定了上升沿跳变的速度;GPIO口由高电平跳变至低电平时(下降沿),电容迅速放电,GPIO口迅速跳变为低电平。因此,电容充放电的速度会影响高低电平的转换速度,也就是上升沿和下降的跳变速度。

寄生电容和上拉电阻形成RC并联电路,时间常数为τ=RC。因此,上拉电阻越大,时间常数τ越大,电容充电的时间就越长,于是上升沿跳变的时间就越长。而对于下降沿,由于不存在上拉电阻,所以电阻很小,时间常数很小,电平迅速跳变。这也就是为什么开漏输出的低电平驱动能力较强,而高电平驱动能力较弱。

注:此图来自文末链接,并非原创。

4、上拉电阻的大小选择

由上文分析可知,上拉电阻影响GPIO口上升沿的跳变速度和高电平驱动能力,上拉电阻越大,GPIO的跳变速度和高电平驱动能力越差。因此,上拉电阻应该尽可能选择小一点。

但是上拉电阻也不能太小,上拉电阻如果太小,存在导致NMOS管被烧毁的风险。因为上拉电阻太小的话,VCC和NMOS(NMOS是接地的)会形成通路,产生大电流有可能会烧毁NMOS。也就是说,上拉电阻在这里有作为限流电阻的作用。

综合两方面分析,一般上拉电阻的取值这样考虑即可:

(1)对于GPIO口驱动能力有要求的负载,比如用于I2C通信等,一般选择小一点的电阻,1kΩ~10kΩ;

(2)对于对驱动能力要求不高的负载,电阻可以选择稍微大一点,10kΩ~100kΩ。

5、思考延伸:stm32的复位电路

smt32的复位电路结构其实和开漏输出和上拉电阻的工作模式很像。stm32的复位引脚也是低电平复位,也存在上拉电阻和电容之间的充放电过程:按下复位按键,引脚接地,电容放电至低电平;松开按键,电容通过上拉电阻接至VCC,电容充电,引脚变为高电平。

6、附录

本文部分内容参考自以下链接

推挽 开漏 高阻 这都是谁想出来的词??_哔哩哔哩_bilibili
单片机的上拉电阻 到底在拉什么?_哔哩哔哩_bilibili

STM32GPIO 引脚可以非常灵活地配置成多种模式,包括输入、输出以及一些特定功能。针对您提到的情况——将 PB10 配置为带外部上拉电阻输出模式: 首先需要澄清的是,在设置GPIO作为输出时通常不需要额外连接物理意义上的“上拉”电阻;而是更多见于输入模式下保证信号电平稳定。不过这里假设你是想让该引脚处于高阻态(如三态),并依靠外接硬件电路里的上拉来确定其默认逻辑状态。 但如果你确实是要将其设为推挽输出模式,并希望它能在未激活状态下保持高位,则可以在初始化过程中指定正确的寄存器值使得 IO 口能够达到预期的功能。 下面是一个简单的步骤指南用于通过 HAL 库(假设基于CubeMX生成的基础工程框架)来进行这样的设定: ```c // 假定已经在CubeMX中完成了初步配置 /** * @brief 初始化PB10为推挽输出模式. */ void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; // 启用端口B的时钟 (如果尚未启用的话) __HAL_RCC_GPIOB_CLK_ENABLE(); // 设置引脚为复用推挽输出模式, 上升沿/下降沿中断触发等属性根据需求调整 GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */ GPIO_InitStruct.Pull = GPIO_NOPULL; /* 不内置上下拉 */ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; /* 输出速度低即可 */ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); // 如果期望初始状态就为 HIGH ,则直接在这里控制一下: HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); } ``` 这段代码会把 `PB10` 设定为普通的推挽式输出,默认输出高电平。请注意这里的 "上拉" 主要是靠内部实现而非依赖外部元件。若真的有特殊原因需要用到外部上拉电阻配合某些特定场合下的IO行为模拟,请先确认是否有更合适的方案可用! --
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值