/*****************************************************************
程序说明:EEPROM 24C64子程序
注:(1)单片机:AT89S52晶振Fosc:11.0592MHz编程软件:Keil uVision2;
(2)地址为000;容量为8K;I2C 在时钟线为高时数据被写入
(3)I2C 开始信号:在时钟线为高时 数据线产生下降沿
I2C 结束信号:在时钟线为高时 数据线产生上降沿
I2C 主机应答:主机要继续从从机读数据 需给应答信号 即向从机写入0
I2C 主机无应答:主机不要继续从从机读数据 需给无应答信号 即向从机写入1
I2C 从机应答:主机向从机写入数据后 从机给应答信号 写入成功为0 失败为1
(4)AT24C64 写入时 先写到数据缓冲区 要延时5ms
******************************************************************/
//-----------------------------------------------------------------
// 头文件包含
//-----------------------------------------------------------------
#include
//-----------------------------------------------------------------
// EEPROM 24C64系列 接口引脚
//-----------------------------------------------------------------
#define AT24C64_SDA P3_7 //I2C数据线
#define AT24C64_SCL P3_6 //I2C时钟线
//-----------------------------------------------------------------
// 数据类型宏定义
//-----------------------------------------------------------------
#define uchar unsigned char
#define uint unsigned int
//-----------------------------------------------------------------
// 功能程序区
//-----------------------------------------------------------------
// I2C 开始信号
void I2C_Start(void)
{
AT24C64_SDA=1; //数据线产生下降沿
Delay(I2C_TIME); //延时(I2C_TIM)us
AT24C64_SCL=1; //时钟线为高
Delay(I2C_TIME); //延时(I2C_TIM)us
AT24C64_SDA=0; //
Delay(I2C_TIME); //延时(I2C_TIM)us
AT24C64_SCL=0; //时钟线拉低
Delay(I2C_TIME); //延时(I2C_TIM)us
}
// I2C 结束信号
void I2C_Stop(void)
{
AT24C64_SDA=0; //数据线产生上降沿
Delay(I2C_TIME); //延时(I2C_TIM)us
AT24C64_SCL=1; //时钟线为高
Delay(I2C_TIME); //延时(I2C_TIM)us
AT24C64_SDA=1; //
Delay(I2C_TIME); //延时(I2C_TIM)us
AT24C64_SCL=0; //时钟线拉低
Delay(I2C_TIME); //延时(I2C_TIM)us
}
// I2C 主机应答
void I2C_Ack(void)
{
AT24C64_SDA=0; //数据线为0 向从机写入0
Delay(I2C_TIME); //延时(I2C_TIM)us
AT24C64_SCL=1; //时钟线为高时数据被写入
Delay(I2C_TIME); //延时(I2C_TIM)us
AT24C64_SCL=0; //时钟线拉低
Delay(I2C_TIME); //延时(I2C_TIM)us
}
// I2C 主机无应答
void I2C_NAck(void)
{
AT24C64_SDA=1; //数据线为1 向从机写入1
Delay(I2C_TIME); //延时(I2C_TIM)us
AT24C64_SCL=1; //时钟线为高时数据被写入
Delay(I2C_TIME); //延时(I2C_TIM)us
AT24C64_SCL=0; //时钟线拉低
Delay(I2C_TIME); //延时(I2C_TIM)us
}
// 函数功能: I2C 从机应答
uchar I2C_Get_Ack(void)
{
uchar temp;
AT24C64_SDA=1; //单片机读数据线时写1
Delay(I2C_TIME); //延时(I2C_TIM)us
AT24C64_SCL=1; //时钟线为高时数据被读出
Delay(I2C_TIME); //延时(I2C_TIM)us
temp=AT24C64_SDA; //数据读到端口
Delay(I2C_TIME); //延时(I2C_TIM)us
AT24C64_SCL=0; //时钟线拉低
Delay(I2C_TIME); //延时(I2C_TIM)us
return temp; //返回从机应答值
}
// I2C 写入一个字节
uchar I2C_Write_Byte(uchar dat)
{
uchar i,temp;
temp=dat;
for(i=0;i<8;i++)
{
AT24C64_SDA=((dat< // temp<<=1; //左移
// AT24C64_SDA=CY; //溢出值送到端口
AT24C64_SCL=1; //时钟线为高时数据被写入
Delay(I2C_TIME); //延时(I2C_TIM)us
AT24C64_SCL=0; //时钟线拉低
Delay(I2C_TIME); //延时(I2C_TIM)us
}
return I2C_Get_Ack(); //返回从机应答信号
}
// 函数功能: I2C 读出一个字节
uchar I2C_Read_Byte(void)
{
uchar i,rbyte=0;
AT24C64_SDA=1; //单片机读数据线时写1
for(i=0;i<8;i++)
{
AT24C64_SCL=1; //时钟线为高时数据被读出
Delay(I2C_TIME); //延时(I2C_TIM)us
if(1==AT24C64_SDA)
{
rbyte|=(0x80>>i); //读取低位
}
AT24C64_SCL=0; //时钟线拉低
Delay(I2C_TIME); //延时(I2C_TIM)us
}
return rbyte;
}
// AT24C64 写入一个字节
void AT24C64_Write_Byte(uint addr,uchar dat)
{
I2C_Start(); //开始信号
I2C_Write_Byte(0xa0); //写入配置信息 1 0 1 0 A2 A1 A0 R/W
I2C_Write_Byte(addr>>8); //写入高位地址
I2C_Write_Byte(addr); //写入低位地址
I2C_Write_Byte(dat); //写入数据
I2C_Stop(); //结束信号
Delay_100us(50); //延时5ms
}
// AT24C64 写入一页字节
void AT24C64_Write_Page(uint addr,uchar *pbuf)
{
uchar i;
I2C_Start(); //开始信号
I2C_Write_Byte(0xa0); //写入配置信息 1 0 1 0 A2 A1 A0 R/W
I2C_Write_Byte(addr>>8); //写入高位地址
I2C_Write_Byte(addr); //写入低位地址
for(i=0;i<32;i++)
{
if(addr>AT24C64_END) //结束地址(听诊器用)
{
addr=AT24C64_START; //开始地址(听诊器用)
I2C_Write_Byte(addr>>8);//写入高位地址
I2C_Write_Byte(addr); //写入低位地址
}
I2C_Write_Byte(pbuf[i]); //写入数据
}
I2C_Stop(); //结束信号
Delay_100us(50); //延时5ms
}
// AT24C64 读出连续字节
void AT24C64_Current_Addr_Read_Byte(uint length,uchar *pbuf)
{
uchar i;
I2C_Start(); //开始信号
I2C_Write_Byte(0xa1); //写入配置信息 1 0 1 0 A2 A1 A0 R/W
for(i=0;i
pbuf[i]=I2C_Read_Byte(); //读出数据
I2C_Ack(); //主机应答
}
pbuf[i]=I2C_Read_Byte(); //读出最后一位数据
I2C_NAck(); //主机无应答
I2C_Stop(); //结束信号
}
// AT24C64 读出一字节
uchar AT24C64_Read_Byte(uint addr)
{
uchar temp;
I2C_Start(); //开始信号
I2C_Write_Byte(0xa0); //写入配置信息 1 0 1 0 A2 A1 A0 R/W
I2C_Write_Byte(addr>>8); //写入高位地址
I2C_Write_Byte(addr); //写入低位地址
AT24C64_Current_Addr_Read_Byte(1,&temp);//长度为1
return temp;
}
// AT24C64 读出连续字节
void AT24C64_Sequential_Read(uint addr,uint length,uchar *pbuf)
{
I2C_Start(); //开始信号
I2C_Write_Byte(0xa0); //写入配置信息 1 0 1 0 A2 A1 A0 R/W
I2C_Write_Byte(addr>>8); //写入高位地址
I2C_Write_Byte(addr); //写入低位地址
AT24C64_Current_Addr_Read_Byte(length,pbuf);//长度为length
}
//-----------------------------------------------------------------
// END of FILE
//-----------------------------------------------------------------