基于延时比较的模拟I2C总线多主通信方法设计

图5 从节点部分的流程

图5给出了从节点的流程。进入从节点时,要将BUSY置为高,说明MCU现在正在工作,不能完成其他的任务。在MCU作为从节点完成接收任务后,要将BUSY置为低。MCU在接收到寻址字节后与自己的地址字节进行比较。如果是访问自己的就进入到下面的接收程序,否则跳出。在访问自己的时候,还要判断主节点是读取数据还是写数据,以便进入相应的程序。在写字节的子程序中,从节点每发送1个字节的数据后都要察看是否有应答信号(ACK),有则说明数据接收到了;否则要跳出等待,重新发送。在读字节的子程序中,每接收1个字节的数据就要发送1个应答信号(ACK),以示接收正常,否则主节点将停止继续发送。在现有的资料中,关于从节点的原理和源代码比较少,这里给出作为从节点时写字节子程序的源代码。由于篇幅有限其他的子程序没有列出。

4 部分源代码

本节是在MCU多主通信中的部分源代码。多主通信的实现中有几个难点和重点。一是在作为主节点时的写字节子程序,里面要包括发送的每位数据和总线的数据进行比较并做出判断。如果数据不同,要跳出并进入从节点的状态。由于子程序返回主程序时改变的只是PC的值而累加器(ACC)和工作寄存器(Ri)里面的值是不变的,因此MCU进入从机状态后继续接收总线剩下的数据,这样总线的数据并没有丢失。二是作为从节点时的写字节的子程序。由于时钟线是由主节点的MCU控制的,所以怎样根据SCL线来读取SDA线的数据是其中的一个难点。三是在具有子地址的从节点关于是写字节还是读字节时的判断。如果是写字节时主节点会给出新的起始信号,并再次发送从节点的地址数据。这时从节点需要做出判断是读取数据还是写数据,并进入相应的子程序。这里给出以上三个重点和难点的子程序的源代码,以供读者参考。这些源代码经实践证明都是正确的。

主节点的写字节子程序:

;其中的NOP可根据时钟的快慢自己加减

WRBYTE:MOVR0,#08H

CLRBUSY;将BUSY值清零

WLP: RLCA;取数据位

JC WR1

SJMPWR0;判断数据位

WLP1:DJNZR0,WLP

NOP

OUT1:RET

WR1: SETBSDA;发送1

NOP

SETB SCL

MOVC,SDA;判断是否与发送的数据相同

JC GOON

SETB BUSY

AJMP OUT1

GOON:NOP

NOP

NOP

CLRSCL

SJMPWLP1

WR0: CLRSDA;发送0

NOP