2. 单线握手

各位同学,咱们今天聊聊单线握手。这玩意儿,说白了就是两个设备之间,只用一根信号线来协调数据传输。你想想看,一根线,既要当请求,又要当确认,是不是听着就有点「省吃俭用」的味道?

我在做嵌入式系统那会儿,最早接触的就是这种握手方式。那时候资源紧张,引脚比黄金还贵,能省一根是一根。但省下来的代价是什么?咱们慢慢聊。

2.1 单线请求-确认模型

单线握手的基本模型,其实特别简单。发送方和接收方共用一根线。发送方把线拉高,表示「我有数据了,你准备收」。接收方看到线拉高了,就把数据读走,然后把线拉低,表示「我收到了,你可以发下一个了」。

嗯,就这么个来回。一根线,两个方向,分时复用。

核心要点:单线握手本质上是一种「半双工」的通信方式。同一时刻,只能有一方控制这根线。

我给你们画个流程图,一看就明白:

发送方 接收方 单线(请求/确认) ① 发送方拉高信号线 请求发送 ② 接收方读取数据 ③ 接收方拉低信号线 确认收到 ④ 发送方准备下一笔 一次完整的单线握手过程

你看这个流程,是不是有点像两个人打乒乓球?你发一个,我回一个。但问题来了——如果接收方处理得慢,发送方就得一直等着。这就是单线握手的第一个坑。

2.2 电平触发与边沿触发

单线握手怎么判断「对方已经响应了」?这里有两种方式:电平触发和边沿触发。

电平触发,就是看信号线当前是高还是低。比如发送方把线拉高,接收方看到高电平,就知道有请求了。接收方处理完,把线拉低,发送方看到低电平,就知道可以发下一个了。

这种方式简单,但有个毛病——如果信号线卡住了,一直高或者一直低,你根本不知道是对方没处理完,还是线坏了。

我的经验:有一次调试一个传感器模块,数据死活读不出来。查了半天,发现是信号线虚焊,一直浮空。电平触发模式下,浮空引脚的状态是随机的,你根本分不清是「没数据」还是「线断了」。

边沿触发就不一样了。它不看电平高低,而是看电平的跳变。上升沿(从低到高)表示请求,下降沿(从高到低)表示确认。或者反过来也行,只要双方约定好。

边沿触发的好处是抗干扰能力强。你想想看,电平触发时,如果线上有个毛刺,高电平被误判成低电平,那就乱套了。但边沿触发只认跳变,短时间的毛刺一般不会触发两次跳变。

触发方式 判断依据 优点 缺点
电平触发 信号线的当前电平 实现简单,硬件开销小 易受干扰,无法区分状态与故障
边沿触发 信号线的电平跳变 抗干扰强,时序更精确 需要检测跳变,逻辑稍复杂

我个人习惯,在低速场合(比如几KHz的通信)用电平触发就够了。但一旦速度上去,或者环境有干扰,我肯定选边沿触发。

2.3 单线握手的局限性

好了,前面说了这么多,现在该泼泼冷水了。单线握手看着简单,但局限性非常明显。

第一,速度上不去。 一根线,一来一回,每次握手都要等对方响应。你想想看,发送方拉高,等接收方拉低,这一来一回就是两个信号传播延迟。如果距离远,或者接收方处理慢,那效率就惨不忍睹了。

第二,无法并发。 单线握手是严格的「一问一答」。发送方发完一个,必须等确认才能发下一个。这就像你打电话,说一句,等对方回一句,再说下一句。不能连续说三句再等回复。

第三,故障检测能力弱。 我曾经遇到过一个案例:设备在高温环境下,信号线的驱动能力下降,电平拉不到标准值。电平触发模式下,接收方死活不认。边沿触发稍微好点,但如果跳变沿变缓了,也可能漏检。

注意:单线握手没有超时机制。如果接收方挂了,发送方会一直等下去。这就是所谓的「死锁」。我建议你在实际项目中,一定要加一个看门狗定时器,超过一定时间没收到确认,就主动复位或者报错。

第四,数据线就是控制线。 单线握手只有一根线,所以数据和控制信息混在一起。你没法在握手的同时传输数据内容。这就意味着,单线握手只能用于简单的「通知」场景,比如告诉对方「数据准备好了,快来取」。至于数据本身,还得靠另外的数据线来传。

说白了,单线握手就是个「敲门」的动作。你敲了门,对方开门,你才能把东西递进去。你不能一边敲门一边把东西塞进去。

嗯,这里要注意一点:单线握手并不是一无是处。在资源极度受限的场景下(比如只有一根GPIO可用),它确实能解决问题。但如果你有选择,我建议至少用两根线——一根请求,一根确认。这样速度和可靠性都会好很多。