参考资料对AT24C256介绍的很清楚
#include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit sda=P1^7;
sbit scl=P1^6;
uint Txmt_Success; //发送成功
uint ACK_Error; //应答错误
void delay15ms(void) //晶振12
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=238;b>0;b--)
for(a=30;a>0;a--);
}
void delay(uint z)//延时1ms,晶振12M
{
uint x,y;
for(x=z;x>0;x--)
for(y=199;y>0;y--);
}
void start(void) //TxmtStartBit
{
sda=1; //Set a falling edge in sda when scl is high
scl=1;
_nop_();
sda=0;
_nop_();
scl=0; //scl need to hold on low
}
void stop(void) //TxmtStopBit
{
scl=0;
sda=0; //Set a rising edge is sda when scl is high
scl=1;
_nop_();
sda=1;
_nop_();
}
void SendData(uchar Data_s)
{
uchar I2CBitCount;
Txmt_Success=0; //no Success
//发送8个bit,高位在前
for(I2CBitCount=0;I2CBitCount<8;I2CBitCount++)
{
if(Data_s&0x80) //if high then send high
sda=1;
else
sda=0; //if low then send low
scl=1; //A falling edge to write the bit
_nop_();
scl=0;
_nop_();
Data_s=Data_s<<1;
}
//收应答
sda=1; //A falling edge to receive the ACK
_nop_();
scl=1;
_nop_();
_nop_();
_nop_();
if(sda) //if sda=1 then ACK wrong
{
sda=1;
scl=1;
ACK_Error=1; //no success
}
else //if sda=0 the ACK right
{
scl=0;
Txmt_Success=1; //success
ACK_Error=0;
}
}
void TxmtSlaveAddr(uchar SlaveAddr)
{
ACK_Error=0;
Txmt_Success=0;
SendData(SlaveAddr);
if(!Txmt_Success&&ACK_Error) //if no success and ACK wrong
stop(); //如果失败则发送STOP结束整个流程
}
void Writeone_24c256(uchar Addr_H,uchar Addr_L,uchar W_Data)//写一个数据
{
start(); //START
TxmtSlaveAddr(0xa0); //发送器件地址(写)
SendData(Addr_H);
SendData(Addr_L); //发生需读取的地址
SendData(W_Data); //写入数据
stop(); //STOP
}
uchar GetData(uchar ack_read)
{
uchar I2CBitCount;
uchar Data_G;
for(I2CBitCount=0;I2CBitCount<8;I2CBitCount++)
{
scl=0;
_nop_();
_nop_();
_nop_();
_nop_();
scl=1; //A rising edge in scl to read sda
Data_G=Data_G<<1; //shift letf first
_nop_();
if(sda)
Data_G=Data_G|0x01;
else
Data_G=Data_G&0xFE;
scl=0;
}
scl=0;
if(!ack_read)
sda=0; /*在此发出应答或非应答信号 */
else sda=1;
_nop_();
_nop_();
_nop_();
scl=1;
_nop_();
_nop_(); /*时钟低电平周期大于4μs*/
_nop_();
_nop_();
_nop_();
scl=0; /*清时钟线,钳住I2C总线以便继续接收*/
_nop_();
sda=1;
_nop_();
return Data_G; //return the result
delay(500);
}
uchar Readone_24c256(uchar Addr_H,uchar Addr_L)
{
uchar ReadData;
start(); //START
TxmtSlaveAddr(0xa0); //发送器件地址(写)
SendData(Addr_H); //发生需读取的地址
SendData(Addr_L);
start(); //START
TxmtSlaveAddr(0xa1); //发送器件地址(读)
ReadData=GetData(1); //读取1个字节数据
stop(); //STOP
return ReadData;
}
void init()
{
sda=1;
delay15ms();
scl=1;
delay15ms();
}
void main()
{
init();
Writeone_24c256(0x00,0x09,a5);
delay(200);
Readone_24c256(0x00,0x09);
while(1);
}