电子产业一站式赋能平台

PCB联盟网

搜索
查看: 39|回复: 0
收起左侧

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

[复制链接]
匿名  发表于 前天 19:50 |阅读模式
在进行嵌入式系统设计时,我们经常需要用单片机(Microcontroller 微控制器或称为MCU)的通用输入/输出(GPIO)引脚来驱动LED、继电器等外围设备。老wu还记得大学时写的第一份代码就是通过51单片机来控制LED灯的闪烁。不知现在的大学课程里还保留有51单片机点灯编程实验否,还是已经不再玩51,入门就是STM32这样更高级些的单片机了?
简单贴一下通过51单片机来控制LED灯的闪烁的C代码(ps: 这不是老wu上学时写的第一份代码哈,存有代码的硬盘已经找不到了,一起消失的还有许多美好的记忆瞬间


  • #include           // 包含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; i10; i++)    {        for(j=0; j10000; j++)        {            // 空循环产生延时        }    }}因为是人生中的第一份单片机代码,程序逻辑怎么简单就怎么来:
    1. 头文件包含: #include 包含了8051系列单片机的寄存器定义
    2. 引脚定义: sbit LED = P2^0; 将P2.0引脚定义为LED控制引脚
    3. 主函数逻辑:
    使用无限循环while(1)
    LED = 0 点亮LED(采用低电平点亮LED)
    LED = 1 熄灭LED
    通过Delay()函数控制闪烁频率
    4. 延时函数: 使用双重for循环产生软件延时,程序在这里空跑,纯粹消耗指令时间,更好的做法是使用定时器产生中断来控制LED的闪烁,期间MCU可以去处理其他的逻辑运算
    这段古老的51单片机代码,其程序逻辑也适用于更现代更高级的STM32单片机,只是STM32在初始化时会更麻烦些,要使能GPIO的时钟,设置GPIO的输出模式等。
    在程序逻辑方面,51单片机与STM32单片机并没有区别,但在硬件电路方面,倒是有些讲究的,特别是你平时用的自己买的STM32开发板做实验,而到了学校实验考核时,切换到学校古董级的51单片机开发板,这两种芯片间硬件层面的差异,往往让只顾着写代码的同学会有些摸不着头脑。
    [img][/img]


    单就用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的具体驱动能力:
    查阅数据手册(Datasheet):数据手册是金标准。你需要关注电气特性中的V_OH(高电平输出电压)和V_OL(低电平输出电压)参数。这些参数通常会在特定的输出电流(I_OH和I_OL)条件下给出。通过这些值,你可以估算出IC在高电平和低电平输出时的等效导通电阻,并了解其最大灌/推电流能力。切记,不要超过“绝对最大额定值”(Absolute Maximum Ratings)中规定的电流限制。
    使用SPICE模型进行仿真:对于更精确的分析,可以寻找芯片制造商提供的SPICE模型。通过在仿真软件中搭建测试电路,可以直观地得到IC的完整I-V特性曲线,从而为设计提供精确的数据支持。
    [/ol]实践中的注意事项基于以上分析,我们在进行微控制器外围电路设计时,应注意以下几点:
    优先使用低电平逻辑驱动:对于需要较大电流或期望获得最佳性能的负载(如高亮度LED、光耦等),应优先设计为低电平有效,即采用“灌电流”的方式。
    驱动大功率负载:MCU的GPIO引脚电流能力有限(通常在几mA到几十mA,STM32 GPIO最大的电流位25mA)。当需要驱动电机、大功率继电器等负载时,绝不能直接连接。必须使用外部驱动电路,如MOSFET或专用的驱动IC,来放大电流。此时,MCU引脚同样可以低电平驱动外部N-MOSFET的栅极,这通常比驱动P-MOSFET更简单高效。
    仔细阅读数据手册:不同型号、不同系列的MCU,其GPIO的驱动能力千差万别。设计前务必仔细阅读目标器件的数据手册,明确其I_OL和I_OH的规格。
    让采购千万别买杂牌IC。
    最后,祝大家好运,设计时能避免踩坑,同时不被采购买到的杂牌IC坑到,以上


    #include           // 包含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#include           // 包含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
  • 本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x
    回复

    使用道具

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条


    联系客服 关注微信 下载APP 返回顶部 返回列表