#include
#define EEP_PORT PORTC //界说是运用PROTC口
#define EEP_DDR DDRC //界说是运用PROTC口
#define SDA 0X10 //界说sda衔接的是portd1
#define SCL 0X20 //界说scl衔接的是portd0
//#define WP 0X04 //界说wp衔接的是portd2
#define EEP_ADD_R 0xa1 //写I2C从器材地址和读方法 a0,a1接地
#define EEP_ADD_W 0xa0 //写I2C从器材地址和写方法 a0,a1接地
void delay(unsigned int us)
{
while(us–);
}
void eep_init(void)
{
EEP_DDR|= SDA | SCL ;//| WP ;
EEP_PORT|=SDA | SCL ;//| WP ;
}
void send(void)
{
EEP_PORT|=SCL;
asm(“nop”);
EEP_PORT&=~SCL;
}
/********************************************
内部函数,I2C开端
********************************************/
void Start(void)
{
EEP_PORT|=SDA; //sda
EEP_PORT|=SCL; //scl
asm(“nop”);
EEP_PORT&=~SDA;
asm(“nop”);
EEP_PORT&=~SCL;
}
/********************************************
内部函数,I2C完毕
********************************************/
void Stop(void)
{
EEP_PORT&=~SDA;
EEP_PORT&=~SCL;
asm(“nop”);
EEP_PORT|=SCL;
asm(“nop”);
EEP_PORT|=SDA;
asm(“nop”);
}
/********************************************
内部函数,等候ACK
********************************************/
void ACK(void)
{
unsigned char errtime=20;
EEP_PORT|=SDA; //上拉
EEP_DDR&=~SDA; //设置为输进口
EEP_PORT|=SCL;
asm(“nop”);
while(PINC&SDA)
{ errtime–;
if(!errtime)
{
Stop();
EEP_PORT&=~SDA; //超时,给他个脱离的理由
}
}
EEP_PORT&=~SCL;
asm(“nop”);
EEP_DDR|=SDA; //设置为输出口
}
/********************************************
内部函数.输出数据字节
********************************************/
void writebyte(unsigned char wdata)
{
unsigned char i;
for(i=0;i<8;i++)
{
if((wdata&0x80)){EEP_PORT|=SDA;}else{EEP_PORT&=~SDA;}
wdata<<=1;
send(); //发送一个位
}
}
/********************************************
内部函数.输入数据
********************************************/
unsigned char Readbyte(void)
{
unsigned char i,bytedata;
EEP_DDR&=~SDA; //设置为输入?
for(i=0;i<8;i++)
{
EEP_PORT|=SCL;
bytedata<<=1;
if(PINC&SDA){
bytedata|=0X01;
}else{
bytedata&=~0X01;
}
EEP_PORT&=~SCL;
asm(“nop”);
}
EEP_DDR|=SDA;
return(bytedata);
}
/********************读24cxx–外部调用********************/
unsigned char read_eep(unsigned char add1,unsigned char add2)
{ unsigned char mdata;
Start(); //开始位
writebyte(EEP_ADD_W); //写eeprom地址+1个写指令
ACK(); //等候应对信号
writebyte(add1); //写如拜访地址
ACK(); //等候应对信号
writebyte(add2); //写入拜访地址
ACK(); //等候应对信号
Start(); //开始位
writebyte(EEP_ADD_R); //写eeprom地址+1个读指令
ACK(); //等候应对信号
mdata=Readbyte(); //获取数据
Stop(); //发送中止方位
asm(“nop”); //此处延时依据实际情况,假如不延时,可能会不正常
return(mdata);
}
/********************写24cxx–外部调用********************/
void write_eep(unsigned char add1,unsigned char add2,unsigned char udata)
{
//EEP_PORT&=~WP; //封闭写保护
Start(); //开始位
writebyte(EEP_ADD_W); //写eeprom地址+1个写指令
ACK(); //等候应对信号
writebyte(add1); //写如拜访地址
ACK(); //等候应对信号
writebyte(add2); //写如拜访地址
ACK(); //等候应对信号
writebyte(udata); //写入数据
ACK(); //等候应对信号
Stop(); //发送中止位
delay(24000);
//delay_nms(4); //此处延时依据实际情况,大多EEPROM都需求3毫秒的写入时刻,假如不延时,可能会不正常
//EEP_PORT|=WP; //翻开写保护
}
void main(void)
{
unsigned char tmp;
eep_init();
DDRC|=(1<<0);
PORTC&=~(1<<0);
write_eep(0,2,7);
tmp=read_eep(0,2);
if(tmp==7)
PORTC|=(1<<0);
while(1);
}