|
一個(gè)通用的24C01-24C256共9種EEPROM的字節(jié)讀寫操作程序, 此程序有五個(gè)入口條件,分別為讀寫數(shù)據(jù)緩沖區(qū)指針, 進(jìn)行讀寫的字節(jié)數(shù),EEPROM首址,EEPROM控制字節(jié), 以及EEPROM類型。此程序結(jié)構(gòu)性良好,具有極好的容錯(cuò)性,程序機(jī)器碼也不多: #pragma ot(6,SIZE) #include #include #define ERRORCOUNT 10 sbit SDA="P0"^0; sbit SCL="P0"^1; enum eepromtype {M2401,M2402,M2404,M2408,M2416,M2432,M2464,M24128,M24256}; enum eepromtype EepromType; //DataBuff為讀寫數(shù)據(jù)輸入/輸出緩沖區(qū)的首址 //ByteQuantity 為要讀寫數(shù)據(jù)的字節(jié)數(shù)量 //Address 為EEPROM的片內(nèi)地址 //ControlByte 為EEPROM的控制字節(jié),具體形式為(1)(0)(1)(0)(A2)(A1)(A0)(R/W),其中R/W="1", //表示讀操作,R/W="0"為寫操作,A2,A1,A0為EEPROM的頁選或片選地址; //EepromType為枚舉變量,需為M2401至M24256中的一種,分別對(duì)應(yīng)24C01至24C256; //函數(shù)返回值為一個(gè)位變量,若返回1表示此次操作失效,0表示操作成功; //ERRORCOUNT為允許最大次數(shù),若出現(xiàn)ERRORCOUNT次操作失效后,則函數(shù)中止操作,并返回1 //SDA和SCL由用戶自定義,這里暫定義為P0^0和P0^1; //其余的用戶不用管,只要把只子程序放在你的程序中并調(diào)用它就可以了; /***********************************************************************************/ bit RW24XX(unsigned char *DataBuff,unsigned char ByteQuantity,unsigned int Address, unsigned char ControlByte,enum eepromtype EepromType) { void Delay(unsigned char DelayCount); void IICStart(void); void IICStop(void); bit IICRecAck(void); void IICNoAck(void); void IICAck(void); unsigned char IICReceiveByte(void); void IICSendByte(unsigned char sendbyte); unsigned char data j,i="ERRORCOUNT"; bit errorflag="1"; while(i--) { IICStart(); IICSendByte(ControlByte&0xfe); if(IICRecAck()) continue; if(EepromType>M2416) { IICSendByte((unsigned char)(Address>>8)); if(IICRecAck()) continue; } IICSendByte((unsigned char)Address); if(IICRecAck()) continue; if(!(ControlByte&0x01)) { j="ByteQuantity"; errorflag="0"; //********clr errorflag while(j--) { IICSendByte(*DataBuff++); if(!IICRecAck()) continue; errorflag="1"; break; } if(errorflag==1) continue; break; } else { IICStart(); IICSendByte(ControlByte); if(IICRecAck()) continue; while(--ByteQuantity) { *DataBuff++=IICReceiveByte(); IICAck(); } *DataBuff="IICReceiveByte"(); //read last byte data IICNoAck(); errorflag="0"; break; } } IICStop(); if(!(ControlByte&0x01)) { Delay(255); Delay(255); Delay(255); Delay(255); } return(errorflag); } /*****************以下是對(duì)IIC總線的操作子程序***/ /*****************啟動(dòng)總線**********************/ void IICStart(void) { SCL="0"; // SDA="1"; SCL="1"; _nop_(); _nop_(); _nop_(); SDA="0"; _nop_(); _nop_(); _nop_(); _nop_(); SCL="0"; SDA="1"; // } /*****************停止IIC總線****************/ void IICStop(void) { SCL="0"; SDA="0"; SCL="1"; _nop_(); _nop_(); _nop_(); SDA="1"; _nop_(); _nop_(); _nop_(); SCL="0"; } /**************檢查應(yīng)答位*******************/ bit IICRecAck(void) { SCL="0"; SDA="1"; SCL="1"; _nop_(); _nop_(); _nop_(); _nop_(); CY="SDA"; //因?yàn)榉祷刂悼偸欠旁贑Y中的 SCL="0"; return(CY); } /***************對(duì)IIC總線產(chǎn)生應(yīng)答*******************/ void IICACK(void) { SDA="0"; SCL="1"; _nop_(); _nop_(); _nop_(); _nop_(); SCL="0"; _nop_(); SDA="1"; } /*****************不對(duì)IIC總線產(chǎn)生應(yīng)答***************/ void IICNoAck(void) { SDA="1"; SCL="1"; _nop_(); _nop_(); _nop_(); _nop_(); SCL="0"; } /*******************向IIC總線寫數(shù)據(jù)*********************/ void IICSendByte(unsigned char sendbyte) { unsigned char data j="8"; for(;j>0;j--) { SCL="0"; sendbyte<<=1; //無論C51怎樣實(shí)現(xiàn)這個(gè)操作,始終會(huì)使CY="sendbyte"^7; SDA="CY"; SCL="1"; } SCL="0"; } /**********************從IIC總線上讀數(shù)據(jù)子程序**********/ unsigned char IICReceiveByte(void) { register receivebyte,i="8"; SCL="0"; while(i--) { SCL="1"; receivebyte=(receivebyte<<1)|SDA; SCL="0"; } return(receivebyte); } /***************一個(gè)簡(jiǎn)單延時(shí)程序************************/ void Delay(unsigned char DelayCount) { while(DelayCount--); } |