单片机/MCUwilliam hill官网
直播中

张三

12年用户 59经验值
擅长:模拟技术 测量仪表
私信 关注
[问答]

模拟I2C读写24c02,可以写,但读出错,大神们帮忙看看

void IIC_write(u8 addr,u8 data)
    IIC_Start();
    IIC_Send_Byte(addr); //发送写命令
    IIC_Stop(); //发送停止信号   

unsigned char IIC_Read(unsigned char addr)
{
        unsigned char data;
    IIC_Start();
        IIC_Send_Byte(0xa0); //发送写器件地址
        IIC_Send_Byte(addr); //发送要读取的地址
    IIC_Start();
        IIC_Send_Byte(0xa1); //发送读器件地址
        data=IIC_Read_Byte(); //读取数据
        IIC_Stop();
        return data;       

}
b0c5ef3eb15b01015dfba0f75e105a6.jpg 9e7ddf2a80f76a44bf532ca0a98482b.jpg 12fe5a99ef523d483e36b267241b155.jpg 2cff0e5f84cc3bc259d1688306e4577.jpg

已退回40积分

回帖(5)

张三

2020-6-17 17:37:21
unsigned char IIC_Read_Byte(void)
{
        unsigned char a=0,data=0;
        TRISC4=0;    //设置为输出
        RC4=1;       //输出高电平
    delay_us();       
        delay_us();       
        TRISC4=1;    //设置为输入
    delay_us();       
        for(a=0;a<8;a++)//接收8个字节
        {
               
                delay_us();
                IIC_SCL=1;
               delay_us();       
                data<<=1;
                data|=IIC_SDA;
               delay_us();       
                IIC_SCL=0;
               delay_us();       
        }
        return data;
}

已经设置上拉了,但是读取的时候一直是低电平
举报

jiciwi

2020-6-17 18:39:34
你都不管ACK的么,然后读的时候,第一次也也要STOP吧
15 举报
  • 张三: 有呀,第一张图有个小凸起,那就是24c02的ack,开始后的第9位
  • jiciwi 回复 张三: 我觉得你少一个脉冲呀,第一个脉冲是起始,后面8个的芯片地址,然后是ACK脉冲,然后是8个地址,再ACK脉冲,再8个数据脉冲,再ACK脉冲,再停止时序
  • 张三 回复 jiciwi: 有ack,不然我也写不进去
  • jiciwi 回复 张三: 你没读出来怎么知道写进去了,然后对不对,你现在都是强制在发脉冲的
  • 张三 回复 jiciwi: 我用硬件配置方法可以读写,现在想移到stm32上,所有才搞模拟的i2c
  • 张三: 开始-》写指令-》内存地址-》开始-》读指令,不是这样的吗?
  • jiciwi 回复 张三: ACK也是一个脉冲,也是需要SCL脉冲的
  • jiciwi 回复 张三: 你可以忽略ACK的值,但是脉冲还是要给的
  • 张三 回复 jiciwi: ack肯定写了,只是瞬间被24c02拉低了,所有示波器只看到一个小突起,我用硬件只要接上示波器,就读不出来,所有也看不到它的时序
  • jiciwi 回复 张三: 不是写啊,你写的时候ACK是返回,只有在读数据后才是你发的,我说的是SCL脉冲,ACK那里也需要SCL脉冲
  • 张三 回复 jiciwi: 真的有,开始,然后发送0xa0,然后是ack脉冲,然后是地址0x01;我截图可以看得很清楚,你可以数一下两个数据之间是不是多一个脉冲
  • 张三 回复 jiciwi: 第一张图和第二张图可以连起来的
  • jiciwi 回复 张三: 那读的话,START-&gt;芯片地址写-&gt;ACK-&gt;写地址-&gt;ACK-&gt;START-&gt;芯片地址读-&gt;ACK-&gt;读地址-&gt;ACK-&gt;读数据
  • 张三 回复 jiciwi: 今天调了一下延时,发现可以读到前4位数据了,于是我在sda上加了上拉电阻就ok了
  • jiciwi 回复 张三: 你原来不是说已经加了上拉电阻么

傅刚

2020-6-18 03:38:16
时序要求太严格,干扰场合读出数据容易出错。
举报

杨先生

2020-6-18 09:37:00
给几点建议:
1、严格按照时序写。软实现是最好调整时序的,但细心一点。看你的时序就比较乱。
2、你写的时候为什么只有3句,写入的数据呢?
3、写入1次有个5ms的事情,你是否知道?
讲个我的故事:时序写不好,只有最高位读取出错,并且是第二字节,当为01xxxxxx时,会读成11xxxxxx,所以自己一点点看时序,从软件,从示波器,明确知道自己什么时候拉低的,什么时候拉高的,宽度是否符合芯片电气特性。
最后重点就是,不要抄别人的,会坑死你自己。
1 举报
  • 张三: 我加了上拉电阻就好了,但用硬件配置可以不用加,配置为上拉输入就好了,这个有点不舒服,最后一句话非常同意

1427074383

2020-7-23 16:55:43
写操作结束后不需要发Stop脉冲直接进行读操作吗。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分