#include <REG2051.H>
#include <intrins.h>
#include "24Cxx.h"
#define _ACK_ 1
#define _NACK_ 0
unsigned char Mask = 0xFF;
////////////////////////////////////////////////////////////////////////////////////////////////
//延时约x毫秒
void DelayMs(unsigned int x)
{
unsigned char j;
unsigned int i;
for(i=x;i>0;i--)
for(j=250;j>0;j--) { _DELAY_ }
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
void Start()
{
SDA = SDA_H;
T_SU_DAT
SCL = SCL_H;
T_SU_STA
SDA = SDA_L;
T_HD_STA
SCL = SCL_L;
// T_LOW
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
void Stop()
{
SCL = SCL_L;
SDA = SDA_L;
T_SU_DAT
SCL = SCL_H;
T_BUF
SDA = SDA_H;
T_BUF
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
bit CAck()
{
bit Resp;
SCL = SCL_L;
SDA = SDA_H;
T_LOW //T_LOW > T_SU_DAT
SCL = SCL_H;
T_HIGH
Resp = (bit)(SDA & (~SDA_L));
SCL = SCL_L;
// T_LOW
return ~Resp; //Return _ACK_(1) When ACK(SDA==0)
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
void Ack()
{
SCL = SCL_L;
SDA = SDA_L;
T_LOW //T_LOW > T_SU_DAT
SCL = SCL_H;
T_HIGH
SCL = SCL_L;
// T_LOW
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
void NAck()
{
SCL = SCL_L;
SDA = SDA_H;
T_LOW //T_LOW > T_SU_DAT
SCL = SCL_H;
T_HIGH
SCL = SCL_L;
// T_LOW
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
void SendByte(unsigned char Byte)
{
unsigned char i;
SCL = SCL_L;
for(i=0; i<8; i++)
{
SDA = ((Byte & 0x80) ? (SDA_H) : (SDA_L));
T_LOW //T_LOW > T_SU_DAT
SCL = SCL_H;
T_HIGH
Byte <<= 1;
SCL = SCL_L;
}
// T_LOW
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
unsigned char ReceiveByte()
{
unsigned char Byte = 0, i;
SCL = SCL_L;
SDA = SDA_H;
for(i=0; i<8; i++)
{
T_LOW //T_LOW > T_SU_DAT
SCL = SCL_H;
T_HIGH
Byte <<= 1;
Byte |= (bit)(SDA & (~SDA_L));
SCL = SCL_L;
}
// T_LOW
return Byte;
}
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
//
bit WR24Cxx( unsigned char* Buff, //缓冲区首地址
unsigned int NByte, //要写入的字节数
unsigned char DevAddr, //器件地址,对应器件地址引脚
unsigned int WordAddr, //片内首地址,字节地址
bit WR, //读写标志,实参为宏_WRITE_或_READ_
unsigned char Bus, //选用的总线通道,实参为宏_CHx_,可并联
unsigned char Device ) //器件类型,实参为宏_24Cxx_
{
code unsigned char PageSize[10] = {8, 8, 16, 16, 16, 32, 32, 64, 64, 128};//各类型器件的页大小
unsigned char i;
Mask = ~Bus;
if(_WRITE_ == WR) //Write Operation
{
while(NByte > 0)
{ //Generate Control Word,For 24C01~16,Mingle Device Address with Page Addess
switch(Device)
{
case _24C04_ :
DevAddr &= 0xFC;
DevAddr |= (unsigned char)(0x02 & (WordAddr >> 7));
break;
case _24C08_ :
DevAddr &= 0xF8;
DevAddr |= (unsigned char)(0x06 & (WordAddr >> 7));
break;
case _24C16_:
DevAddr &= 0xF0;
DevAddr |= (unsigned char)(0x0E & (WordAddr >> 7));
break;
}
//Dummy Write
DevAddr &= 0xFE; //Write
Start();
SendByte(DevAddr); //Control Byte
if(_NACK_ == CAck()) { return FAIL; }
if(Device > _24C16_)
{
SendByte((unsigned char)(WordAddr >> 8)); //High Address Byte
if(_NACK_ == CAck()) { return FAIL; }
}
SendByte((unsigned char)(0x00FF & WordAddr)); //Low Address Byte
if(_NACK_ == CAck()) { return FAIL; }
//Write N Bytes
if(0 == (WordAddr%(PageSize[Device]))) //Snap to page boundary
{
if(NByte > PageSize[Device])
{ //Write One Page
for(i=PageSize[Device]; i>0; i--)
{
SendByte(*(Buff++));
if(_NACK_ == CAck()) { return FAIL; }
}
NByte -= PageSize[Device];
WordAddr += PageSize[Device];
}
else
{ //Write the Rest
for(; NByte>0; NByte--)
{
SendByte(*(Buff++));
if(_NACK_ == CAck()) { return FAIL; }
}
}
}
else //Do not snap to page boundary
{
i=((PageSize[Device])-(WordAddr%(PageSize[Device])));
if(i > NByte) { i = NByte; }
for(; i>0; i--)
{
SendByte(*(Buff++));
if(_NACK_ == CAck()) { return FAIL; }
NByte--;
WordAddr++;
}
}
Stop();
DelayMs(T_WR); //Wait for Internal Write Cycle
}
return SUCCESS; //Finish Writing
}
else //Read Operation
{ //Generate Control Word,For 24C01~16,Mingle Device Address with Page Addess
switch(Device)
{
case _24C04_ :
DevAddr &= 0xFC;
DevAddr |= (unsigned char)(0x02 & (WordAddr >> 7));
break;
case _24C08_ :
DevAddr &= 0xF8;
DevAddr |= (unsigned char)(0x06 & (WordAddr >> 7));
break;
case _24C16_:
DevAddr &= 0xF0;
DevAddr |= (unsigned char)(0x0E & (WordAddr >> 7));
break;
}
//Dummy Write
DevAddr &= 0xFE; //Write
Start();
SendByte(DevAddr); //Control Byte
if(_NACK_ == CAck()) { return FAIL; }
if(Device > _24C16_)
{
SendByte((unsigned char)(WordAddr >> 8)); //High Address Byte
if(_NACK_ == CAck()) { return FAIL; }
}
SendByte((unsigned char)(0x00FF & WordAddr)); //Low Address Byte
if(_NACK_ == CAck()) { return FAIL; }
//Read N Bytes
DevAddr |= 0x01;
Start();
SendByte(DevAddr); //Control Byte
if(_NACK_ == CAck()) { return FAIL; }
while(NByte > 0) //Receive N Bytes
{
*(Buff++) = ReceiveByte();
NByte--;
if(NByte > 0) { Ack(); }
}
NAck();
Stop();
return SUCCESS; //Finish Reading
}
}