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();