打印

关于AT24C64读写的问题

[复制链接]
4822|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ilovecr|  楼主 | 2007-11-13 22:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#define WRITE_1 0xa0  //    写第一片
#define WRITE_2 0xa2  //写第二
#define WRITE_3 0xa4  //写第三片
#define READ_1 0xa1   //读的一片
#define READ_2 0xa3  //读第二片
#define READ_3 0xa5  //读第三片
#define ZC_AD   0xff10//暂存区首地址

#define HIGH 1
#define LOW 0
#define FALAE 0
#define TRUE ~FALAE
sbit D_SDA = P1^7;
sbit D_CLOCK=P3^4;
//void delay_0(void)
    // {;}
////////////////////     
void I_start(void)//工作时序起始
    {
        D_CLOCK=HIGH;
        Delay(1);
        D_SDA=LOW;
        Delay(1);
        D_CLOCK=LOW;
        Delay(1);
       }

void I_stop(void)//工作时序停止
     {
         
        D_SDA=LOW;
        Delay(1);
        D_CLOCK=HIGH;
        Delay(1);
        D_SDA=HIGH;
        Delay(1);
        D_CLOCK=LOW;
        Delay(1);

     }


void I_init(void)//总线初始化
      {
      D_CLOCK=LOW;
          
      I_stop();    
          
        }


bit I_clock(void)//总线时钟

    {
         bit sa;
         D_CLOCK=HIGH;
        Delay(1);
         sa=D_SDA;
         D_CLOCK=LOW;
        Delay(1);
        return (sa);
         
        
    }                        

bit I_send( uchar I_data)//发送8位数据
      {
          uchar i;
          for(i=0;i<8;i++)
             {
                 D_SDA=(bit)(I_data&0x80);
                 I_data=I_data<<i;
                 I_clock();
            }
          D_SDA=HIGH;
          return(~I_clock());
      }

uchar I_receive(void) //接收8位数据
    {
        uchar I_data=0;
        uchar i;
        for(i=0;i<8;i++)
          {
              I_data*=2;
              if(I_clock())
                       {I_data++;}
                       
              
           }
         return(I_data);
    }
void I_Ack(void)//应答信号
    {
        D_SDA=LOW;
        I_clock();
        D_SDA=HIGH;
        }      

bit E_address(uchar WR,uint Address)//向器件写入地址和字节地址,写操作(,写器件地址,器件中地址)
    {
        I_start();
        if(I_send(WR))
               return (I_send(Address));
      else
             return (FALAE);
    }
    
 
bit E_read_block(uchar WR,uchar RD, uint Address)//读取字节(读器件地址,读器件内部地址)
    {
        uchar i;
        if(E_address(WR,Address))
               {
                   I_start();
                   if(I_send(RD))
                          {
                              for(i=0;i<=8;i++)
                                 {
                                     XBYTE[ZC_AD+i]=(I_receive());
                                     if(i!=8)
                                            { I_Ack();}
                                  else 
                                          {
                                            I_clock();
                                            I_stop();
                                            }
                                     }
                              return (TRUE);
                              }
                         else
                             {
                                 I_stop();
                                 return (FALAE);
                                 }     
                   } 
             else
                   I_stop();
                   return(FALAE);      
        
        } 
        
        
bit E_write_block(uchar WR, uint Address)//将外部数据储存的暂时存储数据存储24C64中
     {
         uchar i;
         for(i=0;i<=8;i++)
               {
                   if(E_address(WR,Address+i)&&I_send(XBYTE[ZC_AD+i]))
                         {I_stop(); Delay(10);}
                   else
                        return (FALAE);
                   }
         
         return (TRUE);
         
         }  
         

    
                 
         
