?? 24cxxx.c
字號:
/***********************************************************************************
此程序包括對24XX系列EEPROM的字節、頁讀寫操作
DataBuff為讀寫數據輸入/輸出緩沖區的首址
ByteQuantity 為要讀寫數據的字節數量
Address 為EEPROM的片內地址
ControlByte 為EEPROM的控制字節,具體形式為(1)(0)(1)(0)(A2)(A1)(A0)(R/W),其中R/W=1,
表示讀操作,R/W=0為寫操作,A2,A1,A0為EEPROM的頁選或片選地址;
EepromType為枚舉變量,需為M2401至M24256中的一種,分別對應24C01至24C256;
函數返回值為一個位變量,若返回1表示此次操作失效,0表示操作成功;
ERRORCOUNT為允許最大次數,若出現ERRORCOUNT次操作失效后,則函數中止操作,并返回1
SDA和SCL由用戶自定義,這里暫定義為P0^1和P0^0;
***********************************************************************************/
#pragma ot(5,SIZE)
#include <reg51.h>
#include <intrins.h>
#define ERRORCOUNT 10
sbit SDA=0xB3;
sbit SCL=0xB5;
enum eepromtype {M2401,M2402,M2404,M2408,M2416,M2432,M2464,M24128,M24256};
enum eepromtype EepromType; /* 器件類型枚舉變量取值為0-8 */
/***********************************************************************************/
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; /* clr errorflag */
while(i--) /* 啟動IIC總線并發送EEPROM從器件地址 */
{
IICStart(); /* 啟動IIC總線 */
IICSendByte(ControlByte&0xfe); /* 發送EEPROM地址 */
if(IICRecAck()) /* 接收EEPROM應答信號 */
continue; /* 接收EEPROM應答信號,為1重新啟動 */
if(EepromType>M2416) /* EEPROM為24C32以上器件內地址為2字節 */
{
IICSendByte((unsigned char)(Address>>8));/* 先發送高字節,參考硬件相關說明 */
if(IICRecAck())
continue;
}
IICSendByte((unsigned char)Address);/* 再發送低字節或單字節地址 */
if(IICRecAck())
continue;
if(!(ControlByte&0x01)) /* 以下為寫操作 */
{
j=ByteQuantity; /* ByteQuantity為寫入字節數 */
errorflag=0;
while(j--)
{
IICSendByte(*DataBuff++); /* DataBuff寫操作緩沖區 */
if(!IICRecAck())
continue;
errorflag=1;
break;
}
if(errorflag==1)
continue;
break;
}
else /* 以下為讀操作 */
{
IICStart(); /* 重新啟動IIC總線并發送EEPROM從器件地址 */
IICSendByte(ControlByte);
if(IICRecAck())
continue;
while(--ByteQuantity) /* 每次讀一字節,共ByteQuantity字節 */
{
*DataBuff++=IICReceiveByte(); /*讀1字節并存入DataBuff為指針的存儲單元 */
IICAck(); /* 發送應答信號 */
}
*DataBuff=IICReceiveByte(); /*read last byte data*/
IICNoAck(); /* 讀入最后一字節無須發送應答信號 */
errorflag=0;
break;
}
}
IICStop(); /* 停止IIC總線信號 */
if(!(ControlByte&0x01)) /* 寫入操作需延時,確保足夠長寫入時間 */
{
Delay(255);
Delay(255);
Delay(255);
Delay(255);
}
return(errorflag);
}
/*******************
以下是對IIC操作子程序
*******************/
/*******************
啟動IIC
*******************/
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;
}
/**************
檢查應答位
**************/
bit IICRecAck(void)
{
SCL=0;
SDA=1;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
CY=SDA; /* 應答位返回值在CY中,0有效 */
SCL=0;
return(CY);
}
/***************
對IIC總線產生應答
***************/
void IICAck(void)
{
SDA=0;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
SDA=1;
}
/*****************
不對IIC總線產生應答
*****************/
void IICNoAck(void)
{
SDA=1;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
/*******************
向IIC總線寫數據
*******************/
void IICSendByte(unsigned char sendbyte)
{
unsigned char data j=8;
for(;j>0;j--)
{
SCL=0;
sendbyte<<=1; /* 發送字節變量sendbyte左移1位,CY=sendbyte^7,并回存 */
SDA=CY;
SCL=1;
}
SCL=0;
}
/********************
從IIC總線讀數據子程序
********************/
unsigned char IICReceiveByte(void)
{
register receivebyte,i=8;
SCL=0;
while(i--)
{
SCL=1;
receivebyte=(receivebyte<<1)|SDA;
SCL=0;
}
return(receivebyte);
}
/***************
延時程序
***************/
void Delay(unsigned char DelayCount)
{
while(DelayCount--);
}
/****************
應用舉例
****************/
main()
{
unsigned char *pix=0x30;
unsigned char i;
for(i=0;i<10;i++)
*pix++=i+2; /* 設置待寫入數據 */
RW24XX(0x30,10,0x0010,0xa0,6); /* 待寫入數據存儲指針,寫入字節數 */
/* 寫入器件內首地址,寫入控制字,器件類型 */
RW24XX(0x40,10,0x0010,0xa1,6);
Delay(50); /* 檢查內部數據區0x30-0x39與0x40-0x49應完全相同 */
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -