找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 11352|回复: 12
收起左侧

原创,使用普通IO口自定义协议实现两个51单片机互相通讯 附源码与资料下载

  [复制链接]
ID:284106 发表于 2018-4-15 16:19 | 显示全部楼层 |阅读模式
因为想使两个51单片机通讯,又不能使用串口,因为STC89C52单片机只有一个串口,己被占用了,没有串口可以用。所以编写了这个程序。

使用仿真软件进行测试,工作正常。
01.gif


在电路上实际测试,运行正常。
对控制线,进行短接干扰,测试,都按照预想的结果运行。

20180415_134318.jpg

测试代码:
发送端不停的发送自定义数据帧,每发送一次,将第数据帧中的2个字节数加 1,再发送。
接收端使用LCD1602 将接收的据据帧中的第2个字节,显示出来。
对两根控制线进行断线,和对地短路干扰测试,也按照预想,干扰消除后,恢复正常工作。

下面是说明文档,附件源代码,和仿真电路图下载。

双单片机通信协议说明文档
一、通信协议的作用
     功能:实现两片51单片机互相通信,4根线单向通信,8根线双向通信。
     工作方式:使用普通IO口,不断轮询方式通讯。 (不使用单片机的中断,不使用串口)
     适用场景:电路上两片51单片机,需要互相通讯。
     传输速度:使用Porfessional和keil联调,在单片机的晶振频率为11.0592MHZ,单片机型号AT89C 51。两片单片机的时间全部用在轮询,测试约27MS接受完成16个字节数据。
     (注:测试时发现的问题,Porfessional和keil联调,调试那个CPU就需要把正在调试的CPU改为U1,不然另一个CPU里面的代码没有运行,没有反应不能调试)。
image001.jpg
image002.jpg




定义数据帧的格式


image004.jpg





传输1个字节的流程




   image005.jpg
image006.jpg
image007.jpg
image008.jpg
image009.jpg
image010.jpg

分析运行时的步骤
协议在运行时,发送端控制C1,D1,D2三根线的电平状态,接收端控制C2一根线的电平状态。发送端不断在轮询C2的状态,接收端也同时在不断轮询C1的状态。这两根线我们把他称为控制线,也称为握手线。D1和D2我们把他称为数据线,两根线的电平可以表示4种状态,状态的表示如下:
  
D1
  
D2
状态
0
0
一个字节传输开始
0
1
0
1
0
1
1
1
一个字节传输结束


为什么需要有(一个字节传输开始和一个字节传输结束)这两种状态,直接传送0和1不就可以了吗?我举一个例子:现在我们要把4个字节的数据发送给对方。如:01100110  01100110  01100110 01100110,按照正常的接收,接收端依次读取8个比特然后存入1字节,依次读完36比特存入4字节。但是通讯协议的设计应该要考虑到异常情况,如果由于某种原因受到干扰,这36比特中间少传或者多传了1比特。接收端接下来再以每8比特为1字节的取,接下来的数据就会全部错位。使用开始位和结束位来标识,就解决了这个问题。
发送和接收1比特数据的步骤如下:
初始状态:四根线的电平都为高电平1, 51单片机的IO口默认也是高电平。接收端在不断轮询C1的状态。
步骤一:发送端,发送1比特数据,在代码里,首先将D1和D2置为需要表达的电平,然后将C1置为底电平,等待接收端C2的底电平响应。(因为CPU执行指令是需要时间的,如果发送端先将C1置为底电平,然后再置D1和D2的电平,接收端恰好在C1刚为底电平时,检测到并且读取了D1和D2的状态。发送端还没来的及对D1和D2置需要的电平,这时就读到了错误的数据。虽然概率很小,但是这样可以避免。)
步骤二:接收端,检测到C1的状态是0时,表示发送端在发送1比特数据,接收端读取D1,D2的电平状态接收后,C2置为底电平,表示己接收。然后等待接收端将C1恢复为高电平
步骤三:发送端,检测到C2被置为底电平,表示接收端收到了数据,于是C1恢复为高电平等待C2恢复为高电平
步骤四:接收端,检测到C1恢复为高电平,将C2恢复为高电平。
步骤五:发送端,检测到C2恢复为高电平,继续发送下一个比特。跳到步骤一(循环)。


