逻辑测试笔亮蓝灯为什么还不能判高阻
逻辑测试笔亮蓝灯为什么还不能判高阻
一根 IO 线测出 1.2 V,既不像低电平,也不像高电平。测试笔亮起中间状态的灯,于是顺手写下“引脚高阻”。这个判断很省事,也很容易把排错方向带偏。
1.2 V 可以来自悬空引脚被弱电阻拉住,也可以来自一个输出阻抗只有几十欧的稳定电源。颜色描述的是电压落在哪个区域;高阻描述的是节点提供或吸收电流的能力。 这两件事需要不同的证据。
下面从一支带 3.3 V / 5 V 档位的逻辑测试笔入手,把窗口、电阻负载和运放输入限制算清楚,再把诊断流程落实成可直接运行的 Python 程序。图中的板图是实际 EDA 工程,计算图与运行结果均明确标注;本文没有进行焊接、灯色或速度实测。

图1 悬空探针与低源阻的 1.2 V 电源,在理想模型中都会得到 MID,不能据此合并成一种电气状态。
先看窗口到底由谁决定
核心器件是 LM324ADR 运放。其中两路开环使用,比较检测节点与两个参考电压;D3、D4 将比较结果组合,第三路驱动蓝灯。这不是专用比较器,也没有在输入比较环节加入明确的正反馈迟滞。

图2 实际原理图 REV 1.0 的模拟检测部分。第四路运放在此工程中未使用且输入悬空;图中如实保留,不能把它当作已完善的量产接法。
R12、R10、R11 从电源到地依次串联,阻值分别为 27 kΩ、18 kΩ、6.8 kΩ。忽略参考端输入电流,令档位电源为 VCC,则:
低门限 V2 = VCC × 6.8 / 51.8
高门限 V1 = VCC × 24.8 / 51.8
5 V 档约为 0.656 V 和 2.394 V,3.3 V 档约为 0.433 V 和 1.580 V。它们是这组电阻决定的自定义门限。要判断某颗 MCU 的输入是否合法,仍要回到该器件的 VIL、VIH 规格,不能把这两条线当成全部 TTL、CMOS 接口的统一标准。
门限也不是一串不会移动的小数。假设三只参考电阻各为 ±1%,仅枚举阻值角点,5 V 档的低门限就覆盖约 0.645~0.668 V,高门限覆盖约 2.369~2.419 V。这还没有叠加电源、输入偏置和失调误差。这里的 ±1% 是计算条件,不代表工程 BOM 已承诺这个精度。
探针悬空时,测试笔自己就在给它定电压
输入端最值得细看的不是灯,而是 R5、R6、R7。

图3 R5 后面才是内部检测节点。C4 接在探针 LogicIn 一侧,不能误画成 R5 后面的滤波电容。
R5 为 10 kΩ;内部节点经 R6 的 10 MΩ 接 +V,经 R7 的 4.7 MΩ 接地。D1、D2 是上下钳位。探针断开、忽略输入电流和漏电时,内部偏置电压 VB 与等效电阻 RB 为:
VB = VCC × 4.7 / (10 + 4.7)
RB = 10 MΩ ∥ 4.7 MΩ ≈ 3.197 MΩ
所以 5 V 档的悬空基线约为 1.599 V,3.3 V 档约为 1.055 V,并不是电源的一半。
若被测节点可以等效成电压源 Vs 串联源电阻 Rs,R5 又串在它和内部节点之间。定义 Iinj 正方向为向内部节点注入电流,则直流节点电压为:
Vn = [Vs / (Rs + R5) + VB / RB + Iinj] / [1 / (Rs + R5) + 1 / RB]
这条式子马上能解释“同色不同因”。5 V 档中,Vs = 1.2 V、Rs = 100 Ω 时,Vn 约为 1.201 V;把 Rs 改成 1 MΩ,Vn 约为 1.296 V;探针彻底断开则约为 1.599 V。三个数都在中间窗口里,源阻抗却差得很远。
兆欧级输入网络也会放大小电流的影响。 TI 的 LM324A 参数表中,25 ℃输入偏置电流典型值为每输入 −15 nA。按手册符号,它表示从输入端流出;连接同一检测节点的两路输入,典型合计可按约 30 nA 注入作一阶估算。乘以 3.197 MΩ,对空探针就是约 96 mV 的变化。
这只是典型参数下的线性估算,不是实测误差,也不是保证值。钳位二极管漏电、板面污染、湿度、手碰和实际偏置离散都会参与,不能只靠“电阻很大”就认定测量完全不扰动被测对象。

