当时钟线SCL为高电平时 , 数据线SDA有高电平到低电平的下降沿。
代码:
void start()
{
SDA = 1;SCL = 1;delay(5us);
SDA = 0;delay(5us);SCL = 0;
}
当时钟线SCL为高电平时 , 数据线SDA由低电平到高电平的上升沿。
代码:
void stop()
{
SDA = 0;SCL = 1; delay(5us);
SDA = 1;delay(5us);SCL = 0;
}
应答信号表明IIC的数据传输结束 , IIC在传输一个字节的数据后著期间在第九个时钟周期释放总线SDA , 使其处于高电平 , 此时从器件输出低电平拉蒂数据SDA为应答信号。如果为高电平的话则时传送异常 , 结束发送。
代码:
bit ack()
{
bit ack_bit;
SDA = 1;delay(2us);SCL = 1;
ack_bit = SDA;delay(5us);SCL = 0;
return ack_bit;
}
当我们在进行读操作的时候 , 器件在读取8位数据之后 ,如果不在继续读取了就发送一个非应答信号 , 就是在第九个时钟周期时释放总线SDA , 将其拉高 持续整个时钟周期。
代码:
void Noack()
{
SDA = 1;delay(5us);
SCL = 1;delay(5us);SCL = 0;
}
iIC在在读写时 ,表示IIC总线忙 。要求在读或者写的时候(SCL=1)数据必须稳定 。
代码:
void write(byte)
{
SCL = 0;delay(5us);
if(byte & 0x80) SDA = 1;
else SDA = 0; delay(5us);
SCL = 1;delay(5us);
}
u8 read()
{
SDA = 1;
for( i = 0; i < 8;i++)\
{
value << 1;SCL = 1;delay(5us);
SCL = 0;delay(5us);
if(SDA) value |= 0x01;
}
SCL = 0;
return value;
}
现在以AT24C08为例 , 进行IIC读写
AT24C08支持IIC总线传输协议 , IIC总线协议规定 , 任何数据传送到总线的器件作为发送器 , 任何从总线接收数据的器件佳作接收器。数据传输是由产生串行时钟和所有起始信号的主器件控制的。主器件和从器件都可以作为发送器或者接收器。但是由主器件控制传送数据的模式。
字节写:在字节写模式下 , 主器件发送起始信号 ,和从地址信息给器件。从器件在产生应答后主器件发送字节地址 , 在收到从器件的另一个应答后在发送被寻址的储存单元。从器件再次应答后在发送被寻址的数据,在主器件产生停止信号的时候,开始内部数据的擦写。
代码:
viod EepromWrite(u8 CtrlAddr , u8 Addr , u8 data )
{
start();
write(CtrlAddr);
if(!ack()) return ;
write(Addr );
if(!ack()) return ;
write(data );
if(!ack()) return ;
stop();
}
页写:可以直接写入一个16字节的数据 , 页写操作的启动和字节写是一样的 , 不同的是在传输一个字节数据之后不产生停止信号 ,需要在发送16字节数据后发送起始信号 , 如果超所16字节 , 则会自动翻转 , 覆盖写入。
代码:
EepromPageWrite(u8 CtrlAddr , u8 Addr , u8 n,u8 *data )
{
start();
write(CtrlAddr);
if(!ack()) return ;
write(Addr );
if(!ack()) return ;
for( i = 0; i < n; i ++)
{
write(*data ++);
if(!ack()) return ;
}
}
读操作有3种基本的操作 , 立即地址读 , 选择性读 ,连续读,这里以选择性读为例。选择性读允许器件对寄存器的人以字节进行读操作。主器件发送起始信号 ,从器件地址和像读取的数据的地址。执行一个写的伪操作。器件重新发送控制字节 , 字节地址 , 数据将R/W置为1 , 然后从器件相应发送应答,然后输出所要求的8位字节数据 , 主器件产生一个停止信号。
代码:
u8 EepromRead(u8 CtrlAddr , u8 Addr , u8 data)
{
start();
write(CtrlAddr);
if(!ack()) return ;
write(Addr );
if(!ack()) return ;
write(CtrlAddr + 1);
if(!ack()) return ;
value = read();
Noack();
stop();
return value;
}
先有起始信号 , 在写一个控制字节字节地址的伪操作,然后写0xA1代表将要写 , 在根据地址去读数据。在我读的256字节中 00 FF FF FF …………我们可以校验一下。
……
现在我们看一下写操作,写操作的过程1 先将起始信号和写器件地址写进去 , 收到应答信号 后写字节信号 ,从器件继续应答 , 在写数据 , 然后8字节数据写完 ,应答信号标志着8字节数据发送到被心智的储存单元,最后有个停止信号。