模拟I2C总线多主通信研究与软件设计
写字节的子程序。由于时钟线是由主节点的MCU控制的,所以怎样根据SCL线来读取SDA线的数据是其中的一个难点。三是在具有子地址的从节点关于是写字节还是读字节时的判断。如果是写字节时主节点会给出新的起始信号,并再次发送从节点的地址数据。这时从节点需要做出判断是读取数据还是写数据,并进入相应的子程序。这里给出以上三个重点和难点的子程序的源代码,以供读者参考。这些源代码经实践证明都是正确的。
主节点的写字节子程序:
;其中的NOP可根据时钟的快慢自己加减
WRBYTE:MOV R0,#08H
CLR BUSY;将BUSY值清零
WLP: RLC A;取数据位
JC WR1
SJMP WR0;判断数据位
WLP1: DJNZ R0,WLP
NOP
OUT1: RET
WR1: SETB SDA;发送1
NOP
SETB SCL
MOV C,SDA;判断是否与发送的数据相同
JC GOON
SETB BUSY
AJMP OUT1
GOON: NOP
NOP
NOP
CLR SCL
SJMP WLP1
WR0: CLR SDA;发送0
NOP
SCL
NOP
NOP
NOP
NOP
NOP
CLR
SCL
SJMP WLP1
从节点的写字节子程序(返回为ACK):
SWRBYTE:MOV R0,#08H
WAGAIN: RRC A
MOV B,#37H
WWAIT1: JB SCL,WWAIT1;等待SCL为低
JC WR1;判断是发送"1"还是发送"0"
SETB SDA;发送"1"
AJMP COM
WR1: CLR SDA;发送"0"
COM: DJNZ R0,WWAIT2;判断是否发送完毕
WWAIT3: JNB SCL,WWAIT3;发送完毕等待应答信号
WWAIT4: JB SCL,WWAIT4
WWAIT5: JNB SCL,WWAIT5
CLR ACK
JB SDA,ST0
SETB ACK
ST0: RET;返回
WWAIT2: JNB SCL,WWAIT2;等待SCL为高
SJMP WAGAIN
从节点的读字节同时判断是否有起始信号的子程序。如果有起始信号,则转为写字节子程序:
SRDBYTE:MOV R0,#08H
SETB 20H;设置标志位判断是读还是写
SETB SDA;释放总线
RWAITJ: JNB SCL,RWAITJ;等待SCL为高
MOV C,SDA;从总线上读取数据
RRC A;存入累计器
DEC R0
MOV C,ACC.7;判断是否为起始信号
JNC RWAITJ1;为低继续读取数据
REWAIT: JNB SCL,RWAITJ1;开始判断是否为起始信号
JB SDA,REWAIT
CLR 20H;是,则清标志位并返回
AJMP SjRDOUT
RWAITJ1:JB SCL,RWAITJ1;等待SCL为低
RWAITJ3:JNB SCL,RWAITJ3;等待SCL为高
MOV C,SDA
RRC A
DJNZ R0,RWAITJ2
SjRDOUT:RET
RWAITJ2:JB SCL,RWAITJ2;等待SCL为低继续读数据
SJMP RWAITJ3
5 总结
根据总线协议中的仲裁原理,提出的基于延时比较的模拟I2C多主通信的方法,不仅能够体现了I2C总线的高效性,而且还具有良好的扩展性。它使普通不具有I2C接口的MCU可以应用在多主通信的系统中,既增加了普通MCU的使用范围,又突破了模拟I2C总线的应用局限性,为I2C总线的推广起到了积极的作用。
- I2C 总线接口逻辑分析(05-16)
- 基于DS3231的高精度时钟接口设计(03-21)
- 为数字温度传感器选择系统接口(05-09)
- 基于I2C总线的锅炉温度测量系统的设计与实现(04-25)
- I2C总线键盘电路以及驱动程序设计(05-25)
- 虚拟I2C总线串行显示电路介绍(05-21)