AT24C02,iic通讯,写入寄存器后不能读取或只能读取其中一个
需要在写入数据后,延时一下,让数据能缓存进去。在进行下一步操作。
读操作没有延时要求。
改正之前:
// 读写操作
u8 AT24C02_WriteReadCompare()
{
u8 readda = 0;
write_add(0xA0, 0x00, 0x55);
write_add(0xA0, 0x02, 0x55);
write_add(0xA0, 0x01, 0x55);
if ((read_add(0xA0, 0x01) == 0x55) && (read_add(0xA0, 0x02) == 0x55) && (read_add(0xA0, 0x00) == 0x55))
{
PrintString1("AT24C02_WriteReadCompare OK");
readda = 1;
}
else
{
PrintString1("AT24C02_WriteReadCompare NG");
readda = 0;
}
return readda;
}
改正之后:
// 读写操作
u8 AT24C02_WriteReadCompare()
{
u8 readda = 0;
write_add(0xA0, 0x00, 0x55);
delay_ms(100);
write_add(0xA0, 0x02, 0x55);
delay_ms(100);
write_add(0xA0, 0x01, 0x55);
delay_ms(100);
if ((read_add(0xA0, 0x01) == 0x55) && (read_add(0xA0, 0x02) == 0x55) && (read_add(0xA0, 0x00) == 0x55))
{
PrintString1("AT24C02_WriteReadCompare OK");
readda = 1;
}
else
{
PrintString1("AT24C02_WriteReadCompare NG");
readda = 0;
}
return readda;
}
iic的初始代码:
#include "iic.h"
#include "delay.h"
void IIC_Delay() //前图中大于4us或4.7us的延时
{
Delay1us();
Delay1us();
Delay1us();
Delay1us();
}
void IIC_Init() //将两根线拉高,进入初始状态,等待开始信号
{
SDA = 1;
SCL = 1;
}
void IIC_Start() //起始信号,SCL为高时,SDA由高变低
{
SCL = 1;
SDA = 1;
IIC_Delay();
SDA = 0;
IIC_Delay();
SCL = 0;
IIC_Delay();
}
void IIC_Stop() //结束信号,SCL为高时,SDA由低变高
{
SCL = 0;
SDA = 0;
IIC_Delay();
SCL = 1;
IIC_Delay();
SDA = 1;
IIC_Delay();
}
void IIC_ACK() //应答信号
{
unsigned char i=0;
SCL = 1; //SCL为高时,接收应答
IIC_Delay();
while((SDA==1)&&(i<255)) //过了一段时间SDA仍为高,就是非应答信号;否则,SDA=0,返回应答信号
i++;
SCL = 0; //应答后拉低时钟线,等待结束信号
IIC_Delay();
}
//写一个字节,从高位到低位发送
void IIC_Write_Byte(unsigned char j){
unsigned char i,temp;
temp = j;
SCL = 0; //数据只在SCL为低时允许改变
IIC_Delay();
for(i=0;i<8;i++)
{
temp <<= 1; //temp = temp << 1,从高到低依次移出
SDA = CY; //CY为PSW状态寄存器中的最高位,1000 0000<<1,CY=1;0000 0001>>1,CY=1.CY就是移出来的那一位
IIC_Delay();
SCL = 1; //等待SDA数据稳定
IIC_Delay();
SCL = 0; //等待下一次发送
IIC_Delay();
}
SDA = 1;
IIC_Delay();
}
//读一个字节,从低位到高位读
unsigned char IIC_Read_Byte()
{
unsigned char i,j,k=0;
SCL = 0; //拉低时钟线,等待数据变化
IIC_Delay();
for(i=0;i<8;i++)
{
SCL = 1; //在这个时刻已经获取到了SDA的一位数据
IIC_Delay();
if(SDA == 1)
j = 1;
else
j = 0;
k = (k<<1) | j; //k依次往右移,最低位每次接受新的SDA 变化
SCL = 0; //等待下一次数据变化
}
return(k); //返回读到的字节数据
}
void write_add(u8 iic,u8 address,u8 date){
IIC_Start();//发送起始信号
IIC_Write_Byte(iic);//发送从机地址
IIC_ACK();//应答信号
IIC_Write_Byte(address);//发送寄存器地址
IIC_ACK();//应答信号
IIC_Write_Byte(date);//发送数据
IIC_ACK();//应答信号
IIC_Stop();//发送停止信号
}
u8 read_add(u8 iic,u8 address){
u8 date;
IIC_Start();//发送起始信号
IIC_Write_Byte(iic);//发送从机地址
IIC_ACK();//应答信号
IIC_Write_Byte(address);//发送寄存器地址
IIC_ACK();//应答信号
IIC_Start();//发送起始信号
IIC_Write_Byte(iic+1);//发送从机地址
IIC_ACK();//应答信号
date=IIC_Read_Byte();//读数据
IIC_Stop();//发送停止信号
return date;//返回数据
}