打印
[技术问答]

硬件I2C读EEPROM的问题

[复制链接]
871|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
pq113_6|  楼主 | 2019-11-8 10:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
目前用IO模拟的方式读写EEPROM是正常的,说明硬件已经没问题了。但是硬件I2C读EEPROM有问题,写没问题。读的代码如下:
while (((I2Cx->STATUS_1.STATUS_1_Byte & 0x28) != I2C_STATUS_1_READY_MASK) && (timeout < I2C_READY_STATUS_TIMEOUT))
    {
        timeout ++;
    }
    if (timeout >= I2C_READY_STATUS_TIMEOUT)
    {
        errorStatus |= I2C_ERROR_START_NO_BUSY_FLAG;
    }

    errorStatus |= I2C_Start(I2Cx);
    errorStatus |= I2C_WriteOneByte(I2Cx, slaveAddr);
    if(addrbit == 16)
        errorStatus |= I2C_WriteOneByte(I2Cx, (addr >> 8));
    errorStatus |= I2C_WriteOneByte(I2Cx, (addr & 0xff));
    errorStatus |= I2C_Start(I2Cx);
    errorStatus |= I2C_WriteOneByte(I2Cx, slaveAddr | 0x01);
    while(len > 1 && (errorStatus == I2C_ERROR_NULL))
    {
        errorStatus |= I2C_ReadOneByte(I2Cx, pdata, I2C_SEND_ACK);
        pdata++;
        len--;
    }
    errorStatus |= I2C_ReadOneByte(I2Cx, pdata, I2C_SEND_NACK);
    errorStatus |= I2C_Stop(I2Cx);
    if(errorStatus == I2C_ERROR_NULL)
        return TRUE;
    else
    {
        Printf("I2C Read Fail:%x, len:%d\n", errorStatus, len);
        return FALSE;
    }


errorStatus没有错误,返回都是I2C_ERROR_NULL,读回来的数据错了一个字节。
然后我在errorStatus |= I2C_WriteOneByte(I2Cx, slaveAddr | 0x01);后面加一句空读就正常了。
errorStatus |= I2C_ReadOneByte(I2Cx, pdata, I2C_SEND_ACK);//dummy read?
这个是必须的吗?没看到文档有说明这部分的内容。

使用特权

评论回复

相关帖子

沙发
JasonLee27| | 2019-11-8 17:57 | 只看该作者
IIC驱动代码里有一个专门的Restart函数,你可以用这个试试I2C_Restart

使用特权

评论回复
板凳
pq113_6|  楼主 | 2019-11-11 08:28 | 只看该作者
JasonLee27 发表于 2019-11-8 17:57
IIC驱动代码里有一个专门的Restart函数,你可以用这个试试I2C_Restart

试过,一样的,看代码2个程序作用应该是一样的,就一句不同。

使用特权

评论回复
地板
zchunhua25| | 2019-11-11 15:02 | 只看该作者
我已经改写了这个芯片的IIC驱动,在写函数上增加一个读完是否STOP的参数进去,这样决定写完地址后可以不用产生STOP,然后直接执行读操作。EEPROM已经测试OK。

使用特权

评论回复
5
internally| | 2019-11-11 19:52 | 只看该作者
是因为读操作的时候中间被插入了STOP位了么

使用特权

评论回复
6
pq113_6|  楼主 | 2019-11-12 08:14 | 只看该作者
zchunhua25 发表于 2019-11-11 15:02
我已经改写了这个芯片的IIC驱动,在写函数上增加一个读完是否STOP的参数进去,这样决定写完地址后可以不用 ...

读确实要dummy read一个字节,仔细看了一下例程中的读代码:
//dummy read one byte to switch to Rx mode */
    if (dataLength == 1)
    {
        I2C_ReadOneByte(I2Cx, &rdBuff[0], I2C_SEND_NACK);   /* NACK will influence next transmission. */
    }
    else
    {
        I2C_ReadOneByte(I2Cx, &rdBuff[0], I2C_SEND_ACK);
    }

使用特权

评论回复
7
TechHolder| | 2019-11-12 11:01 | 只看该作者
pq113_6 发表于 2019-11-12 08:14
读确实要dummy read一个字节,仔细看了一下例程中的读代码:
//dummy read one byte to switch to Rx mod ...

现在OK了吗?

使用特权

评论回复
8
pq113_6|  楼主 | 2019-11-12 12:11 | 只看该作者

OK了,没仔细看库文件,不知道还有dummy读这一说

使用特权

评论回复
9
TechHolder| | 2019-11-13 14:56 | 只看该作者
pq113_6 发表于 2019-11-12 12:11
OK了,没仔细看库文件,不知道还有dummy读这一说

dummy读取,就是对写的数据不关心,只关心读取的数据。

使用特权

评论回复
10
operating| | 2019-11-17 17:47 | 只看该作者
需不需要重新初始化模块

使用特权

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

本版积分规则

36

主题

284

帖子

3

粉丝