1、24C02模块的原理图:从图中可以看出,A0、A1、A2三个引脚全部接地,说明表示器件地址7位数据后三位全部是0
注:当上一个数据写完之后,若发送停止信号,则至少停下10ms时间后,才能再发送起始信号,这个时间就叫做写周期。
3、器件寻址:
4、字节写:
5、写页:
(1)、用页写,CAT24WC01可一次写入8个字节的数据,CAT24C02/04/08/16可以一次写入16个字节的数据。
(2)、页写操作的启动和字节写一样,不同在于传送了一字节数据后并不产生停止信号,主器件还可以被允许额外再发送7或者15个字节。
(3)、每发送一个字节数据后CAT24WCxx产生一个应答位,并将字节地址低位加1,高位保持不变。
(4)、若在发送停止信号之前主器件发送超过8个或16个字节,地址计数器将自动翻转,先前写入的数据被覆盖。
(5)、接收到P+1字节数据和主器件发送的停止信号后,CAT24Cxx启动内部写周期(10ms)将数据写到数据区,所有接收的数据在一个写周期内写入CAT24Cxx.
6、字节读:
读操作允许主器件对寄存器的任意字节进行读操作。主器件首先通过发送起始信号、从器件地址和它想读取的字节数据的地址执行一个写操作。在从器件应答之后,
主器件重新发送起始信号和从器件地址,此时R/W位置1,从器件响应并随机发送应答信号,然后输出所要求的一个8个字节数据,主器件不发送应答信号但产生一个停止信号。
7、连续读:
在从机给主机发送完一个8位字节数据后,主器件产生一个应答信号来响应,告诉从机主器件要求更多的数据,对应每个主机产生的应答信号,从机将发送一个8位数据字节。当主器件不发送应答信号而发送停止位时结束操作。
8、首先定义:
#define AT24C01 127
#define AT24C02 255 // AT24C02有255个字节
#define AT24C04 511
#define AT24C08 1023
#define AT24C016 2047
#define AT24C032 4095
#define AT24C064 8191
#define AT24C028 16383
#define AT24C0256 32767
#define EE_TYPE AT24C02 //从器件的类型
#define Device_Address //0xA0
9、读写字节:
(1)、读一个字节:
u8 read_OneByte(u16 addr) //addr表示主器件想读取的字节数据的地址,是16位的
{
u8 data;
I2C_Start();
if( EE_TYPE
>AT24C016 ) //读数据时是双字节寻址
{
send_Byte(0xA0);
I2C_Wait_ACK();
send_Byte(addr>>8); //先发送数据地址高位
}
else //读数据时是单字节寻址
send_Byte(0xA0+((addr/256)<<1)); //器件地址+数据地址高字节(数据地址一个字节表示不完,会挤到器件地址里面)
I2C_Wait_ACK();
send_Byte(addr%256); //数据地址低字节
I2C_Wait_ACK();
//开始读数据
I2C_Start();
send_Byte(0xA1); //最后一位为“1”,表示接下来是要读数据
I2C_Wait_ACK();
data=rev_Byte(0); //"0"表示主机不需要给从机应答
I2C_Stop();
return data;
}
(2)、写一个字节
void write_OneByte(u8 data, u16 addr) //将数据data写到从器件的地址为addr的缓冲区里面
{
I2C_Start();
if( EE_TYPE
>AT24C016 ) //读数据时是双字节寻址
{
send_Byte(0xA0);
I2C_Wait_ACK();
send_Byte(addr>>8); //先发送数据地址高位
}
else //读数据时是单字节寻址
send_Byte(0xA0+((addr/256)<<1)); //器件地址+数据地址高字节(数据地址一个字节表示不完,会挤到器件地址里面)
I2C_Wait_ACK();
send_Byte(addr%256); //数据地址低字节
I2C_Wait_ACK();
//开始写数据
send_Byte(data);
I2C_Wait_ACK();
I2C_Stop();
delay_ms(10ms); //延时10ms,也叫写周期
}
(3)、读两个字节:
u16 read_TwoByte(u16 addr) //addr表示主器件想读取的字节数据的地址,是16位的
{
u16 data;
I2C_Start();
if( EE_TYPE
>AT24C016 ) //读数据时是双字节寻址
{
send_Byte(0xA0);
I2C_Wait_ACK();
send_Byte(addr>>8); //先发送数据地址高位
}
else //读数据时是单字节寻址
send_Byte(0xA0+((addr/256)<<1)); //器件地址+数据地址高字节(数据地址一个字节表示不完,会挤到器件地址里面)
I2C_Wait_ACK();
send_Byte(addr%256); //数据地址低字节
I2C_Wait_ACK();
//开始读数据
I2C_Start();
send_Byte(0xA1); //最后一位为“1”,表示接下来是要读数据
I2C_Wait_ACK();
//先读高字节
data=rev_Byte(1)<<8; //"1"表示主机需要给从机应答
I2C_Wait_ACK();
//读低字节
data=data|rev_Byte(1); //"0"表示主机不需要给从机应答
I2C_Stop();
return data;
}
(4)、写两个字节:
void write_OneByte(u16 data, u16 addr) //将数据data写到从器件的地址为addr的缓冲区里面
{
I2C_Start();
if(EE_TYPE
>AT24C016 ) //读数据时是双字节寻址
{
send_Byte(0xA0);
I2C_Wait_ACK();
send_Byte(addr>>8); //先发送数据地址高位
}
else //读数据时是单字节寻址
send_Byte(0xA0+((addr/256)<<1)); //器件地址+数据地址高字节(数据地址一个字节表示不完,会挤到器件地址里面)
I2C_Wait_ACK();
send_Byte(addr%256); //数据地址低字节
I2C_Wait_ACK();
//先写低位数据
send_Byte(data>>8);
I2C_Wait_ACK();
//再发高字节
send_Byte(data&0xFF);
I2C_Wait_ACK();
I2C_Stop();
delay_ms(10ms); //延时10ms,也叫写周期
}