图4 同版 PCB 的实际 EDA 二维预览,包含顶面、底面及探针端放大。高阻节点周围的残留助焊剂和手指接触都值得排查;这些图显示工程布局,不证明已经做过环境试验。
还有一个经常被忽略的边界。TI 对经典 LM324 的输入共模范围说明为最高约 VCC−1.5 V,跨温需留到 VCC−2 V;至少一个输入处于有效范围时才有相位保证。在 3.3 V 档,上门限约 1.580 V,而跨温上限只有约 1.3 V,临界比较附近可能两个输入都超范围。因此这套原电路不能仅靠分压计算,就宣称具备通用的 3.3 V 全温判别能力。
反过来,也不能看到探针电压接近 5 V,就直接断言每一路一定相位错误,还要看另一个参考输入是否在允许范围内。本文的程序只计算电阻网络和区域,不预测 LM324 的输出摆幅、饱和恢复、LED 亮灭或最高检测频率。
真想知道源阻抗,就增加一个受控负载条件
单次电压读数不够,可以在适用的低压直流节点上多做一次受控加载。这里先把测试笔断开,只留下同一只万用表,避免测试笔的偏置网络再混进方程。

图5 示意中的电压源、万用表与负载共地。先测 v0,再并入 Rl 测 v1;实际 Rm 应取当前万用表量程的输入阻抗。
把万用表输入阻抗记作 Rm,外加到地的负载记作 Rl。先只接表读 v0,再并联 Rl 并等待读数稳定,得到 v1。两个读数采用相同量程、同一参考地。由两次分压关系消掉未知 Vs,可得:
Rs = Rm × Rl × (v0 − v1) / [v1 × Rm − Rl × (v0 − v1)]
例如合成一个 Vs = 1.2 V、Rs = 100 kΩ 的源,Rm = 10 MΩ、Rl = 100 kΩ,则 v0 = 1.188118812 V、v1 = 0.597014925 V,回算得到 100 kΩ。如果直接把 v0 当成完全无负载电压,使用简式 Rl × (v0/v1−1),结果会约为 99.01 kΩ。把表的负载写进模型,才知道少掉的误差来自哪里。
这个办法要求节点在两次测量间稳定,且能用该工作点附近的线性直流等效源描述。不要把负载直接接到未知供电、高速总线或可能触发保护的节点。100 kΩ 只是本文的计算例子,选值应先评估电流与扰动。
电压变化小到接近仪表误差、加载后反而上升,或者方程分母不为正时,程序应拒绝给出貌似精确的数。即便估出很大的 Rs,它仍只说明直流工作点附近的驱动能力,不能代替寄存器配置、上下拉和动态行为的核对,也不能单凭它证明软件把引脚设成了三态。
把诊断规则做成一段可复用代码
下面是完整的 probe_dc.py 1.0.0,使用 Python 3.10 及以上版本,仅依赖标准库。保存后执行 python probe_dc.py,会打印两档门限、不同源阻案例以及两次读数的回算结果。本文核验环境为 Python 3.12.14;没有额外库,也不需要烧录。
sense() 的 vs=None 表示探针断开,电阻单位为 Ω,injected 单位为 A,正值表示向节点注入。模型限定源电压在供电范围内,且不包含钳位导通;超出内部电源轨就拒绝计算。输出刻意只使用 LOW、MID、HIGH,避免把算出的中间电压伪装成已经证实的 HIGH_Z。
source_r() 则与测试笔模型分开,接收实际 v0、v1 和仪表/负载阻值。min_drop 默认 5 mV,是示例中的不确定度门槛,需要结合仪表精度与读数抖动调整,不能照抄成所有仪表的通用精度。
"""Logic-probe DC diagnostic, v1.0.0. Python 3.10+, standard library only.
Ideal resistor model, no diode conduction, op-amp dynamics or LED prediction.
All resistances are ohms, voltages volts, injected current amperes.
"""
from math import isfinite, inf
def positive(value):
if not isfinite(value) or value <= 0:
raise ValueError("expected a finite positive value")
return value
def references(vcc, r12=27e3, r10=18e3, r11=6.8e3):
for x in (vcc, r12, r10, r11):
positive(x)
total = r12 + r10 + r11
return vcc * r11 / total, vcc * (r10 + r11) / total
def sense(vcc, vs=None, rs=0.0, injected=0.0):
"""vs=None means open probe. Positive injected flows INTO the sense node."""
positive(vcc)
if not isfinite(injected):
raise ValueError("invalid injected current")
if not (rs == inf or isfinite(rs) and rs >= 0):
raise ValueError("invalid source resistance")
if vs is not None and (not isfinite(vs) or not 0 <= vs <= vcc):
raise ValueError("DC model requires 0 <= source voltage <= supply")
conductance = 0.0 if vs is None else 1.0 / (rs + 10e3)
numerator = vcc / 10e6 + (0.0 if vs is None else vs * conductance)
vn = (numerator + injected) / (1 / 10e6 + 1 / 4.7e6 + conductance)
if not 0 <= vn <= vcc:
raise ValueError("sense node outside rails; clamp model required")
low, high = references(vcc)
# Equality is assigned to MID by software policy, not an analog guarantee.
region = "LOW" if vn < low else "HIGH" if vn > high else "MID"
return vn, region
def source_r(v0, v1, rm=10e6, rl=100e3, min_drop=0.005):
"""Probe disconnected. Same meter, then add rl from node to ground.
Stable linear Thevenin source only; min_drop is chosen for meter accuracy.
"""
for x in (v0, v1, rm, rl, min_drop):
positive(x)
if v1 > v0 or v0 - v1 < min_drop:
raise ValueError("drop reversed or too small for this uncertainty limit")
drop = v0 - v1
denominator = v1 * rm - rl * drop
if denominator <= 0:
raise ValueError("no finite nonnegative source resistance fits readings")
return rm * rl * drop / denominator
def main():
print("MODEL ONLY | probe_dc 1.0.0 | no hardware measurements")
for vcc in (5.0, 3.3):
low, high = references(vcc)
print(f"VCC={vcc:.1f} low={low:.6f} high={high:.6f}")
for label, vs, rs, current in (
("open", None, 0, 0),
("strong 1.2V", 1.2, 100, 0),
("weak 1.2V", 1.2, 1e6, 0),
("open +30nA", None, 0, 30e-9),
):
vn, region = sense(vcc, vs, rs, current)
print(f" {label:14s} {vn:.6f}V {region}")
rm, rl, vs, rs = 10e6, 100e3, 1.2, 100e3
rp = 1 / (1 / rm + 1 / rl)
v0, v1 = vs * rm / (rs + rm), vs * rp / (rs + rp)
print(f"synthetic v0={v0:.9f}V v1={v1:.9f}V")
print(f"estimated Rs={source_r(v0, v1, rm, rl):.3f} ohm")
if __name__ == "__main__":
main()

