一、实物图
二、原理图
编号 | 名称 | 功能 |
1 | A0 | 地址输入。A2、A1和A0是器件地址输入引脚。
24C02/32/64使用A2、A1和AO输入引脚作为硬件地址,总线上可同时级联8个24C02/32/64器件。 24C04使用A2和A1输入引脚作为硬件地址,总线上可同时级联4个24CO4器件,A0为空脚,可接地。 24C08使用A2输入引脚作为硬件地址,总线上可同时级联2个24C08器件,AO和A1为空脚,可接地。 24C16未使用器件地址引脚,总线上最多只可连接一个16K器件,A2、A1和A0为空脚,可接地。 |
2 | A1 | |
3 | A2 | |
4 | GND | 电源地 |
5 | SDA | 串行地址和数据输入/输出。SDA是双向串行数据传输引脚,漏极开路,需要外接上拉电阻到VCC(典型值10k)。 |
6 | SCL | 串行时钟输入。SCL同步数据传输,上升沿数据写入,下降沿数据读出。 |
7 | WP | 写保护。WP引脚提供硬件数据保护。当WP接地时,允许数据正常读写操作;当WP接VCC时,写保护,只读。 |
8 | VCC | 电源正(1.8~5.5V) |
三、简介
AT24C02是美国Atmel公司的低功耗CMOS型E2PROM,内含256*8位存储空间;具有工作电压宽(1.8V~5.5V):擦写次数多(大于10000次):写入速度快(小于10ms),抗干扰能力强,数据不易丢失,体积小等特点。并且它是采用I2C总线式进行数据读写的串行操作,只占用很少的资源和I/O线。
四、内部结构框图
五、寻址方式
AT24C02的存储容量为2K bit,内容分成32页,每页8Byte,共256Byte,操作时有两种寻址方式:芯片寻址和片内子地址寻址。
(1)芯片寻址:AT24C02的芯片地址为1010,其地址控制字格式为1010 A2 A1 A0 R/W。其中A2,A1,A0可编程地址选择位。A2,A1,A0引脚接高、低电平后得到确定的三位编码,与1010形成7位编码,即为该器件的地址码。R/W为芯片读写控制位,该位为0,表示芯片进行写操作;该位为1,表示芯片进行读操作。
(2)片内子地址寻址:芯片寻址可对内部256Byte中的任意一个进行读/写操作,其寻址范围为00~FF,共256个寻址单位。
六、通信协议(I2C通信)
1、I2C总线介绍
I2C总线(Inter IC bus)是由Philips公司开发的一种通用数据总线。
两根通信线:SCL(Serial Clock串行时钟线)、SDA(Serial Data串行数据线)。
同步、半双工,带数据应答。
*注:同步(因为它有单独的时钟线)、半双工(SDA只有一根线,并且还要来回通信)
通用的I2C总线,可以使各种设备的通信标准统一,对于厂家来说,使用成熟的方案可以缩短芯片设计周期、提高稳定性,对于应用者来说,使用通用的通信协议可以避免学习各种各样的自定义协议,降低了学习和应用的难度。
2、I2C电路规范
所有I2C设备的SCL连在一起,SDA连在一起
设备的SCL和SDA均要配置成开漏输出模式(硬件IIC)
*开漏输出模式——断开时引脚成浮空状态(电路断开,电压不稳定)
SCL和SDA各添加一个上拉电阻,阻值一般为4.7K~10K左右
开漏输出和上拉电阻的共同作用实现了“线与”的功能,此设计主要是为了解决多机通信互相干扰的问题。
3、I2C时序结构
起始信号:SCL高电平期间,SDA从高电平切换到低电平
停止信号:SCL高电平期间,SDA从低电平切换到高电平
代码如下:
/****
*******I2C总线启动信号
*****/
void AT24C02_IIC_Start(void)
{
AT24C02_SDA = 1;
AT24C02_SCL = 1;
AT24C02_IIC_Delay(DELAY_TIME);
AT24C02_SDA = 0;
AT24C02_IIC_Delay(DELAY_TIME);
AT24C02_SCL = 0;
}
/****
*******I2C总线停止信号
*****/
void AT24C02_IIC_Stop(void)
{
AT24C02_SDA = 0;
AT24C02_SCL = 1;
AT24C02_IIC_Delay(DELAY_TIME);
AT24C02_SDA = 1;
AT24C02_IIC_Delay(DELAY_TIME);
}
发送应答:在接收完一个字节之后,主机在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答。
接收应答:在发送完一个字节之后,主机在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)。
代码如下:
/****
*******发送应答或非应答信号
*****/
void AT24C02_IIC_SendAck(bit ackbit)
{
AT24C02_SCL = 0;
AT24C02_SDA = ackbit;
AT24C02_IIC_Delay(DELAY_TIME);
AT24C02_SCL = 1;
AT24C02_IIC_Delay(DELAY_TIME);
AT24C02_SCL = 0;
AT24C02_SDA = 1;
AT24C02_IIC_Delay(DELAY_TIME);
}
/****
*******等待应答信号
*****/
bit AT24C02_IIC_WaitAck(void)
{
bit ackbit;
AT24C02_SDA = 1;
AT24C02_SCL = 1;
AT24C02_IIC_Delay(DELAY_TIME);
ackbit = AT24C02_SDA;
AT24C02_SCL = 0;
AT24C02_IIC_Delay(DELAY_TIME);
return ackbit;
}
发送一个字节:SCL低电平期间,主机将数据位依次放到SDA线上(高位在前),然后拉高SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节。
代码如下:
/****
*******I2C总线发送一个字节数据
*****/
void AT24C02_IIC_SendByte(uchar byte)
{
uchar i;
AT24C02_SCL = 0;
for(i=0; i
{
if(byte & 0x80)
AT24C02_SDA = 1;
else
AT24C02_SDA = 0;
AT24C02_IIC_Delay(DELAY_TIME);
AT24C02_SCL = 1;
AT24C02_IIC_Delay(DELAY_TIME);
AT24C02_SCL = 0;
AT24C02_IIC_Delay(DELAY_TIME);
byte
}
AT24C02_IIC_WaitAck();
}
接收一个字节:SCL低电平期间,从机将数据位依次放到SDA总线上(高位在前),然后拉高SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA)
代码如下:
/****
*******I2C总线接收一个字节数据
*****/
uchar AT24C02_IIC_RecByte(bit ackbit)
{
uchar i, dat;
AT24C02_SDA = 1;
for(i=0; i
{
AT24C02_SCL = 1;
AT24C02_IIC_Delay(DELAY_TIME);
dat
if(AT24C02_SDA)
dat |= 1;
AT24C02_SCL = 0;
AT24C02_IIC_Delay(DELAY_TIME);
}
AT24C02_IIC_SendAck(ackbit);
return dat;
}
4、AT24C02数据帧
AT24C02的固定地址为1010,本设计A2 A1 A0都接地,所以SLAVE ADDRESS+W为0xA0(1010 000 0),SLAVE ADDDRESS+R为0xA1(1010 000 1)
字节写:在“字地址”处写入“数据”
代码如下:
/****
*******向AT24C02的地址address中写入一个字节的数据
*****/
void At24c02_Write_Data(uchar address,uchar dat)
{
AT24C02_IIC_Start();
AT24C02_IIC_SendByte(AT24C02_SlaveAddress);
AT24C02_IIC_SendByte(address);
AT24C02_IIC_SendByte(dat);
AT24C02_IIC_Stop();
}
随机读:读出在“字地址”处的“数据”
代码如下:
/****
*******从AT24C02的地址address中读取一个字节的数据
*****/
uchar At24c02_Read_Data(uchar address)
{
uchar dat;
AT24C02_IIC_Start();
AT24C02_IIC_SendByte(AT24C02_SlaveAddress);
AT24C02_IIC_SendByte(address);
AT24C02_IIC_Start();
AT24C02_IIC_SendByte(AT24C02_SlaveAddress + 1);
dat = AT24C02_IIC_RecByte(AT24C02_ACK);
AT24C02_IIC_Stop();
return(dat);
}
七、流程设计
首先初始化引脚,然后判断是写数据还是读数据,如果是写数据,则首先启动I2C总线,然后发送器件写地址,等待应答,接下来发送数据地址,等待应答,再接下来写入数据,等待应答,最后关闭I2C总线。如果是读数据,则首先启动I2C总线,然后发送器件写地址,等待应答,接下来发送目标地址,等待应答,再次启动I2C总线,然后发送器件读地址,等待应答,接下来读取数据,发送应答,最后关闭I2C总线。