单片机GPIO驱动能力的秘密:为何“灌”比“推”更给力?

 单片机GPIO驱动能力的秘密:为何“灌”比“推”更给力?

在进行嵌入式系统设计时,我们经常需要用单片机(Microcontroller 微控制器或称为MCU)的通用输入/输出(GPIO)引脚来驱动LED、继电器等外围设备。老wu还记得大学时写的第一份代码就是通过51单片机来控制LED灯的闪烁。不知现在的大学课程里还保留有51单片机点灯编程实验否,还是已经不再玩51,入门就是STM32这样更高级些的单片机了?

简单贴一下通过51单片机来控制LED灯的闪烁的C代码(ps: 这不是老wu上学时写的第一份代码哈,存有代码的硬盘已经找不到了,一起消失的还有许多美好的记忆瞬间 /(ㄒoㄒ)/~~)

#include<reg52.h>           // 包含8051特殊功能寄存器声明头文件

sbit LED = P2^0;            // 定义LED连接到P2.0引脚

void Delay(void);           // 延时函数声明

void main(void)
{
    while(1)                // 无限循环
    {
        LED = 0;            // LED点亮(低电平有效)
        Delay();            // 延时
        LED = 1;            // LED熄灭(高电平)
        Delay();            // 延时
    }
}

// 软件延时函数
void Delay(void)
{
    int j;
    int i;
    for(i=0; i<10; i++)
    {
        for(j=0; j<10000; j++)
        {
            // 空循环产生延时
        }
    }
}

因为是人生中的第一份单片机代码,程序逻辑怎么简单就怎么来:

  1. 头文件包含: #include<reg52.h> 包含了8051系列单片机的寄存器定义

  2. 引脚定义: sbit LED = P2^0; 将P2.0引脚定义为LED控制引脚

  3. 主函数逻辑:

  • 使用无限循环while(1)

  • LED = 0 点亮LED(采用低电平点亮LED)

  • LED = 1 熄灭LED

  • 通过Delay()函数控制闪烁频率

  1. 延时函数: 使用双重for循环产生软件延时,程序在这里空跑,纯粹消耗指令时间,更好的做法是使用定时器产生中断来控制LED的闪烁,期间MCU可以去处理其他的逻辑运算

这段古老的51单片机代码,其程序逻辑也适用于更现代更高级的STM32单片机,只是STM32在初始化时会更麻烦些,要使能GPIO的时钟,设置GPIO的输出模式等。

在程序逻辑方面,51单片机与STM32单片机并没有区别,但在硬件电路方面,倒是有些讲究的,特别是你平时用的自己买的STM32开发板做实验,而到了学校实验考核时,切换到学校古董级的51单片机开发板,这两种芯片间硬件层面的差异,往往让只顾着写代码的同学会有些摸不着头脑。

单就用GPIO来点亮LED的电路来说,一个常见的问题是,驱动电路应该设计成高电平点亮还是低电平点亮?

  • 高电平逻辑驱动:MCU引脚输出高电平(’H’)时,电流从MCU流向LED,点亮LED。

  • 低电平逻辑驱动:MCU引脚输出低电平(’L’)时,电流从电源经LED流向MCU,点亮LED。

直观上看,这两种方式似乎没有区别,至少对于STM32这样的单片机来说是没有区别的,但对于51单片机来说,他们在电流驱动能力上却并不相同。

8051的GPIO是“准双向IO”

经典的8051单片机(特指P1, P2, P3口)并没有真正的推挽结构。它的I/O口被称为准双向口(Quasi-bidirectional Port)。其内部结构是非对称的:

  • 一个弱上拉电阻(Weak Pull-up Resistor)。

  • 一个强下拉N-MOS管(Strong Pull-down N-MOS)。

当向51单片机的GPIO端口对应的引脚写入“1”(高电平)时:下管N-MOS截止,此时仅靠微弱的内部上拉电阻将引脚电平拉高。这个“上拉”的动作非常无力,只能提供很小的电流。最大输出电流通常仅有约 0.1-0.3mA(毫安),这是由于其内部采用弱上拉电阻设计(典型值约 20kΩ-50kΩ)。

计算可得最大输出电流:

实际电流因型号和温度略有浮动,但普遍低于 0.5mA,微弱的内部上拉电阻完全无法提供驱动LED所需的毫安级电流,会导致LED非常暗甚至点不亮。。

当向51单片机GPIO端口的引脚写入“0”(低电平)时:下管N-MOS导通,强力地将引脚电平“拉”向地。这个“拉”的动作非常有力,可以“灌入”较大的电流,毫安级别,点亮LED灯没问题,但也不是非常强悍的水平,STC89C51的5V单片机的P0口的灌电流最大为 12 mA ,其他I/0口的灌电流最大为 6 mA 。 STC89LE51的3V单片机的P0口的灌电流最大为 8 mA ,其他II0口的灌电流最大为 4 mA 。

可见51单片机的灌电流并不是非常强悍,仅能直接驱动小功率负载(如低亮度 LED、小尺寸数码管),如果要驱动继电器、蜂鸣器等需外接三极管或 MOS 管放大电流。

