打印

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

[复制链接]
1760|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
恬蔚|  楼主 | 2013-11-16 12:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
看了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;
    Uint16  i;     
    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上的时序图

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
恬蔚 + 1
板凳
zhangjin_comeon| | 2013-11-18 23:04 | 只看该作者
哇  一看代码   就无头绪

使用特权

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

本版积分规则

51

主题

147

帖子

1

粉丝