//---------------------------------------------------------------------------//
//-------24cxx.c-------------------------------------------------------------//
//----I2C的读写时序的软件模拟---------------------------------------------------//
//----by gg------------------------------------------------------------------//
//----at 2006.02.27----------------------------------------------------------//
//---------------------------------------------------------------------------//
//#include <reg51.h>
#include <sanxian.h>
#define HIGH 1
#define LOW 0
#define FALSE 0
#define TRUE ~FALSE
#define WRITE 0xA0 //24Cxx的地址和方向位W
#define READ 0xA1 //24Cxx的地址和方向位R
//#define BLOCK_SIZE 12 //定义指定字节个数
//idata uchar EAROMImage[BLOCK_SIZE];
sbit SCL = P1^1;
sbit SDA = P2^7;
extern uchar idata comarr[10];
//---------------------------------------------------------------------------//
//------void I_start(void);--------------------------------------------------//
//-------I2C总线的起始位-------------------------------------------------------//
//---------------------------------------------------------------------------//
void I_start()
{
SCL = HIGH;
delay(0);
SDA = LOW;
delay(0);
SCL = LOW;
delay(0);
}
//----------------------------------------------------------------------------//
//-------void I_stop();--------------------------------------------------------//
//-----I2C总线的停止位---------------------------------------------------------//
//----------------------------------------------------------------------------//
void I_stop()
{
SDA = LOW;
delay(0);
SCL = HIGH;
delay(0);
SDA = HIGH;
delay(0);
SCL = LOW;
delay(0);
}
//-------------------------------------------------------------------------//
//-----void I_init();------------------------------------------------------//
//-----I2C总线的初始化,应首先调用该函数---------------------------------------//
//-------------------------------------------------------------------------//
void I_init()
{
SCL = LOW;
I_stop();
}
//-------------------------------------------------------------------------------//
//-----bit I_clock();------------------------------------------------------------//
//-----I2C的总线时钟信号,返回时钟为高期间SDA信号线上的状态。可用于数据的发送和接收。------//
//-------------------------------------------------------------------------------//
bit I_clock()
{
bit sample;
SCL = HIGH;
delay(0);
sample = SDA;
SCL = LOW;
delay(0);
return (sample) ;
}
//---------------------------------------------------------------------------------//
//-------bit I_send(uchar I_data);-------------------------------------------------//
//-------向I2C发送8位数据,并请求一个应答信号ACK。如果收到ACK返回1(TRUE),否则0(FALSE)--//
//----------------------------------------------------------------------------------//
bit I_send(uchar I_data)
{
register uchar i;
for (i=0;i<8;i++)
{
SDA = (bit)(I_data & 0x80);
I_data = I_data << 1;
I_clock();
} //end for
//请求应答信号
SDA = HIGH;
return ( ~I_clock() );
}
//--------------------------------------------------------------------------------------------//
//--------uchar I_receive()-------------------------------------------------------------------//
//--------从I2C上接受8位数据信号,并作为一个字节返回,不回送ACK。在调用本函数之前要保证SDA浮置,即8051该口线置1--//
//--------------------------------------------------------------------------------------------//
uchar I_receive()
{
uchar I_data = 0 ;
register uchar i;
for(i=0;i<8;i++)
{
I_data *= 2;
if(I_clock())
I_data++; //end if
} //endfor
return (I_data) ;
}
//---------------------------------------------------------------------------------------------------//
//-------void I_ack()--------------------------------------------------------------------------------//
//-------向I2C总线发送一个应答信号ACK,一秀般用于连续数据读取时---------------------------------------------//
//---------------------------------------------------------------------------------------------------//
void I_ack()
{
SDA = LOW;
I_clock();
SDA = HIGH;
}
//up for I2C
//below is 24c02
//---------------------------------------------------------------------------------------------------------//
//----bit E_address(uchar add)-----------------------------------------------------------------------------//
//---向24CXX写入器件地址和一个指定的字节地址--------------------------------------------------------------------//
//----------------------------------------------------------------------------------------------------------//
bit E_address(uchar add)
{
I_start();
if(I_send( WRITE ))
return (I_send(add));
else
return ( FALSE );
//endif
}
//------------------------------------------------------------------------------------------------------------//
//---------bit E_read_block(uchar startadd,uchar n,uchar *p);---------------------------------------------------------------//
//----从24CXX读数据,从startadd开始,读n个字节,放入地址p中-------------------------------------------//
//------------------------------------------------------------------------------------------------------------//
bit E_read_block(uint idata startadd , uchar idata n, uchar *p)
{
register uint i;
//from address 0
if(E_address(startadd))
{
I_start(); //start again
if(I_send(READ))
{
for(i=0;i<=n;i++)
{
p[i] = (I_receive());
if(i!=n)
I_ack();
else
{
I_clock();
I_stop();
} //endif
}//endfor
return (TRUE);
}
else
{
I_stop();
return (FALSE);
} //endif
}
else
{
I_stop();
return (FALSE);
}
//endif
}