逻辑电平:多少伏算"高",多少算"低"
写好的代码、烧好的固件,单独跑都没毛病。一接上某个 5V 的传感器模块,要么死活读不到数据,要么板子轻微发烫、再后来 GPIO 口彻底哑火。这类故障九成跟"逻辑电平"对不上有关——芯片之间在用电压说话,但两边对"几伏算 1"的理解不一样。
0 和 1 其实是电压区间
数字电路里没有真正的"0"和"1",只有导线上的电压。约定俗成的做法是:电压高代表 1(逻辑高),电压低代表 0(逻辑低)。
关键在于,它不是某个精确值。芯片不会要求"必须 3.3000V 才算高",而是划了两条线:
- 高于某个阈值(比如 2.0V),就判定为高;
- 低于另一个阈值(比如 0.8V),就判定为低;
- 夹在中间那段(0.8V~2.0V)是模糊地带,结果不确定,可能读成 0 也可能读成 1,要尽量避开。
发送方也一样有规矩:它承诺输出高电平时至少给到多少伏、输出低电平时最多压到多少伏。这套发送侧的承诺和接收侧的门槛对得上,通信才成立。具体到某颗芯片,准确数值永远以它的 datasheet 为准(找 VIH/VIL/VOH/VOL 这四个参数)。
TTL 5V vs CMOS 3.3V 阈值
历史上数字逻辑分两大阵营,供电电压不同,阈值也就不同。
TTL(5V 系),老一代逻辑常见:
- 输入:高于约 2.0V 算高,低于约 0.8V 算低;
- 输出:高电平接近 5V,低电平接近 0V。
CMOS(3.3V 系),ESP32、大多数现代 MCU 属于这一类:
- 输出:高电平约 3.3V,低电平约 0V;
- 输入:以 ESP32 为例,大致 >2V 算高、<0.8V 算低(不同芯片、不同供电下数值会变,务必查 datasheet)。
注意一个微妙之处:ESP32 输出高电平只有 3.3V,但一个 5V 的 TTL 器件可能要求输入 >2.0V 才算高——3.3V 高于 2.0V,这个方向勉强能识别。但反过来就未必,下一节细说。
现在设备里 1.8V、3.3V、5V 三种电平都常见(有些低功耗芯片甚至 1.2V),随手放一张对照表,接线前扫一眼心里有底(都是典型值,精确门槛仍以各芯片 datasheet 为准):
| 逻辑族 | 供电 | 输出高(VOH) | 输出低(VOL) | 输入判高(VIH) | 输入判低(VIL) | 常见于 |
|---|---|---|---|---|---|---|
| TTL | 5V | ~4.4V | ~0.4V | ≥2.0V | ≤0.8V | 老逻辑芯片、部分 5V 传感器 |
| LVCMOS | 3.3V | ~3.2V | ~0.4V | ≥2.0V | ≤0.8V | ESP32/S3、多数现代 MCU |
| LVCMOS | 1.8V | ~1.6V | ~0.4V | ≥1.17V | ≤0.63V | 内存、高速接口、低功耗芯片 |
表里藏着两个坑:3.3V 器件去驱动 1.8V 输入,3.3V 远超 1.8V 的耐压,会顶坏对方;而 1.8V 器件输出高电平才 1.6V,喂给要求 ≥2.0V 的 3.3V/5V 输入又"够不着"。跨族基本都得走 电平转换。
3.3V 和 5V 混接为什么出事
混接翻车主要有两个方向,一个伤板子,一个不通信。
方向一:5V 器件输出 → 灌进 3.3V 的 ESP32 引脚。 这是最危险的。5V 模块输出高电平时是 5V,而 ESP32 的 GPIO 一般只能承受到约 3.6V(极少数引脚标注耐 5V,仍以 datasheet 为准)。5V 直接压在 3.3V 引脚上,相当于超压,轻则引脚漏电发热,重则击穿烧毁。最典型的就是把 HC-SR04 超声波模块的 Echo 脚(输出 5V)直连 ESP32——参见 HC-SR04 的接线说明。
5V 信号直灌 3.3V MCU 引脚,是新手烧板的头号原因。模块单独测试时不接 MCU,看不出问题;一旦 Echo/DOUT 这类输出脚 5V 高电平接到 ESP32,可能瞬间或缓慢损坏 GPIO,表现为该口失灵、芯片局部发烫。接任何标 5V 的输出脚前,先想清楚电平。
方向二:3.3V 器件输出 → 喂给 5V 器件输入。 3.3V 高于很多 5V 器件 2.0V 的门槛,往往能识别;但部分 5V 芯片要求输入高电平 >3.5V 甚至更高,这时 3.3V 不够"高",对方一直把它读成模糊地带或低电平,信号根本传不过去。这种是"不通信"而非"烧板",排查起来更费神。
两个方向的解法都指向同一件事:在中间加一级电平转换,把电压翻译到对方认得的区间——做法见 电平转换原理。
开漏与上拉
还有一类信号,光看引脚根本量不到高电平,那不是坏了,是开漏输出(open-drain)。
普通推挽输出能主动把引脚拉到高、也能拉到低。开漏输出只会"拉低"或"放手",自己不产生高电平。放手的时候引脚处于浮空状态,电压随机飘——这时必须外接一个上拉电阻到电源(比如 3.3V),引脚不被拉低时,上拉电阻就把它顶到 3.3V,于是有了稳定的高电平。
I2C 总线、很多传感器的中断脚、复位脚都用开漏 + 上拉这套机制。它的好处之一是天然适配多电压:开漏引脚不主动输出高电平,上拉到哪个电压、高电平就是哪个电压,这在跨电平场景里很有用。原理细节见 上拉电阻与开漏输出。
悬空输入:读到的 0/1 全是假的
还有个和电平相关、却常被忽略的坑:输入引脚不能悬空。配成输入的 GPIO 内阻极高,如果既没接信号源、又没上拉/下拉,引脚电压就处于前面说的"模糊地带",随环境电场、隔壁走线的耦合来回飘。你去 gpio_get_level() 读它,一会儿 0 一会儿 1,全是噪声,不是真信号。
按键电路最典型:一端接 GPIO、另一端接地,看似"按下=低、松开=高",可松开时那个引脚根本没人拉高,就悬空了。解法是给它配一个内部上拉(IDF 里 gpio_config 设 pull_up_en)或外接上拉电阻,松开时被顶到高电平,读数才稳定。规律是:每个输入脚都得有个确定的默认电平,要么信号驱动,要么上拉/下拉钉住。 GPIO 的输入配置细节见 GPIO 是什么。
门槛附近为什么会"抖"
还有个和门槛有关的细节:如果一个信号变化很慢、在 VIH 和 VIL 那段模糊地带里磨磨蹭蹭地爬,芯片就可能在门槛上反复判高判低,一个边沿被读成好几次跳变——按键的机械抖动、缓慢上升的传感器信号都容易这样。
为此大多数数字输入内部带了一个施密特触发器(Schmitt trigger):它把判高和判低设成两个不同的门槛(判高门槛更高、判低门槛更低),中间留一段迟滞。信号往上爬要超过高门槛才认高,往下掉要低过低门槛才认低,门槛附近的小抖动就被这段迟滞吃掉,不会来回翻。知道有这回事,遇到慢边沿信号触发不干净时,就明白该找带迟滞的输入或加整形电路,而不是怀疑代码。
实战注意
落到动手层面,记住几条:
- 接任何 5V 模块前,先确认它的信号脚是不是 5V 输出。 供电 5V 不代表信号一定 5V,但很多便宜模块确实是 5V 逻辑,比如 HC-SR04。看 HC-SR04 接线就知道 Echo 必须降压。
- 不确定方向时,查 datasheet 的 VIH/VIL/VOH/VOL。 这四个值决定了两颗芯片能不能直连。
- 跨电平就上电平转换。 别赌"3.3V 应该够高",电路里还有噪声容限——高电平和判定阈值之间要留出余量,干扰一来才不会误判,余量太小同样不稳。
逻辑电平是 GPIO 通信的地基。把"几伏算高、几伏算低、两边对不对得上"想清楚,很多莫名其妙的不工作和烧板就能提前避开。延伸阅读:GPIO 是什么、数字信号与模拟信号、电压与电流,或回到 硬件基础原理总览。