为什么要在推挽模式下为 GPIO 引脚启用上拉?

电器工程 GPIO 拉起 推拉
2022-01-14 10:40:14

在本STM32L486xx HAL 用户手册 (注:36 MB!)中,第 53 页上的 GPIO 配置为外部 LED 供电的示例。让我感到困惑的代码行是以下两行:

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 
GPIO_InitStruct.Pull = GPIO_PULLUP; 

所以他们将推挽模式与上拉结合使用。为什么要这么做?我想不出一个用例。无论如何输出都很高,那么就不需要上拉。或者输出低,上拉将没有机会,输出信号仍然是低,有或没有上拉。那么这个配置有合理的用途吗?

4个回答

就像引体向上一样,这样做的理由有点弱。这样做有错吗?当然不是。你应该这样做吗?可能。对于除了闪烁 LED 什么都不做的代码示例是否有意义?并不真地。

这一系列 ST 微控制器的上拉和下拉电阻完全独立于其他任何东西进行控制,让您确实可以进行像这样的浪费电流的配置,当引脚为高电平时,上拉将不起作用,并且低电平时可能会浪费 100 微安或 2 微安电流(仍然不做任何事情)。

人们可能希望这样做有原因的,它只是为了确保在稍后将模式从推挽模式更改为默认状态时将引脚拉到默认状态. 虽然在推挽模式下上拉或下拉电阻确实没有任何用途,但上拉电阻至少在所有其他模式中可能是可取的:开漏和输入。因此,如果您没有计算每个 µA,并且可能正在改变某些引脚的角色,那么让上拉电阻一直打开是有意义的,以确保引脚不会因意外或其他原因浮空当 GPIO 引脚的引脚模式切换到推挽以外的方式时出现故障。事实上,任何时候你有一个引脚处于推挽模式并需要将其切换到开漏或输入模式时,你可能会在实际切换到该模式之前激活上拉电阻,所以能力即使在推挽模式下也打开上拉电阻当然是有用且重要的。在将引脚更改为输入或开漏时需要防止毛刺,这当然取决于连接到它的内容。

现在,在像他们这样的例子中使用它绝对是一个奇怪的选择。为了绝对清楚,在推挽模式下使用引脚时 可以(并且可以说在大多数情况下应该)设置GPIO_InitStruct.Pull为。GPIO_NOPULL

当然,如果你这样做,你必须记住打开一个上拉或下拉电阻(如果没有外部电阻),如果你将引脚模式更改为推挽以外的其他方式。也许 ST 只是在谨慎行事,并假设有人闪烁 LED 将很有可能忽略这一点,至少在最初是这样。或许这只是一个小小的疏忽。无论如何,它在显示的示例中肯定没有真正的用途,因此,我觉得它主要只是混淆了此处文档的要点。

这就是为什么你来堆栈交换甚至问这个问题的原因。也许 ST 的某个人会在阅读此内容后更新 PDF。在我看来,他们应该这样做,因为这显然会让人们感到困惑,这是人们最不想做的事情。

除此之外,不要过多地阅读它。你会经常遇到这样的小怪事,但不要在每次发生时都开始怀疑自己。我想我们大多数人可能喜欢假装我们所有的数据表、文档和应用笔记都没有错误,每一行示例代码和每一句话都是有目的的和经过深思熟虑的。但我们都是人类,只要人类还在编写数据表和文档,有时你就会发现错误。你会遇到的许多错误都是相对良性的,并且会导致一些像这个例子一样有点奇怪或不必要的东西。这些也是那些通常永远不会被纠正的问题,仅仅是因为它并不那么重要,而且没有人会被打扰。

我如何处理特定的代码异常,以及将来处理此类问题的一个好方法是查阅相关芯片的实际数据表。了解端口在物理上是如何工作的,然后你就会有足够的信心在那种情况下打开引体向上而不担心它。如果您了解芯片的功能,这就是您所需要的。无论是谁编写的,您都可以发现芯片的任何示例代码中包含的任何怪异之处,而不是任其摆布。

来自 STM32L4x5 和 STM32L4x6 RM0351 - 参考手册

一个 GPIO 可以有以下模式:

  • 输入浮动
  • 输入上拉
  • 输入下拉
  • 模拟
  • 具有上拉或下拉能力的输出开漏
  • 具有上拉或下拉能力的输出推挽
  • 具有上拉或下拉功能的交替功能推挽
  • 具有上拉或下拉功能的备用功能开漏

弱 40kΩ 上拉和下拉对于能够吸收/提供 25mA 电流的推/拉输出没有意义(在 5V 时影响仅为 0.125mA)。但这假设 GPIO 引脚不会改变它的模式。

任何 GPIO 引脚都可以从一种模式转换到另一种模式。输入可以变成输出,反之亦然。双向和多用途引脚。

请注意,所有输出和交替模式都具有上拉和下拉功能,而输入分为三类(浮动、上拉和下拉)。为什么需要具有下拉功能的开漏输出?

为避免 GPIO 在引脚从输出转换到输入时浮动,所有输出都提供上拉和下拉以将输入设置为默认或关闭状态。

如果 GPIO 引脚永远不会改变其模式,请使用 NOPULL 进行配置。

在正常使用期间您不会这样做。但是如果你想使用最深的睡眠模式,可以禁用 IO 引脚,而上拉和下拉保持状态。

或者,如果您只想使用内部上拉的开漏通信。

这与GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;语句有关(就在您引用的代码下方)。

深入研究参考手册(第 296 页):

STM32L486 GPIO 速度字段

GPIO_SPEED_FREQ_MEDIUM 在实际寄存器中的值为01(请参阅参考手册中的第 304 页),这是通过使用上拉加载输出引脚来实现的(其他模式是使用下拉加载或无负载加载)。

只是为什么这不可能是 HAL 的一部分(已知中等速度需要上拉)尚不清楚,因为库应该只知道尽管 HAL 的这部分是通用的,而各种 STM32 系列中的其他部分可能不需要拉销(或不同的方式)以达到此速度,因此必须明确说明。

所以才真正实现中速功能。

我会注意到现代微控制器文档包含如此多的信息,以至于很容易需要数周(或数月)才能完全理解所有内部部件和细微差别。