当前位置: 代码迷 >> 单片机 >> 为什么24C02 读写出错了?解决思路
  详细解决方案

为什么24C02 读写出错了?解决思路

热度:75   发布时间:2016-04-28 16:07:20.0
为什么24C02 读写出错了?

  这是我使用51单片机 与24C02 之间进行读写的程序, 把一个已经初始化的数组里值 写入24C02, 然后读取24C02存储的数据,把结果显示在数码管里。


#include<reg52.h>
#include<intrins.h>
typedef unsigned char uchar;
//编码范围:0-9
unsigned char code table[10]={0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d,0x7,0x7f,0xef }; 


sbit SCL=P2^0; //时钟线
sbit SDA=P2^1; //数据线


void Write_I2C_Byte(unsigned char Data) //往24C02里写数据 即传送数据
{//传送数据Data 首先从高字节开始传送
  unsigned char i;
  for(i=0; i<8; i++)
  {
  SDA=Data&0x80; //Data和0x80进行逻辑"与"运算 即读取Data数据的高位
  Data=Data<<1; //由于已经读取一次高位 因此左移一位 从而可以继续读取下一位
  _nop_();

  SCL=1; //时钟线为高电平 使SDA数据线传输的数据能有效传送
  _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
  //延时 是为了保证SDA数据线传送的数据能够顺利完成传输过程
  SCL=0;
  _nop_(); _nop_();  

  }
}

unsigned char Read_I2C_Byte(void) //从24C02里读数据 即接收数据
{
  unsigned char Data=0;
  unsigned char i;  
   
  for(i=0; i<8; i++)
  {
  SCL=0;
  _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
   
  SCL=1;
  _nop_(); _nop_();
   
  Data=Data<<1; // 
  Data=Data|SDA; //调试的时候,发现: 从24C02芯片里读取一个字节时, SDA一直保持高电平,才导致返回Data的值是0xFF, 而在读取第二个字节的时候,SDA一直保持低电平, 所以导致 在数码管里显示的数字是: 800
  请问, 各位, 我这个程序,哪里出问题了?

  _nop_(); _nop_();

  SCL=0;  
  }
   
  return Data; //返回读取的数据
}

void Delay(unsigned char n)
{
  unsigned char i, j;
  for(i=n; i>0; i--)
  for(j=110; j>0; j--);
}

void Write(uchar DataStartAdress, uchar *pData, uchar count) // 写操作
{ //DataStartAdress 为数据起始保存地址, 
//pData指针为指向数据的指针变量, count 为写入字节的个数
   
  unsigned char i;
  I2C_Start(); 
  Write_I2C_Byte(WR24C02); //把器件地址 发送到24C02 里 
  Check_ACK();
  Write_I2C_Byte(DataStartAdress); //数据存储地址 即字地址 
  Check_ACK();

  for(i=0; i<count; i++)
  {
  Write_I2C_Byte(*pData); 
  Check_ACK(); 
  pData++; 
  }  
   
  I2C_Stop();

  Delay(20);
}

void Read(uchar DataStartAdress, uchar *pData, uchar count) // 读操作: 随机读
{
  unsigned char i;
  I2C_Start(); 
  Write_I2C_Byte(WR24C02); //把器件地址 发送到24C02 里 
  Check_ACK();
  Write_I2C_Byte(DataStartAdress); //数据地址 即字地址
  Check_ACK();

  I2C_Start(); 
  Write_I2C_Byte(RD24C02); 
  Check_ACK();
   
  for(i=0; i<count; i++)
  {
  *pData=Read_I2C_Byte();
  ACK(); 
  pData++;
  }  
  
  NoACK();  
  I2C_Stop();
  Delay(10);
}

void main(void)
{
  unsigned char WriteString[3]={3,6,9};
  unsigned char ReadString[3];

  unsigned char i;

  Write(0x00, WriteString, 3);
 
  Read(0x00, ReadString, 3);


  while(1)
  {
  P1=0xfe; //位选线
  i=ReadString[0];
  P0=table[i]; //段选线
  Delay(10);

  P1=0xfd;
  i=ReadString[1];
  P0=table[i];
  Delay(10);