分析协议在传输数据过程中受到干扰会发生的状态
在正常工作的情况下,数据会由发送端发送,接收端完成接收,一直运行。但是设计协议需要考虑到抗干扰性,受到干扰之后,协议能够恢复正常工作,继续传输数据,而不是停在某个状态。(例如:发送端在等待接收端响应,接收端同时也在等在发送端响应,一直停在这样的状态)。
现在我们来分类别分析发送端和接收端的等待情况,检查看能否发生同时等待的现象,造成死锁,数据传输停在这个状态。
发送端发生等待的2种情况:
(1)    发送端C1置底电平,等待接收端C2底电平响应     (在第一步)
(2)    发送端C1置高电平,等待接收端C2高电平响应     (在第五步)  
接收端发生等待的2种情况:
(1)    接收端C2是高电平,等待发送端C1的底电平          (在第一步)         
(2)    接收端C2置底电平,等待发送端C1高电平响应     (在第二步)
分析控制线的状态:如果有一个条件符合,其中的一端控制线的电平就会发生改变,不会发生死锁。如果没有条件符合,就会发生死锁。
分析1:发送端(1)和接收端(1)相结合,总有一个条件符合,不会发生死锁。
分析2:发送端(1)和接收端(2)相结合,总有一个条件符合,不会发生死锁。
分析3:发送端(2)和接收端(1)相结合,总有一个条件符合,不会发生死锁。
分析4:发送端(2)和接收端(2)相结合,总有一个条件符合,不会发生死锁。
结论:不会发生死锁
现在我们再来分类别分析发送端和接收端的异常情况,数据在传输时,会发生的情况。
1、接收端和发送端两片单片机不是同时启动分两种情况
(1)发送端先启动,接收端后启动,结果:接收端启动后开始检测C1的电平,接收比特数据,不影响。
(2)接收端先启动,发送端后启动,结果:发送端启动后,如果有数据,置C1为底电平,开始发送比特数据,不影响。
2、接收端在接收比特数据的时候死机重启分2种情况
      (1)在步骤一,接收端死机重启后,接收端检测到C1为0,开始接收数据。如果不是开始位,丢弃接收到的比特,直到收到开始位。结果:会丢弃不完整数据,继续接收,恢复通讯。
     (2)在步骤三,接收端死机重启后,接收端默认置C2为高电平,发送端检测到C2为高电平,认为接收端响应,继续发送下1比特数据。接收端开始接收比特数据。结果:会丢弃不完整数据,继续接收,恢复通讯。
    (3)在步骤五,接收端死机重启后,结果和(步骤三)一样。
3、发送端在发送比特数据的时候死机重启分 3种情况
(1)在步骤二,发送端死机重启后,发送端恢复到初始状态,开始发送1比特,置C1为0。接收端在等待C1为1,等不到。但是接收端检测到C2被接收端己置为0,发送端认为接收端己收到数据,发送端响应,置C1 为1,接着正常执行后面的步骤。结果:发送端发送的这1比特丢失,会丢弃不完整的数据,继续接收,恢复通讯。
(2)在步骤二,发送端死机重启后,发送端恢复到初始状态,开始发送1比特,置C1为0的过程中。在发送端重启过程中,C1有一段时间为高电平,接收端正好收到,并响应。接收端进入步骤四。
(3)在步骤四,发送端死机重启后,发送端恢复到初始状态,开始发送1比特,置C1为0。接收端己完成1比特接收,没有等待,继续接收数据。结果:会丢弃不完整的数据,继续接收,恢复通讯。
4、在发送数据的1个初始状态和5个步骤过程中,控制线电平受到干扰分类别分析
(1)在初始状态,发送端没有数据需要发送:C1,C2全部为高电平,这时,接收端在等待C1的底电平到来然后接收比特数据。C1,C2受到干扰,由高电平变为底电平。
接收端的代码如果正好执行到检测C1位置,接收端响应,进入步骤二,等待C1恢得为高电平。干扰消除后,C1恢复为高电平,接收端进入步骤四完成1比特数据接收,继续接收下1比特数据。结果:接收1比特错误数据,续续接收,恢复通讯。
接收端的代码如果没有执行到检测C1位置,干扰消除。结果:无影响。
初始状态,发送端没有检测C2状态,受到干扰,无影响。
(2)在步骤1,发送端发送1比特数据,置C1为底电平,发送端等待C2的底电平来到来。C2受到干扰,由高电平变为底电平。
     发送端的代码如果正好执行到检测C2位置,发送端认为接收端己接收到1比特数据并响应,发送端进入步骤三,置C1为高电平,等待C2恢复为高电平。干扰消除后,C2恢复为高电平。发送端进入到步骤五。结果:接收端少收到1比特数据,恢复通讯。
