为什么说结束信号和应答信号都可以不要?如果不加入两者分别会造成什么结果呢
单片机和嵌入式系统中,每个外设在通信时都需要一些固定的信号来进行数据传输和控制。对于某些通信协议中涉及的结束信号和应答信号,其实在某些情况下是可以省略的。这主要取决于具体的通信协议和应用场景。
例如,在I2C协议中,通信双方都需要发送ACK(应答)信号来确认是否接收到数据。在某些应用场景下,为了节省字节和时间,可以省略ACK信号来完成快速传输。但这种情况只适用于少量数据传输,且必须保证数据传输的准确性。如果数据出错或者通信双方意见不同,就可能会引起通信错误。
同理,对于结束信号,例如在USART协议中,可以通过发送固定长度的数据来代替结束信号,避免了单独发送结束信号所带来的开销。但在某些应用场景中,例如传输可变长度的数据时,就很难去除结束信号的作用。
因此,对于通信协议中的结束信号和应答信号,需要综合考虑具体应用场景和实际需要,做出合适的选择,以确保通信的准确性和有效性。
现在,我们已经知道了计算机是怎么一步一步被创造出来的,CPU运行的时候内部实际又在发生着什么。有了一个比较系统的认识以后,现在就可以来回答我们开头提出的那个问题:计算机一定要有时钟吗?时钟是用来干什么的呢?现在我们就把时钟弄明白,它存在的意义是什么,要解决什么问题。通过前面的介绍,你已经知道了CPU是靠电流驱动的,而1代表有电流,0代表没电流,而电流的通断由晶体管来控制着,晶体管就像一个开关一样。如果我们用一个波形图来表示电流的变化情况,它的变化应该是这样的:
在凹下去的地方就是0,凸起来的地方就是1。可以看到,从0变化到1并不是瞬间完成的,而是有一个斜率,这就意味着在从0变化到1是有一段过渡的时间。为什么不是瞬间完成呢?其实你可以回想一下你拧开水龙头的情景,当你拧动水龙头的时候,水流是从小逐渐变大的,而电流的变化也有这种现象。电流本质是沿着一个方向运动的电子,当你开始加一个5V的电压,电压从0到5V也需要过渡的时间,所以刚加电压的时候,只能驱动少量电子向一个方向运动,随着电压逐渐变大,被驱动的电子也越来越多,所以电流是在逐渐变大。我们把从0变化到1(或者从1变化到0)所用的时间称为传播延迟。但是,这个过渡时间(传播时延)其实是极其短暂的,基本是在纳秒(ns)级别,对于我们来说纳秒几乎感觉不到,但是对于电路来说,却不能忽略。为什么不能忽略?如果你想明白了那你就知道时钟存在的意义了,如果没有猜到,没关系,那就先把这个问题跳过去,后面会解释的。因为这个过渡时间是纳秒级别的,所以上面这个图的斜率其实非常陡,就像下面这样:
这种图对于分析问题非常不方便,如果你是研究问题的人,你愿意对着这样的图来研究下去吗?所以,人们为了图看起来更方便,就直接把它画成一条直来直去的竖线,就成了下面这幅图:
把这样的一个方波,就称为一个脉冲。在我们现在讨论的话题里,也就是关于CPU的脉冲的时候,把这种脉冲称为时钟脉冲,它还有另一种常见的叫法,叫时钟信号,都是一回事,简称为时钟。你可能会好奇问为什么叫时钟呢?难道和我们看时间的钟表有什么关系吗?请你回想一下,前面我们说过有一个东西叫振荡器,它可以不停的产生脉冲信号,这种东西被用在安上电池才能走动的钟表中。在这种钟表里面,有一个振荡器,它每隔一秒产生一个脉冲,用来驱动一个小小的电机,促使它每次转动一个角度,并通过齿轮传动机构带动秒针跟着向前移动一步,还“嗒”地响一下。由于这个原因,这种振荡脉冲经常被称为时钟脉冲,或者时钟信号,以表彰它至今仍在某些钟表里面努力工作的精神。现在知道为什么叫时钟脉冲了吧,原来和钟表中的振荡器有关。前面我们讲的振荡器是为了给电路的一个脉冲,让整个电路在脉冲的驱动下工作。你可能会马上想到,晶振就是产生时钟的,那主板上的晶振也是为了产生时钟脉冲然后驱动CPU工作吧?如果你这么想,显然你认为CPU依靠时钟脉冲才能工作。其实,CPU没有时钟照样可以工作,这种CPU叫做异步CPU(asynchronous CPU),而我们平常所说的需要时钟的CPU属于同步CPU(synchronous CPU),目前市面上在销售的CPU差不多都是同步CPU。而且,可以告诉你的是,异步CPU还比同步CPU更快,那为什么不用异步CPU呢?因为异步CPU的设计更加复杂,在最开始的门电路设计上就已经与同步CPU不一样了。还有一点,我认为是代价的衡量,因为即使异步CPU更快,这个时间在每一次改变晶体管状态的时候属于纳秒(ns)级别的,即使快1000ns,对于人来说几乎感觉不到,但是异步的设计无疑增加时间和人力的成本,究竟要不要为了纳秒级别的提升而设计比同步CPU更加复杂的电路,相信设计CPU的工程师们一定比我们更清楚。所以,现在你应该知道了,时钟不是为了驱动CPU工作的,那时钟究竟是干什么的呢?刚才说只有同步CPU才会需要时钟,那就来理解一下同步这个词,理解了“同步”,就知道时钟的作用了。理解同步,需要举一个生动的例子,运动会的100米比赛再好不过了。现在有5个人要参加比赛,有一根起跑线。当比赛即将开始,5个人陆续向起跑线走来。第一个人先到了,但是他还不能起跑,因为这个比赛有五个人,他还要再等等其他四个人都站到起跑线上才能开始。如果不需要等待,假设他们的速度都是一样快,那离起跑线最近的那个人势必先到达终点,那这场比赛就乱套了。所以,只有等五个人全部站在了起跑线上,也就是说这5个人同步了,然后就可以跑了。
同步理解了,那时钟呢?现在,我们要记录一个时间,就是刚才的5个人中,走到起跑线时间最多的那个人的时间作为他们这组的同步时间,就是最多用多长时间你们这5个人就能在起跑线上都站好了,假设这个时间是20秒,我们就把这个时间叫做一个时钟周期。也就是在这个时钟周期内,保证5个人已经全部站在起跑线上了,这个时候裁判一打抢,他们就可以跑出去。我们假设这个比赛不止一组,刚才那5个人是第一组。裁判是个机器人,他每隔20秒就打一次枪,也就是一个时钟周期就打一次枪。现在轮到第2组,经过一个20秒的时钟周期,5个保证全部到了起跑线,然后裁判机器人打枪,第二组起跑。接下来的每一组都是如此,5人站到起跑线,起跑,5人站到起跑线,起跑。所以,时钟周期的意义就是能保证5个人能全部出现在起跑线上,也就是可以确保这5个人同步了,然后再进行下一步的动作。当然这是一个比较通俗的解释,为了可以对时钟的作用有一个感觉,知道它是为了控制一个时间范围,起到同步的作用。在前面,我们已经知道了CPU是通过很多的逻辑门来工作的,而逻辑门的实现就是依靠晶体管的开关作用。比如现在有两条电流要经过一个非门,第一条电流它过来时候可能是从别的门的输出过来的,第二条电流可能直接过来的,没经过逻辑门。那当这两条电流到达逻辑门的时候,肯定是第二条电流先到达。第一条电流因为要经过一个逻辑门,所以会有传播延迟,等它从那个逻辑门出来的时候,第二条已经先于它到达了非门。由于第二条电流一到达,非门就会发生变化,但是要想非门正确输出,必须等待第一条电流也到达后, 将两条电流汇合的结果再作为输出。非门不能在第二条电流一到达就产生输出,要给它一个时间限制,假如是20纳秒,经过20纳秒后,非门才能输出。而在20纳秒内,第一条电流一定会到达,因为这个20秒是按第一秒能到达的最长时间算的。通过一个具体的例子更能说明问题,考虑下面一个逻辑电路:
当A=B=1时,Q=0。当输入信号发生变化时,逻辑元件不会立即对输入变化做出反应,会有一个传播时延(propagation delay)。当B变化为0时,由于B也作为XOR的直接输入,所以XOR异或门会立即感知一个输入变为0的状态变化,XOR输出变为了1。但是由于传播时延的作用,AND与门的输出会过一小段时间才变为0,XOR的输出会在变为1后隔一小段时间重现变为0。表现为下图就是这样:
上面这种现象叫作空翻(race condition),即指输出中出现了一个不希望有的脉冲信号。
一个简单的办法就是在输出端放置一个边沿触发器:
边沿触发器的作用就是只有当CLK端输入从0变到1时,数据端D的输入才会影响边沿触发器的输出。这样,所有的传播时延都会被边沿触发器所隐藏掉,这时Q端的输出将变得稳定。比如:
其中灰色的部分代表没有边沿触发器时的Q端输出状态。我们可以看出,当有了边沿触发器后,Q端的输出变得稳定,基本消除了传播时延。
从上面的例子我们可以看出CPU为什么要时钟:目前绝大多数的微处理器都是被同步时序电路所驱动,而时序电路由各种逻辑门组成。正如上面说的那样,逻辑门需要一小段时间对输入的变化做出反应(propagation delay)。所以需要时钟周期来容纳传播时延,并且时钟周期应当大到需要容纳所有逻辑门的传播时延。
前面我们也说了有异步CPU,它采用Asynchronous sequential logic设计,即不需要时钟信号做同步。但是这种异步逻辑电路虽然速度比同步时序电路快,然而设计起来比同步时序电路复杂的多,并且会遇到上面说的空翻现象(race condition),所以,现在绝大多数的CPU还是需要时钟做信号同步的。
现在彻底明白了时钟的作用了吧?由于现在是集成电路,所以产生时钟的元件就由晶振来承担了。最后总结一下,我们的思路是从一个问题开始嵌套的问下去,一直追问到本质,然后又通过分析本质,逐级回溯到最初的问题,看似没有联系的几个方面,实则有着千丝万缕的联系,所以说,计算机是人类智慧的结晶。
结束信号和应答信号在通信中是非常重要的,它们用于保证数据的正确传输和接收。如果不添加这两个信号,程序会产生的影响是数据传输的错误和数据丢失,下面是一些实例说明:
1.在模拟信号通信中,由于信号的波高和频率连续变化,在传输一定距离内,信号衰减较小,信息保留相对完整。但在数字信号通信中,由于信号是离散的,每个信号由多个频率的波形叠加而成,各个波形衰减速度不同,在传输的过程中,信号变形比较严重,信息缺失较多,因此需要在发送数据结束时定义一个结束信号,以保证数据的完整性。
2.在串行通信中,发送端发送完一个数据包后,需要等待接收端的应答信号,以确保数据正确接收。如果接收端没有发送应答信号,那么发送端会重发数据包,防止数据丢失或者错误。
对于结束信号和应答信号如何添加,具体操作如下:
1.在发送数据时,添加一个结束标志,例如在数据包结尾添加一个固定的字符或者字符组合,作为结束标志。
2.在接收数据时,读取数据包,如果发现结束标志,即说明数据包传输完成,如果没有结束标志,则说明数据包传输失败,需要重新发送。
3.发送端发送完数据包后,等待接收端的应答信号,如果接收端正确接收了数据,就发送一个应答信号给发送端,通知发送端可以继续发送下一个数据包,如果没有收到应答信号,则认为数据丢失或错误,需要重发数据包。
4.接收端收到数据包后,读取数据包,如果数据包正确,则发送一个应答信号给发送端,表明数据包接收成功。如果数据包错误,则不发送应答信号,发送端会自动重发数据包。
例如,在使用串口通信时,发送端可以在数据包结尾添加一个回车换行符作为结束标志,接收端接收到数据包后,检查最后两个字符是否为回车换行符,如果是,则说明数据传输结束,如果不是,则说明数据包传输失败。同时,在接收到数据包后,接收端发送一个字符作为应答信号给发送端,如果发送端没有收到应答信号,则认为数据包传输失败。