图6 实际运行日志。open 与 strong 1.2V 都输出 MID;下方 100 kΩ 来自合成读数回算,不能当作仪器测量报告。
核验没有只把同一个式子再抄一遍。针对探针侧和内部节点分别列 KCL,独立解二元方程,扫描 3.3 V / 5 V、五档源电阻、五档源电压比例和三档注入电流,再用不同 Rm、Rl、Rs 生成读数回算,并检查越界和不可解输入,共 184 项通过。参考电阻 ±1% 的八组角点另行枚举。
这次完成的改进是一个可执行的直流诊断工具和计入表负载的排错流程,硬件图保留核验基线。若要继续把测试笔做成可靠仪器,下一步应在独立硬件副本中处理比较器选型、明确迟滞和未用通道,再对阈值、漏电与动态响应做实体测试;本文没有把这些后续工作算作已完成。
下次遇到一根“不高不低”的 IO 线,可以先把记录写成“电压处于中间窗口”,再去查它的来源与驱动能力。这个小小的措辞变化,能让后面的测量围着证据走。
资料与验证范围
工程与 EDA 图取自何电工的“逻辑电平测试笔”,项目许可为 Public Domain;其中充放电电路在项目中注明采用 libc0607 的 Public Domain 方案。实际采用原理图 REV 1.0、页面注明的 2023-01-30 PCB;页面更新时间为 2026-06-08。
项目及公开工程入口 https://oshwhub.com/heyh/luo-ji-dian-ping-ce-shi-bi
同版 EDA 编辑入口 https://lceda.cn/editor#id=f2b89a691b7d426184c16fdd46ba7329|47ce28411c6a453d82b8b57b2a602257
TI LM324 数据手册 SLOS066AE,2025 年 9 月修订;本文使用经典 LM324A 对应参数及共模说明,没有套用 LM324B 的较新指标。https://www.ti.com/lit/ds/symlink/lm324.pdf
电路图和 PCB 图从实际 EDA 编辑器取图,保真栅格化并裁去界面、网格和留白,未修改连线、器件数值或板图。正文代码、推导和诊断示意为本文独立完成;验证限于工程静态核对、直流计算及合成输入运行,未做实板或全温验证。完整诊断源码已内嵌,无代码附件。
技术交流,欢迎关注微信公众号:美男子玩编程。



