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

第一百二十六节: “单线”的肢体接触通信。 【126.1 同步通信与异步通信。 】 既然芯片之 间通信离不开 “数据” 和 “时钟” 这两 种信号, 那么 是不是说, 通信必 须至少两根 线 (双线) 以上?不是。 单线也可以 通信, 继续拿甲乙 两人的 肢体通信做比 喻, 这一次只 允许用一 只 “手” 不许 用 “脚” , “手” 继续 做数据 信号 ,那么 时钟 信号 在哪? 时钟 信号在 甲乙 两人各 自的 “心跳 ” 。 用两…

100%1 / 836
{
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。
第八次“心跳”:手的状态是“松开,数据位 bit6,记录 1。
第九次“心跳”:手的状态是“握紧,数据位 bit7,记录 0。
第十次“心跳”:手的状态是“松开,停止位,至少持 1 个“心跳”的待命状态。
现在把上述的“单线”异步)的肢体通信过程翻译成 C 语言代码,甲发送数据的代码如下:
sbit Hand_DATA=P2^6; //手的数据线
void SendByte(unsiged char u8Data) //甲发送数据的发送函数
{
static unsigned char i;
Hand_DATA=0; //开始位。0 代表“握紧”
Delay(); //甲的心跳间隔时间
for(i=0;i<8;i++) //发送 8 个数据位
{
if(0==(u8Data&0x01)) //根据数据的每一位状态,发送对应的位数据。
{
Hand_DATA=0; //0 代表“握紧
}
else
{
Hand_DATA=1; //1 代表“松开
}
Delay(); //甲的心跳间隔时间
u8Data=u8Data>>1; //右移一位,为即将发送下一位做准备
}
Hand_DATA=1; //停止位。1 代表“松开”
Delay(); //甲的心跳间隔时间
}