从单片机基础到程序框架(全集 2019pdf版) - 第744页

{ Hand_DAT A=0; //0 代表“握紧 ” } else { Hand_DAT A=1; //1 代表“松开 ” } Foot_CLK =1; Delay(); / /为产生均匀 的脉冲节拍, 时钟线的高电 平先延时一会 Foot_CLK =0; //从高电平跳 变到低电平, 产生瞬间 的“下降 沿” ,代 表“踢 一脚” Delay(); / /为产生均匀 的脉冲节拍, 时钟线的低电 平先延时一会 u8Data=u 8Da…

100%1 / 836
第一百二十五节: “双线”的肢体接触通信。
【125.1 “双线”的肢体接触通信。
芯片之间通信,都离不开“数据信号”和“时钟信号”,缺一不可。“数据信号”和“时钟信号”是什么
关系,它们是怎样相互配合来实现通信的功能?其实原理也很简单。打个比喻,甲乙两个人,规定只能靠
手”和一只“脚”进行肢体接触的通信,们之间如何传输数据“手”可以产生“两种”状态握紧
和“松开”“脚”可以产生“一种”状态“踢一脚”。他们之间约定,甲发送数据给乙,乙每被甲“踢一脚”
就去记录一次手的状态是“握紧”还是“松开”“握紧”代表二进制的 0,“松开”代表二进制 1,这样,
如果他们之间想传输一个字节的十六进制数据 0x59,只需把十六进制的数据 0x59 展开成二进 01011001,
从右到左(从低位到高位)以“位”为单位挨个发送,过程如下:
第一次“踢一脚”:手的状态是“松开”,记录 1。
第二次“踢一脚”:手的状态是“握紧”,记录 0。
第三次“踢一脚”:手的状态是“握紧”,记录 0。
第四次“踢一脚”:手的状态是“松开”,记录 1。
第五次“踢一脚”:手的状态是“松开”,记录 1。
第六次“踢一脚”:手的状态是“握紧”,记录 0。
第七次“踢一脚”:手的状态是“松开”,记录 1。
第八次“踢一脚”:手的状态是“握紧”,记录 0。
上述肢体接触的通信过程其实一只手”就代表了一“数据线”以产生高电平“1”和低电平“0”
这两种状态,而一“脚”代表了一“时钟线”但是“踢一脚”代表了“时钟线”的一种什么状态呢
注意,“踢一脚”既不是高电平“1”也不是低电平“0”,而是瞬间只产生一次的“上升沿”或者“下降沿”
何谓“上升沿”何谓“下降沿”?“上升沿”是代表“时钟线从低电平跳变到高电平的瞬间“下升沿”是
代表“时钟线从高电平跳变到低电平的瞬间”“踢一脚”“上升沿”“下降沿”此三者都可以统一理解成“节
拍”
芯片之间通信,“时钟信号”只需 1 个足矣,“数据信号”却可以不止 1 个。1 “数据信号”往往叫
“串行”通信,一个节拍只能传输 1 位数据。8 个以上并列的“数据信号”往往叫“并行”通信,一个节拍
能传输 8 位以上的数据。可见,并行的“数据信号”越多,传输的速率越快。
IICSPI USBCAN 32
nandflash,norflash,sdram,sram 这些信往“并信,号多 8 16
32 个。
本节标题之所以强调“双线”是因为“手”代表数据线,“脚”代表时钟线,一共两条线因此为“双线”
现在把上述的肢体通信过程翻译成 C 语言代码,甲发送数据的代码如下:
sbit Hand_DATA=P2^6; //手的数据线
sbit Foot_CLK=P2^7; //脚的时钟线
void SendByte(unsiged char u8Data) //甲发送数据的发送函数
{
static unsigned char i;
for(i=0;i<8;i++) //一个字节包 8 个位数据,需要循环 8
{
if(0==(u8Data&0x01)) //根据数据的每一位状态,发送对应的位数据。
{
Hand_DATA=0; //0 代表“握紧
}
else
{
Hand_DATA=1; //1 代表“松开
}
Foot_CLK=1;
Delay(); //为产生均匀的脉冲节拍,时钟线的高电平先延时一会
Foot_CLK=0; //从高电平跳变到低电平,产生瞬间的“下降沿”,代表“踢一脚”
Delay(); //为产生均匀的脉冲节拍,时钟线的低电平先延时一会
u8Data=u8Data>>1; //右移一位,为即将发送下一位做准备
}
}
第一百二十六节: “单线”的肢体接触通信。
【126.1 同步通信与异步通信。
既然芯片之间通信离不开“数据”“时钟”这两种信号,那么是不是说,通信必须至少两根线(双线)
以上?不是。单线也可以通信,继续拿甲乙两人的肢体通信做比喻,这一次只允许用一“手”不许“脚”
“手”继续做数据信号,那么时钟信号在哪?时钟信号在甲乙两人各自的“心跳用两个人的“心跳”作
为时钟信号就有两个时钟节拍,初学者可能在这里会有疑惑,这两人的“心跳频率可能不一致,时钟节拍
可能不同步,怎么能进行通信呢?说到这里恰好通讯界有两个专业的概念,一个是“同步通信”另一个是
“异步通信”。像上一节讲那种用脚的动作“踢一脚”为时钟信号,这个时钟信号只有一个,对于通讯的
甲乙双方是实时“同步的”时钟信号,因此这种通信叫做“同步通信而本节提到的用两个人各自的“心
跳”做时钟信号,有两个时钟源,时钟信号是“不同步的”,这种通信叫做“异步通信
【126.2 异步通信的原理。
既然两人各自的“心跳”不同步(异步而且“心跳”是从甲乙两人出生开始就一直持续存在不停跳
动的,那么发送一个字节的数据是从什么时候开始到什么时候结束就必须事先有一个约定。他们是这样约定
的:
(一)平时的待命状态甲是发送方,乙是接收方平时待命没有发送数据的时候甲手的状态一直是
“松开”的(电平 1)
(二)1 个开始位与 8 个数据位。当甲要发送数据给乙的时候 1 个心跳甲先“握紧(电平 0代表
“开始位”“开始位”用来通知乙方请做好接收数据的准备然后第 2 个到 9 个心跳甲依次靠手的状态发
8 个位的字节数据(数据位),乙方因为“甲的开始位”的存在已经做好了接收 2 心跳数据的准备
因此乙方能完全接收第 2 个心跳至第 9 个心跳的数据位的数据。
(三)1 停止位。甲发送了第 9 个心跳的数据后,必须马上恢复到待命的状态“松开电平 1,以
便为下一次发送数据时能正确发送“开始位”但是这个待命的状态“松开”至少应该持续多长的时间呢
至少持续 1 个“心跳”的时间以上。这样虽然两个人的“心跳”不同步并且频率也不一样,但是只要 8
“心跳”的累加误差不超过 1 个“心跳”的停止位时间,数据就肯定不会错位。这个至少持续 1 个“心跳”
的待命状态就起到消除累加误差的作用
【126.3 异步的肢体通信的例子。
“手”可以产生“两种”状态“握紧”和“松开,甲发送数据给乙,乙每“心跳”一次就去判断一
手的状态,“握紧”代表二进制 0“松开”代表二进制的 1,这样,如果他们之间想传输一个字节的十六
进制数据 0x59,只需把十六进制的数据 0x59 展开成二进 01011001,从右到左(从低位到高位)以“位”
为单位挨个发送,过程如下:
平时手的状态一直处于“松开”的待命状态,直到手第一次出现“握紧”的状态......
第一次“心跳”:手的状态是“握紧,开始位,通知乙作好接收即将过来的 8 个“心跳”数据位。
第二次“心跳”:手的状态是“松开,数据位 bit0,记录 1。
第三次“心跳”:手的状态是“握紧,数据位 bit1,记录 0。
第四次“心跳”:手的状态是“握紧,数据位 bit2,记录 0。
第五次“心跳”:手的状态是“松开,数据位 bit3,记录 1。
第六次“心跳”:手的状态是“松开,数据位 bit4,记录 1。
第七次“心跳”:手的状态是“握紧,数据位 bit5,记录 0。