//适用于AT24C128/256器件的读写程序(该2种器件页容量均为64)个字节 // 2006/12/19 /////////////////////////////////////////////////////////////////////////////// #pragma optimize(5) #include "e:kc802C51INCSTCSTC89C51RC_RD_PLUS.h" #include "intrins.h"
#define UCHAR unsigned char #define UINT unsigned int #define nop() _nop_()
sbit SDA = P1^1; sbit SCL = P1^0; /////////////////////////////////////////////////////////////////////////////// void I2C_Start(void){ SCL=1;nop();nop();
SDA=1;nop();nop(); SDA=0;nop();nop();
SCL=0;nop();nop(); } void I2C_Stop(void){ SDA=0;nop();nop(); SCL=1;nop();nop(); SDA=1;nop();nop();
SCL=0;nop();nop(); } void I2C_Ack(bit sig){ SDA=sig;
SCL=0;nop();nop(); SCL=1;nop();nop(); SCL=0;nop();nop(); } UCHAR I2C_ReadByte(void){ UCHAR i,rByte=0;
SDA=1; for(i=0;i<8;i++){ SCL=0;nop();nop(); SCL=1;
rByte<<=1; if(SDA==1){rByte+=1;} } SCL=0;
return rByte; } bit I2C_WriteByte(UCHAR preByte){ bit ack; UCHAR i;
for(i=0;i<8;i++){ SDA=0; if((preByte<<i)&0x80){SDA=1;}
SCL=1;nop();nop(); SCL=0; } SDA=1;nop();nop();//释放数据线,准备接收应答信号 ack=SDA; SCL=1;nop();nop(); SCL=0;
return ack; } /////////////////////////////////////////////////////////////////////////////// //每次对器件进行读写操作之前都要用此函数查询其忙状态,对MicroChip的24C16测试结果 //如下: // 在22.1184M/12T时钟晶体的情况下,i典型值为16 // 在11.0592M/12T时钟晶体的情况下,i典型值为8 //sla-从器件地址,从A0H开始 /////////////////////////////////////////////////////////////////////////////// void I2C_AcknowledgePolling(UCHAR sla){ UCHAR i; I2C_Start(); for(i=0;i<30;i++){ if(I2C_WriteByte(sla)==1){I2C_Start();} else{break;} } } bit I2C_SequentialRead_AT24C128_256(UCHAR sla,UINT suba,UCHAR *pHead,UCHAR len){ UCHAR i;
I2C_Start(); if(I2C_WriteByte(sla)==1){return 0;} if(I2C_WriteByte((UCHAR)(suba>>8))==1){return 0;} if(I2C_WriteByte((UCHAR)suba)==1){return 0;} I2C_Start(); if(I2C_WriteByte(sla+1)==1){return 0;}
if(len>1){ for(i=0;i<(len-1);i++){ *pHead=I2C_ReadByte(); I2C_Ack(0); pHead++; } } *pHead=I2C_ReadByte();
I2C_Ack(1); I2C_Stop();
return 1; } bit I2C_PageWrite_AT24C128_256(UCHAR sla,UINT suba,UCHAR* pHead,UCHAR len){ UCHAR wLen; UINT addr; wLen=len; addr=suba; ScrollPage:I2C_AcknowledgePolling(); I2C_Start(); if(I2C_WriteByte(sla)==1){return 0;} if(I2C_WriteByte((UCHAR)(addr>>8))==1){return 0;} if(I2C_WriteByte((UCHAR)addr)==1){return 0;} if(I2C_WriteByte(*pHeader)==1){return 0;} addr++; wLen--; while(wLen>0){ if((addr%64)!=0){ if(I2C_WriteByte(*pHeader)==1){return 0;} addr++; wLen--; } else{ I2C_Stop(); goto ScrollPage; } } I2C_Stop(); return 1; } |