STM32的“推挽”模式具有强劲的驱动电流

STM32 GPIO 推挽模式电流流向图

STM32的GPIO在配置为输出时,最常用的就是“推挽(Push-pull)”模式。其名称生动地描述了它的内部结构:由一个P-MOS管(上管)和N-MOS管(下管)组成。

  • 推(Push):当需要输出高电平时,上管P-MOS导通,下管N-MOS截止。P-MOS管像一只手,主动、强力地将引脚电压“推”向电源(VDD),能够提供(Source)较大的电流。

  • 拉(Pull):当需要输出低电平时,下管N-MOS导通,上管P-MOS截止。N-MOS管像另一只手,主动、强力地将引脚电压“拉”向地(GND),能够吸纳(Sink)较大的电流。

STM32得益于半导体工艺的进步,能够为每个引脚都配备功能更强、更直观的真推挽结构。无论是输出高电平还是低电平,都有一个强大的晶体管在主动工作。能提供和吸纳几乎同等级别的电流,驱动能力强劲且均衡。

如STM32 Datasheet中电流规格表所示,GPIO向外推的电流和向里灌的电流最大都是25mA,都能让LED获得足够的亮度。

为何有时“灌电流”能力更强?

经典8051刚出来时,当时的工艺还不能实现高密度的晶体管集成,或者说在硅片上光刻晶体管会比较贵,所以当时设计经典的8051的智慧在于用更少的晶体管实现了一种巧妙的、能读能写的“准双向”口,这在当年是极具成本效益的创新。而大多数CMOS逻辑IC的输出级都采用“推挽式”(Push-Pull)结构,由一个P沟道MOSFET和一个N沟道MOSFET组成。

  • 当输出高电平时,上方的P-MOS管导通,将引脚“推”向电源电压(Vcc)。

  • 当输出低电平时,下方的N-MOS管导通,将引脚“拉”向地(GND)。

关键在于,由于半导体物理特性的差异,N沟道MOSFET的导通电阻通常比P沟道MOSFET的更小

  • 在由外向里“灌”(Sinking)电流时,内部压降更小,允许通过的电流更大。

  • 在由里向外“推”(Sourcing)电流时,内部压降更大,限制了其输出电流的能力。

简而言之,经典8051单片机为了节约晶体管,采用的“弱上拉电阻”+“强下拉N-MOS管”的方式,造成8051的驱动电流能力不对称,点亮LED需要用“灌电流”的方式。

由于意法半导体自有晶圆厂的优秀工艺,STM32单片机的“灌电流”和“推电流”的能力是一致的,都是最大25mA,而一些CMOS 逻辑IC,比如小厂的74HC04逻辑IC,有可能“灌电流”的方式比“推电流”的方式驱动能力更强。(ps:采购买到杂牌IC的苦大家应该都懂的)

如何确认IC的驱动能力?

作为工程师,我们不能只凭经验。有两种方法可以确定一个IC的具体驱动能力:

  1. 查阅数据手册(Datasheet):数据手册是金标准。你需要关注电气特性中的V_OH(高电平输出电压)和V_OL(低电平输出电压)参数。这些参数通常会在特定的输出电流(I_OHI_OL)条件下给出。通过这些值,你可以估算出IC在高电平和低电平输出时的等效导通电阻,并了解其最大灌/推电流能力。切记,不要超过“绝对最大额定值”(Absolute Maximum Ratings)中规定的电流限制。

  2. 使用SPICE模型进行仿真:对于更精确的分析,可以寻找芯片制造商提供的SPICE模型。通过在仿真软件中搭建测试电路,可以直观地得到IC的完整I-V特性曲线,从而为设计提供精确的数据支持。

实践中的注意事项

基于以上分析,我们在进行微控制器外围电路设计时,应注意以下几点:

  • 优先使用低电平逻辑驱动:对于需要较大电流或期望获得最佳性能的负载(如高亮度LED、光耦等),应优先设计为低电平有效,即采用“灌电流”的方式。

  • 驱动大功率负载:MCU的GPIO引脚电流能力有限(通常在几mA到几十mA,STM32 GPIO最大的电流位25mA)。当需要驱动电机、大功率继电器等负载时,绝不能直接连接。必须使用外部驱动电路,如MOSFET或专用的驱动IC,来放大电流。此时,MCU引脚同样可以低电平驱动外部N-MOSFET的栅极,这通常比驱动P-MOSFET更简单高效。

  • 仔细阅读数据手册:不同型号、不同系列的MCU,其GPIO的驱动能力千差万别。设计前务必仔细阅读目标器件的数据手册,明确其I_OLI_OH的规格。

  • 让采购千万别买杂牌IC。

最后,祝大家好运,设计时能避免踩坑,同时不被采购买到的杂牌IC坑到,以上 🙂

❤️ 如果这篇文章对您有帮助,欢迎打赏支持

微信打赏二维码

扫描上方二维码,用微信打赏

吴川斌

吴川斌

Leave a Reply