发送端的代码如果正好执行到检测C2位置,同时,接收端检测到C1为底电平,接收1比特数据并响应C2为底电平。结果:接收端正确收到1比特数据,无影响。
发送端的代码如果没有执行到检测到C2的位置,干扰消除。结果:无影响。
(3)在步骤2,接收端收到1比特数据,置C2为底电平,接收端等待C1的高电平到来。C1受到干扰,由底电平变为高电平。
     接收端代码正好执行到检测C1位置,接收端认为发送端响应,接收端完成1比特数据接收,进入步骤四,恢复C2为高电平。干扰消除后,继续接收发送端的数据。结果:收到错误的1  比特数据,恢复通讯。
     接收端代码没有执行到检测C1的位置,干扰消除。结果:无影响。
(4)在步骤3,发送端等待C2为高电平。受到干扰,C2变为高电平。
发送代码正好执行到检测C2位置,发送端认为接收端响应,跳到步骤五。如果此时接收端正好响应,则完成1比特数据发送。结果:无影响。
发送端等待C2为高电平。受到干扰,C2变为高电平。发送代码正好执行到检测C2位置,发送端认为接收端响应,跳到步骤五,然后又跳到步骤一,发送到下1比特数据。此时接收端在等待C1的高电平,然而C1是底电平,接收端继续等待。但是C2被接收端置为底电平,发送端认为接收端己接收1比特数据响应。进入步骤三,置C1为1,接收端响应,完成1比特数据接收。结果:接收端少收到1比特数据。
(5)在步骤4,接收端己完成接收,接收端在检测C1的底电平到来,接收数据。
       C1受到干扰,由高电平变为底电平,然后干扰消除恢复为高电平。接收端会多收到1比特数据。当然这比特数据是错误的数据。结果:收到错误的1比特数据,恢复通讯。
        C2受到干扰,由高电平变为底电平,干扰消除后恢复为高电平。因为发送端在这一步骤在等待接收端C2的高电平,然后发送数据,结果:干扰消除后发送端开始发送数据,无影响。
(6)在步骤5,实际就是初始状态。受到干扰发生的情况,也一样,就不再重复。

结论:受到干扰有三种结果:1,多收到1比特数据(数据是错误的)。2,少收到1比特数据。3,收到1比特错误数据。所以通信协议在受到干扰的情况下,不能保证数据的完整性,但是干扰消除,能够恢复通讯。这个通信方式,设计的时候,是尽可能的让数据传输,需要上层的通信协议来识别数据是否正确。
image003.jpg
0.png 0.jpg

全部资料51hei下载地址(源码+资料):
四根线进行通讯协议设计.rar (2.21 MB, 下载次数: 159)

评分

参与人数 2黑币 +115 收起 理由
perfect123 + 15 目前用不到,但是先赞一个
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:98767 发表于 2018-4-16 01:03 | 显示全部楼层
这个不错,谢谢分享
回复

使用道具 举报

ID:79034 发表于 2018-12-5 11:16 | 显示全部楼层
这个应该顶一下
回复

使用道具 举报

ID:46999 发表于 2018-12-6 09:54 | 显示全部楼层
这种资料很少。感谢楼主的分享!
回复

使用道具 举报

ID:71233 发表于 2019-3-5 15:41 | 显示全部楼层
厉害厉害,只是需要的连线偏多,但速度一定棒!
回复

使用道具 举报

ID:526585 发表于 2019-5-12 13:44 | 显示全部楼层
源代码看不了
回复

使用道具 举报

ID:519089 发表于 2020-10-30 20:31 | 显示全部楼层
8根线有点太多了,2根IO线就足够全双工通信了
回复

使用道具 举报

ID:615192 发表于 2020-11-7 15:50 | 显示全部楼层
单工通讯是不是一根IO就可以啦
回复

使用道具 举报

ID:387856 发表于 2020-11-9 10:38 | 显示全部楼层
这个实用性不强吧,IO占用太多了,还不如采用红外线协议做通讯呢
回复

使用道具 举报

ID:349362 发表于 2021-5-5 14:30 | 显示全部楼层
这个不错测试下看
回复

使用道具 举报

ID:519089 发表于 2021-7-14 19:11 | 显示全部楼层
单总线就可以 了
回复

使用道具 举报

ID:953589 发表于 2021-7-27 08:18 | 显示全部楼层
这个很不错
回复

使用道具 举报

ID:87000 发表于 2021-7-27 14:42 | 显示全部楼层
1根线应该可以吧?

单总线模式
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表