当前位置: 代码迷 >> 单片机 >> SDA SCL 在每个阶段到时是如何赋值的
  详细解决方案

SDA SCL 在每个阶段到时是如何赋值的

热度:163   发布时间:2016-04-28 16:24:43.0
SDA SCL 在每个阶段到时是怎么赋值的
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define NOP4() {_nop_();_nop_();_nop_();_nop_();}

sbit SCL = P1^0;
sbit SDA = P1^1;
sbit SPK = P3^0;

uchar code HI_LIST[] =
{
  0,226,229,232,233,236,238,240,241,242,245,246,247,248
};
uchar code LO_LIST[] =
{
  0,4,13,10,20,3,8,6,2,23,5,26,1,4,3
};
uchar code Song_24C04[] =
{
  1,2,3,1,1,2,3,1,3,4,5,3,4,5
};
uchar sidx;

void DelayMS(uint x)
{
uchar t;
while(x--)
{
for(t=120;t>0;t--);
}
}

void Start()
{
  SDA=1;SCL=1;NOP4();SDA=0;NOP4();SCL=0; //SDA在SCL 高电平期间由高电平跳变为低电平
}

void Stop()
{
  SDA=0;SCL=0;NOP4();SCL=1;NOP4();SDA=1; //SDA在SCL 高电平期间由低电平跳变为高电平
}

void RACK()
{
  SDA=1;NOP4();SCL=1;NOP4();SCL=0;
}

void NO_ACK()
{
  SDA=1;SCL=1;NOP4();SCL=0;SDA=0;
}

void Write_A_Byte(uchar b)
{
  uchar i;
for(i=0;i<8;i++)
{
b<<=1;SDA=CY;_nop_();SCL=1;NOP4();SCL=0;
}
RACK();
}

void Write_IIC(uchar addr,uchar dat)
{
  Start();
Write_A_Byte(0xa0);
Write_A_Byte(addr);
Write_A_Byte(dat);
Stop();
DelayMS(10);
}

uchar Read_A_Byte()
{
  uchar i,b;
for(i=0;i<8;i++)
{
SCL=1;b<<=1;B|=SDA;SCL=0;
}
return b;
}

uchar Read_Current()
{
  uchar d;
Start();
Write_A_Byte(0xa1);
d=Read_A_Byte();
NO_ACK();
Stop();
return d;
}

uchar Random_Read(uchar addr)
{
  Start();
Write_A_Byte(0xa0);
Write_A_Byte(addr);
Stop();
return Read_Current();
}

void T0_INT() interrupt 1
{
  SPK=!SPK;
TH0=HI_LIST[sidx];
TL0=LO_LIST[sidx];
}

void main()
{
  uchar i;
IE=0x82;//定时器0开中断
TMOD=0x00;
for(i=0;i<14;i++)
{
Write_IIC(i,Song_24C04[i]);
}
while(1)
{
for(i=0;i<14;i++)
{
sidx=Random_Read(i);
TR0=1;
DelayMS(300);
}
}
}




------解决方案--------------------
I2C的时序模拟, 楼主首先看下你对应控制的设备,比如E2PROM等,
其对应的时序中,是SCL下降沿还是上升沿传输数据。

51单片机采用I2C读写EEPROM的源代码:
http://download.csdn.net/source/1977557
51单片机采用I2C读写EEPROM的源代码,采用C实现51单片机通过I2C 总线EEPROM(具体型号为24C02)的读写,并采用LED和LCD分别显示读写的内容,值得参考。
------解决方案--------------------
SDA 和SCL 他们的高低电平,标识了IIC的不同工作状态,比如起始条件,数据传输阶段,终止条件

至于 ACK 那个是应答,应该是数据传输阶段的


楼主应该好好看看IIC的协议,讲的特别的清楚的
------解决方案--------------------
void RACK()
{
SDA=1;NOP4();SCL=1;NOP4();SCL=0;
}

void NO_ACK()
{
SDA=1;SCL=1;NOP4();SCL=0;SDA=0;
}

这个区别要看双方的协议的。
------解决方案--------------------
IIC协议基本上是相似的,但不同的芯片报文是有所不同的。你可以对照芯片的时序来看一下。
------解决方案--------------------
看Datasheet里面的时序图啊,
------解决方案--------------------
ACK就是从器件将DATA线拉低作为响应主器件的标志,相反的,NOACK就是不拉低DATA线。

单字节读写的ACK操作如下:
写时序:
开始条件——器件地址——ACK——寄存器地址——ACK——数据——ACK——结束条件

读时序:
开始条件——器件地址——ACK——寄存器地址——ACK——开始条件(注意!)——器件地址(最后一位要设置为1表示读操作)——ACK——此时从器件写数据——NOACK(注意,这里从器件不应答既DATA为高,如果应答的话就不对了)——结束条件

以上是最简单的读写。
  相关解决方案