恬蔚 发表于 2013-11-16 12:41

AT24C08写时序的问题,帮忙看下吧

看了AT24C08的datasheet但还是不懂,不知道这个写控制字{ bytein(0xA0 + ((addr & 0x0300) >> 7))}是怎么得来的,我将addr & 0x0300中的0x0300改成0x0500什么的,对结果没有影响!
还有 bytein(0xA0 + ((addr & 0x0300) >> 7));//写入写控制字0xA0
    bytein(addr);                                               //写入指定地址
    begintrans();                                               //开始
    bytein(0xA1);    这段话是读操作中的立即地址读吗?
void begintrans(void)                                       //发送START 信号
{
    SDA_W1;                                                         //SDA=1
    delay(DELAY_UNIT * 10);                         //延时
    SDA_WRITE();                                            //SDA 方向为输出到EEPROM
    delay(DELAY_UNIT * 10);                         //延时
    SCL_1;                                                          //SCL=1
    delay(DELAY_UNIT * 10);                         //延时
    SDA_W0;                                                         //SDA=0
    delay(DELAY_UNIT * 10);                              //延时
}

void stoptrans(void)                                      //发送STOP 信号
{
    SDA_WRITE();                                            //SDA方向为输出到EEPROM
    delay(DELAY_UNIT * 10);                              //延时
    SDA_W0;                                                         //SDA=0
    delay(DELAY_UNIT * 10);                         //延时
    SCL_1;                                                          //SCL=1
    delay(DELAY_UNIT * 10);                         //延时
    SDA_W1;                                                         //SDA=1
    delay(DELAY_UNIT * 10);       
}

void ack(void)                                            //等待EEPROM 的ACK 信号
{
    Uint16 d;
    Uint16i;   
    SDA_READ();                                             //SDA方向为从EEPROM 输入
    delay(DELAY_UNIT * 2);                          //延时
    SCL_1;                                                          //SCL=1
    delay(DELAY_UNIT * 2);                                //延时
    i = 0;            
    do
    {
      d = SDA_R;
      i++;
      delay(DELAY_UNIT);       
    }
    while((d == 1) && (i <= 500));              //等待EEPROM 输出低电平,4ms后退出循环

    if (i >= 499)
    {
      eromrw_err = 0xff;
    }
   
    i = 0;         
    SCL_0;                                                          //SCL=0
    delay(DELAY_UNIT * 2);                          //延时
}

void bytein(Uint16 ch)                                        //向EEPROM 写入一个字节
{
    Uint16 i;   
    SCL_0;                                                          //SCL=0
    delay(DELAY_UNIT * 2);                                        //延时
    SDA_WRITE();                                            //SDA方向为输出到EEPROM
    delay(DELAY_UNIT);                                        //延时
    for(i=8;i>0;i--)
    {       
      if ((ch & 0x80)== 0)
            {
            SDA_W0;                                           //数据通过SDA 串行移入EEPROM
            delay(DELAY_UNIT);                                //延时
            }
      else
            {
            SDA_W1;
            delay(DELAY_UNIT);                                //延时
            }
      SCL_1;                                                      //SCL=1
      delay(DELAY_UNIT * 2);                      //延时
      ch <<= 1;
      SCL_0;                                                      //SCL=0
      delay(DELAY_UNIT);                              //延时
    }
    ack();
}

Uint16 byteout(void)                                      //从EEPROM 输出一个字节
{
    unsigned char i;
    Uint16 ch;
    ch = 0;

    SDA_READ();                                             //SDA 的方向为从EEPROM 输出
    delay(DELAY_UNIT * 2);                                 //延时
    for(i=8;i>0;i--)
    {
      ch <<= 1;
      SCL_1;                                                      //SCL=1
      delay(DELAY_UNIT);                              //延时
      ch |= SDA_R;                                            //数据通过SDA 串行移出EEPROM
      delay(DELAY_UNIT);                                   //延时
      SCL_0;                                                      //SCL=0
      delay(DELAY_UNIT * 2);                      //延时
    }
    ack();
    return(ch);
}

void writebyte(Uint16 addr,Uint16 data)         //向EEPROM 指定地址写入一个字节的数据
{
    begintrans();                                                        //开始
    bytein(0xA0 + ((addr & 0x0300) >> 7));//写入写控制字0xA0
    bytein(addr);                                               //写入指定地址
    bytein(data);                                                      //写入待写入EEPROM 的数据
    stoptrans();                                                        //停止
    delay(8000);
}



Uint16 readbyte(Uint16 addr)                                 //从EEPROM 指定地址读取一个字节的数据
{
    Uint16 c;   
    begintrans();                                               //开始
    bytein(0xA0 + ((addr & 0x0300) >> 7));//写入写控制字0xA0
    bytein(addr);                                               //写入指定地址
    begintrans();                                               //开始
    bytein(0xA1);                                               //写入读控制字0xA1
    c = byteout();                                              //读出EEPROM 输出的数据
    stoptrans();                                              //停止
    delay(2000);                                              //延时
    return(c);

zhangmangui 发表于 2013-11-16 18:35

addr应该是一个字节   与0x0300位与之后为0   右移7位也是0
所以写入的还是0xA0   
写入0xA0和0xA1的区别可能就是最后一位是0还是1代表着是写还是读
你可以看看datasheet上的时序图

zhangjin_comeon 发表于 2013-11-18 23:04

哇一看代码   就无头绪
页: [1]
查看完整版本: AT24C08写时序的问题,帮忙看下吧