main()
  {  
      uchar i,x_0,y_0;
       uchar j,z,m;
       uchar xdata abc[9];
        
             z=1;
             m=1;
             I_init();
           LCDInit();
       LCDClear();
       Y_1();
       Delay(5);
    
  

       for(j=0;j<8;j++)
          {
              XBYTE[ZC_AD+j]=j;      /////往数据存储器中存储数据
          }
           Delay(5);
             z=E_write_block(0x000);
              Delay(5);
           
       for(j=0;j<8;j++)
        {
            XBYTE[ZC_AD+j]=j+2;      //往数据存储器中存储数据
        }   
        
         z=E_write_block(0x010);
           Delay(5);
        
        
          m=E_read_block(0x000);
          Delay(5);
       
        for(j=0;j<8;j++)
             {
                 abc[j]=XBYTE[ZC_AD+j];
             }
         
       Y_7();
         while(1)
         
         {
              x_0=0;
                   y_0=0;
         
             DisplayCN(0,32,z);
             DisplayCN(0,64,m);
              for(i=0;i<8;i++)
               {
                 DisplayCN(x_0,y_0,abc);
                 x_0=x_0+2;
                 }
      
         }   
        
        }       

请教现在这个程序无法读写24C64,请教问题能出在哪里!

相关帖子

沙发
ilovecr|  楼主 | 2007-11-13 22:34 | 只看该作者

我用了3片24C64


主函数可以不看,主函数是改用一个片子的读写,仍然不行

使用特权

评论回复
板凳
ayb_ice| | 2007-11-14 07:58 | 只看该作者

基本程序有问题吧

使用特权

评论回复
地板
ilovecr|  楼主 | 2007-11-14 08:04 | 只看该作者

问题出在哪里!请赐教!现在思绪有点乱

使用特权

评论回复
5
ilovecr|  楼主 | 2007-11-14 08:05 | 只看该作者

我的元件地址分配如下


写从机1的地址是1010,000,0  读是1010,000,1  片内地址是0-2FFF
写从机2的地址是1010,001,0   读是1010,001,1  片内地址是0-2fff
写从机3的地址是1010,010,0   读是1010,010,1  片内地址是0-2fff
我这样理解对吗! 

使用特权

评论回复
6
gjg191| | 2007-11-14 12:28 | 只看该作者

dd

地址有3位是靠硬件分配的你弄对了吗

使用特权

评论回复
7
ilovecr|  楼主 | 2007-11-14 12:37 | 只看该作者

那个分配好了

那个分配好了

使用特权

评论回复
8
涛行九天| | 2007-11-14 21:46 | 只看该作者

www.study-bbs.com

单片机版面置顶帖子有代码,自己下了看看吧

使用特权

评论回复
9
草履虫| | 2007-11-15 08:39 | 只看该作者

问题可能?

你的ACK信号检测好像有问题,很可能还没有出现ACK信号你就返回了。


IIC器件的连接需在接上拉。如果I2C的器件过多,可能驱动不了。
你先适好一片,再适另一片,每片都调通后再适其他的。

使用特权

评论回复
10
ilovecr|  楼主 | 2007-11-15 20:29 | 只看该作者

谢谢各位的支持!

还是我的时序和,地址有问题,没办法参考了一个网上的程序,调试通过了,谢谢发布这个程序的朋友,现将代码贴出,声明这个程序不是我写的借用一下了,惭愧!还好通过这个程序我已把IIC 的时序基本弄懂了
#define ZC_AD   0x0300//暂存区首地址
#define  ERRORCOUNT 10
sbit     SDA=P1^7;
sbit     SCL=P3^4;


//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^0和P0^1;
//其余的用户不用管,只要把只子程序放在你的程序中并调用它就可以了;

/*************************************************************************/
bit RW24XX(unsigned char *DataBuff, unsigned char ByteQuantity, unsigned int Address, unsigned char ControlByte)
{
void Delay0(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))
  {
  Delay0(255);
  Delay0(255);
  Delay0(255);
  Delay0(255);
  }
return(errorflag);
}

/*****************以下是对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中的
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;        //无论C51怎样实现这个操作,始终会使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 Delay0(unsigned char DelayCount)
{
while(DelayCount--);
}

使用特权

评论回复
11
hotsic| | 2017-4-6 16:11 | 只看该作者
你好,CY 在哪里定义?

使用特权

评论回复
12
XIAO肖| | 2017-4-6 21:52 | 只看该作者
楼主解决问题没有?

使用特权

评论回复
13
daibumeikuai| | 2017-4-7 15:42 | 只看该作者
一般ack没处理好导致没调通 。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

45

主题

202

帖子

0

粉丝