2018/4/16
51单片机
1.说在前面:
今天朋友拿了一个ADDA模块,但是看到上面的SDA,SCL,瞬间就蒙了,学过的东西要记住去复习,边用边学,边用边复习
2.i2c
1.介绍:是一种串行总线,结构比较简单,只有SDA(数据线)和SCL(时间线)
2.预备知识:
2-1.该总线是使用了上拉电阻来接正电源,总线为空闲(无数据交流),两根线都为高点平,但是任一为低电平,会拉低总线电平
2-2:在i2c进行数据传输的时候,只有时钟信号为高电平时,数据线上的数据才处于稳定状态,时钟信号为低电平的时候,数据线上才可以进行修改
2-3:SCL为高电平的时候,SDA从高变为低为起始状态,SCL为高电平,SDA从低变为高位终止
3.模式配置代码
1.时序图
起始位配置(I2cStart())
void Delay10us(void) { unsigned char a,b; for(b=1,b>0;b++) { for(a=2;a>0;a--); } } //模拟起始信号 void I2cStart() { SDA=1; Delay10us();//10us SCL=1; Delay10us();//10us SDA=0; Delay10us();//10us SCL=0; Delay10us();//10us }
终止位配置( I2cStop())
void I2cStop() { SDA=0; Delay10us();//10us SCL=1; Delay10us();//10us SDA=1; Delay10us();//10us }
判断发送信号正误(1/0)
unsigned char I2cSendByte(unsigned char dat)//获得返回值,判断是否发送正确 { unsigned char a=0; for(a=0;a<8;a++) { SDA=dat>>7;//SDA来检测高位 dat=dat<<1;循环向回推 Delay10us();//总线时序最高4.7us SCL=1;//保持时钟线稳定 Delay10us(); SCL=0;//改变数据 Delay10us(); } int b=0; while(SDA)//设置没有应答的情况,返回1 { b++;//设置变量 if(b>200)//超过200ms { SCL=0; Delay10us(); } } SCL=0; Delay10us(); return 1;//发送成功,返回1 }
读取数据 (SDA储存的数据)
//读取数据 unsigned char I2cReadByte() { unsigned char a=0,dat; for(a=0;a<8;a++) { SCL=1; Delay10us();//稳定数据 dat<<=1; dat|=SDA; Delay10us();//稳定数据 SCL=0; Delay10us(); } return dat; }
写入数据(写入初始地址和数据)
void At24c02Write(unsigned char addr,unsigned char dat) { I2cStart(); I2cSendByte(0xa0);//寄存器操作,写入 //发送数据 I2cSendByte(addr);//写入数据 I2cSendByte(dat);//写入数据, I2cStop();//停止 }
读取数据(注意状态反转)
unsigned char At24c02Read(unsigned char addr) { unsigned char num; I2cStart(); I2cSendByte(0xa0); I2cSendByte(addr);//发送首地址 I2cStart(); I2cSendByte(0xa1);//读取数据 I2cstop();