1、优化上节《51单片机——AT24C02_EEPROM驱动-模拟IIC通讯32页8字节缓存1.0》里的代码。
2、增添了读取AT24C02的状态、增添了有多少个AT24C02器件。
3、主要优化读、写,页读、页写,擦除里的代码,减少不必要的代码。
#ifndef __AT24C02_H__
#define __AT24C02_H__
extern unsigned char Mount_DDR_AT24C02[8];//挂载的器件地址,若为0则表示没有器件
extern unsigned char page_data_AT24C02[8];//页读取出来的数据存放位置
//读AT24C02状态是否在忙是否存在此器件读取时间10ms最大
extern bit read_status_AT24C02(unsigned char DDR);
//检测挂载多少个AT24C02,并将挂载的器件地址下入Mount_DDR_AT24C02数组里面
extern unsigned char Mount_Several_AT24C02(void);
//向某个器件存入数据,字节写,ddr表示器件地址,a_datax表示要将数据准备写入eeprom哪个地方,datax表示要写入到eeprom里的数据
//函数返回1表示写入成功,0表示写入失败
extern bit write_1byte_at24c02(unsigned char DDR, unsigned char a_datax, unsigned char datax);
//向器件存入数据,页写,ddr表示器件地址,page表示要EEPROM那页,数组datax【8】表示要写入8个数据
//函数返回1表示写入成功,0表示写入失败
extern bit write_page_at24c02(unsigned char DDR, unsigned char page, unsigned char datax[8]);
//向器件读取数据,字节读
//函数返回0表示通讯失败,不为0则读取正常。
extern unsigned char read_1byte_at24c02(unsigned char DDR, unsigned char a_datax);
//向器件读取数据,页读,数据将会存放在page_data_AT24C02[]数组里
extern unsigned char read_page_at24c02(unsigned char DDR, unsigned char page);
//擦除器件数据 ddr为器件地址,本开发板器件地址为0xa0 (0xa0写 0xa1读)
//函数返回1表示擦除成功,0表示擦除失败,并且iic通讯异常
extern bit ERASE_at24c02(unsigned char DDR);
#endif // !__AT24C02_H__
//P2^1;//时钟连接P2.1口
//P2^0;//时钟连接P2.0口
//AT24C02具有8字节页写缓存器,之前我写的代码有问题
//at24c02芯片地址为0101 0 A2 A1 A0最后3位看原理图,在本单片机里芯片地址位0101 000
//at24c02芯片内部地址为256字节,一页8个字节,共计32页,0x00表示第0页,0x08表示第2页,0x10表示第3页后面依次类推
//页写:发送8个字节的数据,每发送一个字节,芯片响应一个应答信号,同时,寻址字节低位自动加1,而高位不变。
//字节写:写地址,写数据,接收应答,然后在写地址,再写数据,在接收应答。。。。。。。
#include "iic.h"
unsigned char Mount_DDR_AT24C02[8] = {0};
unsigned char page_data_AT24C02[8]={0};
static unsigned char datax;//读取芯片的数据
//读AT24C02状态是否在忙是否存在此器件,最大读取时间10ms
bit read_status_AT24C02(unsigned char DDR)
{
unsigned char k = 0;
do
{
k++;
START_IIC();
write_1_byte_IIC(DDR);
if (!read_ACK_IIC())
{
STOP_IIC();
return 1;//器件存在且不忙
}
STOP_IIC();
delay_ms(1);//延迟1ms..............................................................
} while (k<11);//最大10ms等待IIC器件,别的大佬说是这个器件最大等待时长就是10毫秒之内响应
return 0;//器件不存在或通讯异常
}
//检测挂载多少个AT24C02
unsigned char Mount_Several_AT24C02(void)
{
unsigned char i=0;//流水号
unsigned char j=0;//挂载器件个数
unsigned char DDR = 0x50;//首器件地址
unsigned char DDRx;
for (i = 0; i < 8; i++)
{
DDRx = DDR << 1;
if (read_status_AT24C02(DDRx))
{
j++;
Mount_DDR_AT24C02[i] = DDR;
}
else
{
Mount_DDR_AT24C02[i] = 0;
}
DDR++;
}
return j;
}
//向某个器件存入数据,字节写,ddr表示器件地址,a_datax表示要将数据准备写入eeprom哪个地方,datax表示要写入到eeprom里的数据
//函数返回1表示写入成功,0表示写入失败
bit write_1byte_at24c02(unsigned char DDR,unsigned char a_datax,unsigned char datax)
{
DDR <<= 1;
if (read_status_AT24C02(DDR))//读取DDR器件是否在忙或不存在此器件
{
START_IIC();
write_1_byte_IIC(DDR);//器件
if (!read_ACK_IIC())
{
write_1_byte_IIC(a_datax);//地址
if (!read_ACK_IIC())
{
write_1_byte_IIC(datax);//数据
if (!read_ACK_IIC())
{
STOP_IIC();
if (read_status_AT24C02(DDR))//延迟一段时间让at24c02开始写数据进入eeprom里面
return 1;//函数返回1,iic通讯正常
else
return 0;//函数返回0,iic通讯异常
}
}
}
}
else
return 0;//函数返回0,iic通讯异常
STOP_IIC();
return 0;//函数返回0,iic通讯异常
}
//向器件存入数据,页写,ddr表示器件地址,a_datax表示要EEPROM地址,数组datax【8】表示要写入8个数据
//函数返回1表示写入成功,0表示写入失败
bit write_page_at24c02(unsigned char DDR,unsigned char page, unsigned char datax[8])
{
unsigned char i=0;//流水号
DDR <<= 1;
page <<= 3;//类似于page=page*8;
if (read_status_AT24C02(DDR))//读取DDR器件是否在忙或不存在此器件
{
START_IIC();//iic通讯开始信号
write_1_byte_IIC(DDR);//0xa0表示at24c02器件地址,0表示要向它接下来写入数据
if (!read_ACK_IIC())//检测从器件ACK信号
{
write_1_byte_IIC(page);//第page页的0地址准备写入数据
if (!read_ACK_IIC())//检测从器件ACK信号
{
for (i = 0;i < 8;i++)//共计写8个字节数据,每次写入一页
{
write_1_byte_IIC(datax[i]);//开始向eeprom写入数据
if (!read_ACK_IIC());//读取ACK
else
goto look;
if (i == 7)
{
STOP_IIC();//第page页写入完成
if (read_status_AT24C02(DDR))//延迟一段时间让at24c02开始写数据进入eeprom里面
return 1;//函数返回1,本次通讯结束
else
return 0;//函数返回0,iic通讯异常
}
}
}
}
}
else
return 0;//函数返回0,iic通讯异常
look:
STOP_IIC();
return 0;//函数返回0,iic通讯异常
}
//选择地址从器件读取数据,字节读
//函数返回0表示通讯失败,不为0则读取正常。
unsigned char read_1byte_at24c02(unsigned char DDR, unsigned char a_datax)
{//先开始信号,空写器件,接收应答,发送空写eeprom地址,接收应答,发送开始信号,发送读器件,接收应答,接收发来的数据
DDR << 1;
DDR += 1;
if (read_status_AT24C02(DDR))//读取DDR器件是否在忙或不存在此器件
{
START_IIC();//开始信号
write_1_byte_IIC(DDR & 0xfe);//操作地址 空写
if (!read_ACK_IIC())
{
write_1_byte_IIC(a_datax);//eeprom地址那页的第几个
if (!read_ACK_IIC())
{
START_IIC();
write_1_byte_IIC(DDR);//器件地址及准备读取数据
if (!read_ACK_IIC())
{
datax = read_1_byte_IIC();
write_ACK_IIC(1);//发送No ack
STOP_IIC();//结束本次通讯
return datax;//返回结果给函数
}
}
}
}
else
return 0;//函数返回0,iic通讯异常
STOP_IIC();
return 0;//函数返回0,iic通讯异常
}
//向器件读取数据,页读,数据将会存放在page_data_AT24C02[]数组里
unsigned char read_page_at24c02(unsigned char DDR, unsigned char page)
{
unsigned char i=0;//流水号
DDR <<= 1;
DDR += 1;
page<<=3;
if (read_status_AT24C02(DDR))//读取DDR器件是否在忙或不存在此器件
{
START_IIC();
write_1_byte_IIC(DDR);
if (!read_ACK_IIC())
{
write_1_byte_IIC(page);
if (!read_ACK_IIC())
{
for(i = 0;i < 8;i++)
{
page_data_AT24C02[i] = read_1_byte_IIC();
if(i==7)
{
write_ACK_IIC(0);//发送NO应答
STOP_IIC();
return 1;//函数返回1,iic通讯正常
}
write_ACK_IIC(1);//发送应答信号,继续接收数据
}
}
else
{
STOP_IIC();
return 0;//函数返回0,iic通讯异常
}
}
else
{
STOP_IIC();
return 0;//函数返回0,iic通讯异常
}
}
return 0;//函数返回0,iic通讯异常
}
//擦除器件数据 ddr为器件地址,本开发板器件地址为0xa0 (0xa0写 0xa1读)
//函数返回1表示擦除成功,0表示擦除失败,并且iic通讯异常
bit ERASE_at24c02(unsigned char DDR)
{
unsigned char i=0;//流水号
unsigned char j=0;//流水号
DDR << 1;
if (read_status_AT24C02(DDR))//读取DDR器件是否在忙或不存在此器件
{
START_IIC();//iic通讯开始信号
write_1_byte_IIC(DDR);//0xa0表示at24c02器件地址,0表示要向它接下来写入数据
if (!read_ACK_IIC())//检测从器件ACK信号
{
for (i = 0;i < 32;i++)//循环32页
{
write_1_byte_IIC(i*8);//向i页,第0地址准备写入数据
if (!read_ACK_IIC())//检测从器件ACK信号
{
for (j = 0;j < 8;j++)//共计写8个字节数据,每次擦除一页
{
write_1_byte_IIC(0xff);//开始写1即擦除eeprom
if (!read_ACK_IIC());//读取ACK
else
goto look;
if (j == 7)
{
STOP_IIC();//第i页写入完成
if (read_status_AT24C02(DDR))//延迟一段时间让at24c02开始写数据进入eeprom里面
{
if (i == 31)//判断没有ack应答32页是否传送完了,若传送完了就结束通讯
return 1; //函数返回1表示本次擦除eeprom成功
}
else
goto look;
}
}
}
else
goto look;
}
}
}
else
return 0;//函数返回0,iic通讯异常
look:
STOP_IIC();
return 0;//函数返回0,iic通讯异常
}