1、单片机普通IO口模拟IIC多机通信本人已测试通过/* 说明,该程序是模拟IIC的通信思想,但也不全是,首先本人设计的不是从机与主机的通信,而是两单片机是平等的,单片机A可以向B或其他任何单片机发送数据(通过各个单片机所设置的地址来加以区分),同时单片机A可以也向B或其他任何单片机读取数据。反之单片机B或其他单片机也可以向A发送数据或读取A的数据,所以各个单片机的代码基本上是一样的,只需根据具体不同的需要调用就行。 由于本人初学单片机,代码写的并不是很好。望各位多多指教!*/单片机A 的代码#include#define uchar unsigned char#define uint unsig
2、ned int#define LOC_address 0x48sbit sda=P10;sbit scl=P11;sbit STROBE = P12;bit R_W;bit START_flag=0;uchar DEV_address;void delay() uint i; for(i=0;i=100;i+);void init() sda=1; scl=1; STROBE=1; void start() /启动I2C总线 sda = 1; delay(); scl = 1; delay(); sda = 0; delay(); / 此处scl不能拉低,否则两单片机通信时时序无法保持一致 /
3、*void start_scan() bit PreState; bit NowState; char NN = 10; PreState = sda; /记录当前SDA状态,用作比较 while(scl = 1 & NN-) NowState = sda; if(PreState = 1 & NowState = 0) /如果为下降沿则为开始信号 START_flag = 1; */void Send_Date(uchar j) unsigned char i; bit temp; scl = 1; while(STROBE); if(STROBE=0) delay(); delay();
4、delay(); for (i = 0 ;i 8 ;i+) if(ji)&0x80)temp=1; else temp=0; sda = temp; 、 delay(); scl = 0; delay(); scl = 1; delay(); scl = 0; sda = 1; /释放数据线 delay(); STROBE=1; STROBE=1;uchar Receive_Date() uchar i,j,k=0xff; scl = 1; STROBE=0; delay(); if(!scl)&(sda) return k; if(STROBE=0) while(scl); for(i=0;
5、i8;i+) while(!scl); if(sda=1) j=1; else j=0; k=(k1)|j; delay(); delay(); while(scl); P2=k; return k; return k;/*void ChackRdd() uchar i,j,k=0xff; scl = 1; STROBE=0; delay(); if(!STROBE) while(scl); for(i=0;i8;i+) while(!scl); if(sda=1) j=1; else j=0; k=(k1)|j; delay(); delay(); while(scl); P0=k; R_W
6、=k&0x01; DEV_address=(k&0xfe); STROBE=1; STROBE=1;void B_work() if(STROBE) ChackRdd(); if(DEV_address=LOC_address) if(R_W) STROBE=(STROBE); Send_Date(0x55); else if(!R_W) STROBE=(STROBE); Receive_Date(); */void main() init(); while(1)/以下为测试代码。 while(STROBE) while(STROBE) start(); while(!STROBE); /*
7、while(STROBE) Send_Date(0xaa); /发送地址和写指令 while(!STROBE) Send_Date(0x99); /发送数据 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90 */ while(STROBE) Send_Date(0xab); /发送地址和读指令 while(!STROBE) STROBE=1; Receive_Date(); /单片机B的代码#include#define uchar unsigned char#define uint unsigned int#define LOC_addres
8、s 0xaasbit sda=P10;sbit scl=P11;sbit STROBE = P12;bit R_W;bit START_flag=0;uchar DEV_address;void delay() uint i; for(i=0;i=100;i+);/*void start() /启动I2C总线 sda = 1; delay(); scl = 1; delay(); sda = 0; delay(); */void start_scan() bit PreState; bit NowState; char NN = 10; PreState = sda; /记录当前SDA状态,用
9、作比较 while(scl = 1 & NN-) NowState = sda; if(PreState = 1 & NowState = 0) /如果为下降沿则为开始信号 START_flag = 1; void Send_Date(uchar j) unsigned char i; bit temp; scl = 1; while(STROBE); if(STROBE=0) delay(); delay(); delay(); for (i = 0 ;i 8 ;i+) if(ji)&0x80)temp=1; else temp=0; sda = temp; delay(); scl = 0
10、; delay(); scl = 1; delay(); scl = 0; sda = 1; /释放数据线 delay(); STROBE=1; STROBE=1;uchar Receive_Date() uchar i,j,k=0xff; scl = 1; STROBE=0; delay(); if(!scl)&(sda) return k; if(STROBE=0) while(scl); for(i=0;i8;i+) while(!scl); if(sda=1) j=1; else j=0; k=(k1)|j; delay(); delay(); while(scl); P2=k; re
11、turn k; return k;void ChackRdd() uchar i,j,k=0xff; scl = 1; STROBE=0;/置低信号告诉单片机A、单片机B已做好准备接收 delay(); if(!STROBE) while(scl);/等待A响应 for(i=0;i8;i+) while(!scl); if(sda=1) j=1; else j=0; k=(k1)|j; delay(); delay(); while(scl); P0=k; R_W=k&0x01; DEV_address=(k&0xfe); STROBE=1; STROBE=1;void B_work() if(STROBE) start_scan(); if(START_flag) START_flag=0; STROBE=0; delay(); STROBE=1; ChackRdd(); if(DEV_address=LOC_address) if(R_W) STROBE=(STROBE); STROBE=1;/必须再次置高,使得两单片机在发送和接收数据时时序保持一致 Send_Date(0x80); else if(!R_W) STROBE=(STROBE); Receive_Date(); void main() STROBE=1; scl=1; while(1) B_work();
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1