/* 程序在单片机89s51上正确运行,开发环境是keil uvision3*/
/*********************************************/
#include <REG51.H>
#include <intrins.H>
#define uint unsigned int
#define uchar unsigned char
#define LENGTH 32
/********************24c64定义*********************/
sbit sda_24c64 = P3^7; //24c64定义数据线
sbit scl_24c64 = P3^6; //24c64定义时钟线
/*********************************************/
unsigned char m_data_from_24c64[LENGTH] ;//接受数组
void init(void)
{
TMOD=0x20; //自动恢复初值的8位计数器,TL=计数值,TH=初值
PCON=0x00;
TH1=0xfd;
TL1=0xfd;
SCON=0x50;//允许串口接收,8位数据
TR1=1; //开计数器
TI=0;//////发送中断标志清零
ES=1; //允许串口中断
}
//**************************************/
void Delay_xus(uint i)//(
{
while(i--);
}
void Delay_100ms()//
{
// uchar i;
uint j = 140;
for(;j>0;j--);
//{
// i = 7;
// while(i--);
//}
}
/***************************************/
void start_24c64()
{
sda_24c64 = 1;
scl_24c64 = 1;
//Delay_xus(1); //===========
sda_24c64 = 0;
//Delay_xus(1);
scl_24c64 = 0;//控制时钟线,防止数据误入
// I2C总线空闲时,sda、scl为高电平
}
void stop_24c64()
{
sda_24c64 = 0;
scl_24c64 = 1;
//Delay_xus(1);//===========================
sda_24c64 = 1;
scl_24c64 = 0;
}
/*void ack_24c64() //写数据应答,第九个脉冲sda_24c64为低,则24c64成功接受数据
{
sda_24c64 = 1;
//scl_24c64 = 0;
scl_24c64 = 1;
Delay_xus(1);
sda_24c64 = 0;
Delay_xus(1);
while(sda_24c64);//结合写数据发第九个脉冲,检查应答位,若无应答,一定时间后退出
scl_24c64 = 0;
Delay_xus(1);
scl_24c64 = 1;
} */
void ack() //
{
sda_24c64 = 0;
scl_24c64 = 1;
Delay_xus(1);
scl_24c64 = 0;
sda_24c64 = 1;
}
void nack() //
{
sda_24c64 = 1;
scl_24c64 = 1;
Delay_xus(1);
scl_24c64 = 0;
Delay_xus(1);
sda_24c64 = 0;////
}
void writebyte_24c64(uchar data_to_24c64)//写入数据
{
uchar i;
scl_24c64 = 0; ////******************************************
for(i=0;i<8;i++)
{
if(data_to_24c64&0x80)
{
sda_24c64 = 1;
}
else
{
sda_24c64 = 0;
}
scl_24c64 = 1; //时钟线低变高,发数据
//Delay_xus(1);//===================
scl_24c64 = 0;
data_to_24c64<<=1;
}
ack();
}
uchar readbyte_24c64()
{
uchar i,data_from_24c64;
scl_24c64 = 0;
for(i=0;i<8;i++)
{
data_from_24c64<<=1;
scl_24c64 = 1;
Delay_xus(1);
data_from_24c64 |= sda_24c64;
scl_24c64 = 0;
Delay_xus(1);
}
return data_from_24c64;
}
void write_o_data_24c64(uint add,uchar data_24c64)//写入单个数据
{
start_24c64();
writebyte_24c64(0xa0);//写指令
writebyte_24c64(add/256);//写高位地址
writebyte_24c64(add%256);//写低位地址
writebyte_24c64(data_24c64);//写储存数据
stop_24c64();
Delay_xus(1);
}
void write_m_data_24c64(uint add,uchar *m_data_24c64,uchar n) //从某地址开始连续多字节写入
{
uchar i;
start_24c64();
writebyte_24c64(0xa0);//写指令
writebyte_24c64(add/256);//写高位地址
writebyte_24c64(add%256);//写低位地址
for(i=0;i<n;i++)
{
writebyte_24c64(*m_data_24c64);//写储存数据
m_data_24c64++;
}
stop_24c64();
}
uchar read_o_data_24c64(uint add) //读出单个数据
{
uchar temp;
start_24c64();
writebyte_24c64(0xa0);//写写指令
writebyte_24c64(add/256);//写高位地址
writebyte_24c64(add%256);//写低位地址(实际上是调24c64地址指针到要读取的数据的地址)
stop_24c64();
start_24c64();
writebyte_24c64(0xa1);//写读指令
temp = readbyte_24c64();
nack();
stop_24c64();
return temp;
}
void read_m_data_24c64(uint add,uchar* m_data,uchar n)//从某地址开始连续读取n个数据
{
uchar i;
start_24c64();
writebyte_24c64(0xa0);//写写指令
writebyte_24c64(add/256);//写高位地址
writebyte_24c64(add%256);//写低位地址(实际上是调24c64地址指针到要读取的数据的地址)
//stop_24c64();
start_24c64();
writebyte_24c64(0xa1);//写读指令
for(i=0;i<n-1;i++) //读n个字节数据
{
*m_data= readbyte_24c64();
m_data++;
ack();
}
*m_data= readbyte_24c64();
nack();
stop_24c64();
}
/******************************/
/*
程序说明:利用串口显示写入EEPROM中的数据,波特率是9600,8位数据位
*/
void main(void)
{
unsigned char t;
uint k;
uint Ad=0;
init();
Delay_100ms();
Delay_100ms();
Delay_100ms();
Delay_100ms();
for(k=0;k<256;k++)//向eeprom写入验证数据
{
for(t=0;t<LENGTH;t++)
m_data_from_24c64[t]=t%8;
write_m_data_24c64(Ad,m_data_from_24c64,LENGTH);
Delay_100ms();
Ad+=LENGTH;
}
/*for(k=0;k<5940;k++)
{
write_o_data_24c64(Ad,k%8);
Delay_100ms();
Ad++;
P1 =0xf7;
}*/
Ad=0;
//for(k=0;k<186;k++)
for(k=0;k<2;k++) //从EEPROM读出验证数据,并传给串口,在串口助手中显示出来
{
read_m_data_24c64(Ad,m_data_from_24c64,LENGTH);
for(t=0;t<LENGTH;t++)
{
//SBUF=read_o_data_24c64(Ad);
SBUF=m_data_from_24c64[t];
Ad++;
while(!TI);
TI=0;
}
P1 =0x7f;
}
while(1);
}