嵌入式系统中经常会听到上拉电阻、下拉电阻,强上拉、弱上拉等等,上拉、下拉有什么用?这里的强、弱是什么意思?为什么输出端加上拉电阻后可以增加驱动能力?
1.上拉电阻与下拉电阻
嵌入式系统中经常会使用MCU的IO口来检测外部开关信号,开关信号也就是低电平和高电平信号。
比如我们需要检测1个低电平有效的开关信号,检测电路如下图所示:
无外部上拉电阻的低电平检测电路
当开关S闭合时,信号接地,MCU的 IO口会检测到0V,但是当开关断开时,有的MCU会检测到高电平,有的MCU则既不是高电平,也不是低电平。这是因为部分低端单片机可能没有内置上下拉电阻,所以IO口会处于悬空状态,也就是高阻态,这种状态不是1个稳定状态,容易受到外部的干扰而偶发性的误判断为低电平信号。
这时可以采用的解决方法就是在IO口外部连接一个电阻到电源VDD,这样外部开关断开时,IO口的电平是固定的高电平,这个电阻R就叫做上拉电阻。
有外部上拉电阻的低电平检测电路
如果MCU的IO口检测的外部开关信号是高电平有效,则外部开关断开时,存在同样的悬空问题,端口受到干扰后也会产生误判,此时的解决方法就是在IO口外部连接一个电阻到地GND。
有外部下拉电阻的高电平检测电路
这样外部开关S断开时,IO口的电平是固定的低电平,这个电阻R就叫做下拉电阻。
也就是连接到高电平的电源端的电阻是上拉电阻,连接到低电平的地端的电阻是下拉电阻。
2.强上拉与弱上拉
目前大部分MCU的GPIO口内部都已经集成了上拉和下拉电阻,通常可以通过寄存器设置为上拉、下拉和无上下拉三种模式。其中的无上下拉也就是上面所说的悬空高阻态。
MCU的内部电路
寄存器设置为上拉输入时,上拉开关S1闭合,内部上拉电阻Rup生效,外部无信号输入时为高,比如外部按键为低有效时可以使用这个模式;
设置为下拉输入时,下拉开关S2闭合,内部下拉电阻Rdown生效,外部无信号输入时为高,比如外部按开关为高有效时可以使用这个模式;
设置为无上下拉时,上下拉开关S1和S2都断开,此时外部无信号输入时为悬空,比如外部信号为模拟信号输入时,可以使用这个模式。
此外,其它未使用的引脚通常建议配置为下拉输入,防止悬空。
无论是上拉还是下拉,电阻都需要有一定的阻值,在电压一定的情况下,如果阻值很大,外部开关闭合导通时,导通后的电流I=U/R就会比较小,这就是弱;如果阻值很小,电流I=U/R就会比较大,这就是强,也就是强弱是根据电流大小来定义的。
这些上拉或下拉电阻通常在几k到几十K,强和弱之间没有明确的标准,强上拉或下拉常使用1-5kΩ的小阻值电阻,甚至更低;弱上拉或下拉常使用10kΩ以上的大阻值电阻,典型值为40kΩ。
内部强上拉与弱上拉示例
对于输入检测来说:
强上拉,也就是电流大时稳定性好,检测准精度高,但是功耗大;
弱上拉,也就是电流小时虽然功耗小,但是抗干扰能力弱,这是因为电流小时就表示电阻很大,而当电阻无穷大时就相当于是断路悬空状态,也就是不稳定状态。
对于输出控制来说,效果类似,电流大的信号驱动力强,电流小的驱动力弱。
对于高速电路而言,过大的上拉电阻会延长信号上升/下降时间,使边沿变得平缓,可能引发时序问题或干扰。高速电路建议选用较小阻值(如1kΩ),兼顾驱动能力和信号完整性。
如果MCU的 GPIO内部是弱上拉,而外部需要一个比较大的驱动电流,怎么办呢?
内部弱上拉但外部要求大电流
比如外部要点亮一个LED灯,普通低亮度LED的电流通常在5mA至20mA之间,而内部弱上拉输出的电流最大只有5/40k=0.125mA(不考虑负载电阻),远小于LED所需要的电流,所以LED无法点亮。
这时只要在外部再加1个强上拉就可以了。
外部增加强上拉
因为增加外部上拉后,外部上拉电阻R与内部上拉电阻Rup是并联的关系:
总电阻R总= R*Rup/(R+Rup)=0.5*40/(0.5+40)=0.49K;
总电流I总=U/R总=5/0.49K=10.2mA。
也就是驱动电流由0.125mA变为10.2mA,驱动能力增大了80多倍。
这是因为总的并联电阻会小于任一分支电阻,所以当外部上拉电阻远小于内部上拉电阻时,总的并联电阻会更接近外部上拉,也就是外部上拉对总电阻的影响更大,这时就可以基本忽略内部上拉,按照外部上拉来估算驱动电流了。
3.OC与OD输出
MCU的GPIO还有一种输出没有内部上拉的,也就是三极管的集电极开路OC输出或MOS管的漏极开路OD输出。
OD输出
在OD输出结构中,MOS管的漏极D直接连接到输出端,当栅极G输入信号为高电平(如5V)时,MOS管导通,输出端被拉低至0V;当输入信号为低电平时,MOS管关闭,输出端由于外部上拉为高电平,如果外部没有上拉,则此时输出端会处于高阻态(即开路状态)。
OD输出需要外部上拉
这种开漏输出模式的好处是可以适配不同电压的设备,比如MCU工作电压是3.3V,外部设备为5V或12V等,就可以使用这种开漏输出,VDD的大小由外部设备电压决定。
另外,开路输出还可以允许多个设备共享同一总线,通过外部上拉电阻实现电平切换,比如I2C总线的SCL和SDA端口都采用OD输出结构。
I2C总线电路图
当多个设备同时连接时,只有当某个设备将信号线拉低时,其他设备的输入引脚才能感知到低电平信号。若采用推挽输出模式,多个设备同时驱动总线会导致信号冲突甚至损坏设备。
4.推挽输出
与OC/OD相对的就是既可以输出高,也可以输出低的推挽输出,推挽输出是通过内部两个互补的MOS管实现高低电平切换,其原理也可以参看上一篇《为什么需要推挽电路?》。
推挽输出
如上图所示,MCU内部在栅极G端输入低电平时:上面的PMOS导通,下面的NMOS截止,输出端口为电源VDD;
MCU内部在栅极G端输入高电平时:下面的NMOS导通,上面的PMOS截止,输出端口为地GND。
推挽输出模式是通过内部MOS管直接输出高、低电平,驱动能力由芯片内部电路提供,无需依赖外部电阻辅助,所以也不需要配置上拉或下拉电阻。
5.小结
上下拉电阻可分为强上(下)拉和弱上(下)拉,弱上拉因阻值大,电流小,功耗低,但是弱上拉对大负载电容充电慢,可能导致信号上升沿延迟;
强上拉电阻小,电流大,能加速电平转换,但是功耗高容易发热。
另外,使用外部强上拉可增强输出的驱动能力,对于OC/OD输出,外部上拉不仅可以提供输出通道,还可以匹配不同的电平。