51模拟iic读取24c16的数据总是0xff,求解。

[复制链接]
2103|8
 楼主| yzcook 发表于 2019-5-28 19:34 | 显示全部楼层 |阅读模式
简单的模拟,但是读取的数据总是0xff,请教各位。iic的函数应该不会有问题,因为是之前学开发板的标准程序 复制过来的。
但是怎么改都是0xff
已经改了两天了。还是这样。
麻烦各位帮忙解答一下 谢谢

void main()
{
    unsigned char dat;
                Init_Uart();
                E2WriteByte(0x02,0x01)  ;   
    dat = E2ReadByte(0x02);   
                SendByte(dat);
    while (1);
}


unsigned char E2ReadByte(unsigned char addr)
{
    unsigned char dat;

    I2CStart();
    I2CWrite(0x50<<1);
    I2CWrite(addr);   
    I2CStart();      
    I2CWrite((0x50<<1)|0x01);
    dat = I2CReadNAK();      
    I2CStop();

    return dat;
}


void E2WriteByte(unsigned char addr, unsigned char dat)
{
    I2CStart();
    I2CWrite(0x50<<1);
    I2CWrite(addr);   
    I2CWrite(dat);   
    I2CStop();
}


void I2CStart()
{
    I2C_SDA = 1;
    I2C_SCL = 1;
    I2CDelay();
    I2C_SDA = 0;
    I2CDelay();
    I2C_SCL = 0;
}


void I2CStop()
{
    I2C_SCL = 0;
    I2C_SDA = 0;
    I2CDelay();
    I2C_SCL = 1;
    I2CDelay();
    I2C_SDA = 1;
    I2CDelay();
}


bit I2CWrite(unsigned char dat)
{
    bit ack;
    unsigned char mask;  

    for (mask=0x80; mask!=0; mask>>=1)
    {
        if ((mask&dat) == 0)  
            I2C_SDA = 0;
        else
            I2C_SDA = 1;
        I2CDelay();
        I2C_SCL = 1;         
        I2CDelay();
        I2C_SCL = 0;         
    }
    I2C_SDA = 1;   
    I2CDelay();
    I2C_SCL = 1;  
    ack = I2C_SDA;
    I2CDelay();
    I2C_SCL = 0;  

    return (~ack);

}


unsigned char I2CReadNAK()
{
    unsigned char mask;
    unsigned char dat;

    I2C_SDA = 1;  
    for (mask=0x80; mask!=0; mask>>=1)
    {
        I2CDelay();
        I2C_SCL = 1;     
        if(I2C_SDA == 0)  
            dat &= ~mask;
        else
            dat |= mask;
        I2CDelay();
        I2C_SCL = 0;     
    }
    I2C_SDA = 1;   
    I2CDelay();
    I2C_SCL = 1;  
    I2CDelay();
    I2C_SCL = 0;   

    return dat;
}


unsigned char I2CReadACK()
{
    unsigned char mask;
    unsigned char dat;

    I2C_SDA = 1;  
    for (mask=0x80; mask!=0; mask>>=1)
    {
        I2CDelay();
        I2C_SCL = 1;     
        if(I2C_SDA == 0)  
            dat &= ~mask;
        else
            dat |= mask;  
        I2CDelay();
        I2C_SCL = 0;     
    }
    I2C_SDA = 0;   
    I2CDelay();
    I2C_SCL = 1;  
    I2CDelay();
    I2C_SCL = 0;   

    return dat;
}




Diyer123 发表于 2019-5-28 20:31 | 显示全部楼层
代码没看。不过存储器默认都是0xFF的……
所以你的测试代码要先写,再读出比较,才能知道是否读写正确。
叶春勇 发表于 2019-5-28 20:52 | 显示全部楼层
本帖最后由 叶春勇 于 2019-5-28 20:53 编辑

楼主,写通讯程序,搞个这个,事半功倍
你这个i2c程序,发送地址的时候没有验证从机的ack,建议补上,看看从机有没有ack

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
suncat0504 发表于 2019-5-28 21:23 | 显示全部楼层
测试的话,如果读写操作符合脉冲以及电平顺序,就看看时许对不对。比如时间间隔,这个和你的MPU的晶振有关,必要的话,加延时处理,保证时序匹配。
suncat0504 发表于 2019-5-28 21:29 | 显示全部楼层
另外晶振速度快的话,I2C_SCL = 1; 之后最好做必要的延时,24c16收到高电平,也需要一段准备时间,马上读,不稳定吧?
suncat0504 发表于 2019-5-28 21:34 | 显示全部楼层
刚查了下资料,读取数据应该是在SCL的下降沿之后读取。你的代码中好像是在SCL=1之后读取,请你再仔细看下24C16的资料。
xyz549040622 发表于 2019-5-29 08:27 | 显示全部楼层
24cxx 51的程序都烂大街了,除了修改下从机地址外,其他的照抄就好,还有注意延时函数的匹配。
ayb_ice 发表于 2019-5-29 08:33 | 显示全部楼层
判断下返回值,看设备是否有应答
linqing171 发表于 2019-5-30 08:41 | 显示全部楼层
看了第一个小函数,没有处理tWr,写完后等5ms再读。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

28

主题

84

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部