⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 24cxxx.c

📁 程序是用52单片机对24C64进行读写操作,已经过测试,欢迎大家一起探讨.
💻 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 + -