打印

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

[复制链接]
1744|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

逻辑分析仪.png (270.02 KB )

逻辑分析仪.png

使用特权

评论回复
地板
suncat0504| | 2019-5-28 21:23 | 只看该作者
测试的话,如果读写操作符合脉冲以及电平顺序,就看看时许对不对。比如时间间隔,这个和你的MPU的晶振有关,必要的话,加延时处理,保证时序匹配。

使用特权

评论回复
5
suncat0504| | 2019-5-28 21:29 | 只看该作者
另外晶振速度快的话,I2C_SCL = 1; 之后最好做必要的延时,24c16收到高电平,也需要一段准备时间,马上读,不稳定吧?

使用特权

评论回复
6
suncat0504| | 2019-5-28 21:34 | 只看该作者
刚查了下资料,读取数据应该是在SCL的下降沿之后读取。你的代码中好像是在SCL=1之后读取,请你再仔细看下24C16的资料。

使用特权

评论回复
7
xyz549040622| | 2019-5-29 08:27 | 只看该作者
24cxx 51的程序都烂大街了,除了修改下从机地址外,其他的照抄就好,还有注意延时函数的匹配。

使用特权

评论回复
8
ayb_ice| | 2019-5-29 08:33 | 只看该作者
判断下返回值,看设备是否有应答

使用特权

评论回复
9
linqing171| | 2019-5-30 08:41 | 只看该作者
看了第一个小函数,没有处理tWr,写完后等5ms再读。

使用特权

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

本版积分规则

28

主题

84

帖子

0

粉丝