C51读写AT24C04源代码及AT24C04测试程序

电子说

1.2w人已加入

描述

 一、C51读写AT24C04源代码

  /*=============================================*/

  /*;***********************************/

  /*;起动24C01时序*/

  void Start()

  {

  SCL=1;

  SDA=1;

  SDA=0;

  SCL=0;

  }

  /*;************************************/

  /*;停止24C01时序*/

  void Stop()

  {

  SDA=0;

  SCL=1;

  SDA=1;

  }

  /*;**************************************/

  /*;检测24C01的响应信号*/

  bit ACK()

  {

  bit c;

  SDA=1;

  SCL=1;

  c=SDA;

  SCL=0;

  return c;

  }

  /*;************************************/

  /*;往24C01发一8位数据*/

  void SendChar(unsigned char ch)

  {

  unsigned char i;

  i=8;

  do

  {

  SDA=(ch&0x80);

  SCL=1;

  SCL=0;

  ch《《=1;

  }while(--i!=0);

  }

  /*;**************************************/

  /*;从24C01接收一8位数据*/

  unsigned char RecChar()

  {

  unsigned char i,j;

  i=8;

  do

  {

  SCL=1;

  j=(j《《1)|SDA;

  SCL=0;

  }while(--i!=0);

  return j;

  }

  //;**************************************

  /*;********************************/

  /*;往24C01写一字节*/

  void WriteChar(unsigned int addr,unsigned char ch)

  {

  unsigned char c;

  c=((*((unsigned char *)&addr))《《1)&0x02;

  Start();

  SendChar(0xa0|c);

  ACK();

  SendChar(addr);

  ACK();

  SendChar(ch);

  ACK();

  Stop();

  // for(addr=4;addr!=0;addr--)

  for(ch=0xff;ch!=0;ch--) ;

  }

  //;**************************************

  /*;********************************/

  /*;往24C01写多字节*/

  void WriteBuf(unsigned int addr,unsigned char idata *buf,unsigned char count)

  {

  unsigned char c;

  c=((*((unsigned char *)&addr))《《1)&0x02;

  Start();

  SendChar(0xa0|c);

  ACK();

  SendChar(addr);

  ACK();

  do

  {

  SendChar(*buf++);

  ACK();

  if(count!=1)

  {if(((++addr)&0x7)==0)

  {

  Stop();

  for(c=0xff;c!=0;c--) ;

  c=((*((unsigned char *)&addr))《《1)&0x02;

  Start();

  SendChar(0xa0|c);

  ACK();

  SendChar(addr);

  ACK();

  }

  }

  else

  {

  Stop();

  for(c=0xff;c!=0;c--) ;

  }

  }while(--count!=0);

  }

  /*;**********************************/

  /*;从24C01读一字节*/

  /*;入口:R0中为要读出内容的地址*/

  /*;出口:A中为读到的内容*/

  unsigned char ReadChar(unsigned int addr)

  {

  unsigned char ch;

  ch=((*((unsigned char *)&addr))《《1)&0x02;

  Start();

  SendChar(0xa0|ch);

  ACK();

  SendChar(addr);

  ACK();

  Start();

  SendChar(0xa1|ch);

  ACK();

  ch=RecChar();

  Stop();

  return ch;

  }

  /**********************************/

  /*至少读2字节*/

  void ReadBuf(unsigned int addr,unsigned char idata *buf,unsigned char count)

  {

  unsigned char ch;

  ch=((*((unsigned char *)&addr))《《1)&0x02;

  Start();

  SendChar(0xa0|ch);

  ACK();

  SendChar(addr);

  ACK();

  Start();

  SendChar(0xa1|ch);

  ACK();

  count--;

  do

  {

  *buf++=RecChar();

  SDA=0;

  SCL=1;

  SCL=0;

  SDA=1;

  }while(--count!=0);

  *buf=RecChar();

  Stop();

  }

  二、AT24C04测试程序

  /**************************************

  主芯片 : STC12C5A60S2 (1T)

  工作频率: 12.000MHz

  **************************************/

  #include “REG51.H”

  #include “INTRINS.H”

  typedef unsigned char BYTE;

  typedef unsigned short WORD;

  sbit SCL = P3^4; //AT24C04的时钟

  sbit SDA = P3^5; //AT24C04的数据

  BYTE BUF[16]; //数据缓存区

  BYTE code TESTDATA[] =

  {

  0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,

  0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF

  };

  void Delay5us();

  void Delay5ms();

  void AT24C04_Start();

  void AT24C04_Stop();

  void AT24C04_SendACK(bit ack);

  bit AT24C04_RecvACK();

  void AT24C04_SendByte(BYTE dat);

  BYTE AT24C04_RecvByte();

  void AT24C04_ReadPage();

  void AT24C04_WritePage();

  void main()

  {

  AT24C04_WritePage();

  Delay5ms();

  AT24C04_ReadPage();

  while (1);

  }

  /**************************************

  向AT24C04写1页(16字节)数据

  将TESTDATA开始的16个测试数据写如设备的00~0F地址中

  **************************************/

  void AT24C04_WritePage()

  {

  BYTE i;

  AT24C04_Start(); //起始信号

  AT24C04_SendByte(0xa0); //发送设备地址+写信号

  AT24C04_SendByte(0x00); //发送存储单元地址

  for (i=0; i《16; i++)

  {

  AT24C04_SendByte(TESTDATA[i]);

  }

  AT24C04_Stop(); //停止信号

  }

  /**************************************

  从AT24C04读取1页(16字节)数据

  将设备的00~0F地址中的数据读出存放在DATA区的BUF中

  **************************************/

  void AT24C04_ReadPage()

  {

  BYTE i;

  AT24C04_Start(); //起始信号

  AT24C04_SendByte(0xa0); //发送设备地址+写信号

  AT24C04_SendByte(0x00); //发送存储单元地址

  AT24C04_Start(); //起始信号

  AT24C04_SendByte(0xa1); //发送设备地址+读信号

  for (i=0; i《16; i++)

  {

  BUF[i] = AT24C04_RecvByte();

  if (i == 15)

  {

  AT24C04_SendACK(1); //最后一个数据需要会NAK

  }

  else

  {

  AT24C04_SendACK(0); //回应ACK

  }

  }

  AT24C04_Stop(); //停止信号

  }

  /**************************************

  延时5微秒(STC12C5A60S2@12M)

  不同的工作环境,需要调整此函数

  此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同

  **************************************/

  void Delay5us()

  {

  BYTE n = 4;

  while (n--)

  {

  _nop_();

  _nop_();

  }

  }

  /**************************************

  延时5毫秒(STC12C5A60S2@12M)

  不同的工作环境,需要调整此函数

  此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同

  **************************************/

  void Delay5ms()

  {

  WORD n = 2500;

  while (n--)

  {

  _nop_();

  _nop_();

  _nop_();

  _nop_();

  _nop_();

  }

  }

  /**************************************

  起始信号

  **************************************/

  void AT24C04_Start()

  {

  SDA = 1; //拉高数据线

  SCL = 1; //拉高时钟线

  Delay5us(); //延时

  SDA = 0; //产生下降沿

  Delay5us(); //延时

  SCL = 0; //拉低时钟线

  }

  /**************************************

  停止信号

  **************************************/

  void AT24C04_Stop()

  {

  SDA = 0; //拉低数据线

  SCL = 1; //拉高时钟线

  Delay5us(); //延时

  SDA = 1; //产生上升沿

  Delay5us(); //延时

  }

  /**************************************

  发送应答信号

  入口参数:ack (0:ACK 1:NAK)

  **************************************/

  void AT24C04_SendACK(bit ack)

  {

  SDA = ack; //写应答信号

  SCL = 1; //拉高时钟线

  Delay5us(); //延时

  SCL = 0; //拉低时钟线

  Delay5us(); //延时

  }

  /**************************************

  接收应答信号

  **************************************/

  bit AT24C04_RecvACK()

  {

  SCL = 1; //拉高时钟线

  Delay5us(); //延时

  CY = SDA; //读应答信号

  SCL = 0; //拉低时钟线

  Delay5us(); //延时

  return CY;

  }

  /**************************************

  向IIC总线发送一个字节数据

  **************************************/

  void AT24C04_SendByte(BYTE dat)

  {

  BYTE i;

  for (i=0; i《8; i++) //8位计数器

  {

  dat 《《= 1; //移出数据的最高位

  SDA = CY; //送数据口

  SCL = 1; //拉高时钟线

  Delay5us(); //延时

  SCL = 0; //拉低时钟线

  Delay5us(); //延时

  }

  AT24C04_RecvACK();

  }

  /**************************************

  从IIC总线接收一个字节数据

  **************************************/

  BYTE AT24C04_RecvByte()

  {

  BYTE i;

  BYTE dat = 0;

  SDA = 1; //使能内部上拉,准备读取数据

  for (i=0; i《8; i++) //8位计数器

  {

  dat 《《= 1;

  SCL = 1; //拉高时钟线

  Delay5us(); //延时

  dat |= SDA; //读数据

  SCL = 0; //拉低时钟线

  Delay5us(); //延时

  }

  return dat;

  }

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分