野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 10970|回复: 7

关于I2C读取数据

[复制链接]
发表于 2019-3-25 20:49:22 | 显示全部楼层 |阅读模式
本帖最后由 steady 于 2019-3-25 20:49 编辑

问题前提条件,EEPROM里存的1,2,3,4,5,6,7。

通过查资料了解到I2C读取EEPROM时候,每读取一个地址的数据,AT24C02就会自动给指向的地址加1。
但是写程序的时候 写了   I2C_Send7bitAddress(EEPROM_I2C, EEPROM_ADDRESS, I2C_Direction_Receiver);后
就开始直接使用库函数读取DR的值了。      *pBuffer = I2C_ReceiveData(EEPROM_I2C);     /* Point to the next location where the byte read will be saved */
      pBuffer++;
    /* Decrement the read bytes counter */
      NumByteToRead--;然后回到*pBuffer = I2C_ReceiveData(EEPROM_I2C);

问题1: 通过把DR的值赋给*pBuffer,系统是会捕捉到这个操作,然后发出应答信号,DR继续接受下一个数据是吗?
如果不是,那又是怎么保证我每次读取DR的值都是前一次读取,地址加1后的值的。

问题2:我在   *pBuffer = I2C_ReceiveData(EEPROM_I2C);这句后加了个延时 for(int p=0xfff;p>2;p--);
但时间不够长时,程序运行是没有问题的(P=0xFF时),但延时过长时就会出现问题,
譬如将延时里的P=0xFFF时,初次运行没有问题,复位后再运行就会报错总线占用。
再烧入没修改过的官方例程也还是报错总线占用,必须断电后才恢复正常。请问这是什么原因?
STM32I2Cquestion.jpg
回复

使用道具 举报

发表于 2019-3-26 08:36:49 | 显示全部楼层
其实我觉得这些在野火的教程讲得好清楚,专门有讲你这些问题的
回复 支持 反对

使用道具 举报

发表于 2019-3-26 08:38:34 | 显示全部楼层

读eeprom后,只要一直产生应答信号,eeprom就会一直返回数据,跟你读不读数据寄存器没关
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-3-26 14:50:59 | 显示全部楼层
flyleaf 发表于 2019-3-26 08:38
读eeprom后,只要一直产生应答信号,eeprom就会一直返回数据,跟你读不读数据寄存器没关

使能应答后,自动产生应答,
那如果加延时后再读数据寄存器,
延时的期间里,新来数据不是就会覆盖还没来得及读出来的旧数据吗?
回复 支持 反对

使用道具 举报

发表于 2019-3-26 15:39:03 | 显示全部楼层
steady 发表于 2019-3-26 14:50
使能应答后,自动产生应答,
那如果加延时后再读数据寄存器,
延时的期间里,新来数据不是就会覆盖还没 ...

是的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-3-26 15:44:07 | 显示全部楼层

那样的话,如果接受数据和读取数据的速度没配对好,读一大串数据的时候,容易丢失数据。

还有问题,为什么我加延时后在读DR前,只能正常运行一次,再复位的时候,就报错 总线占用了?
回复 支持 反对

使用道具 举报

发表于 2019-3-26 15:47:21 | 显示全部楼层
steady 发表于 2019-3-26 15:44
那样的话,如果接受数据和读取数据的速度没配对好,读一大串数据的时候,容易丢失数据。

还有问题,为 ...

那为什么要加延时,stm32的速度比I2C总线运行的速度快多了,不是人为延时肯定是比接收的速度快
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-3-26 21:27:34 | 显示全部楼层
本帖最后由 steady 于 2019-3-27 09:33 编辑
flyleaf 发表于 2019-3-26 15:47
那为什么要加延时,stm32的速度比I2C总线运行的速度快多了,不是人为延时肯定是比接收的速度快

有个新问题请教
{
  /* Read a byte from the device */
   *pBuffer = I2C_ReceiveData(EEPROM_I2C);
while(!(I2C_ReadRegister(EEPROM_I2C, I2C_Register_SR1)&0x0040))  /*检测RxNE*/
{
}
/* Point to the next location where the byte read will be saved */
   pBuffer++;
   /* Decrement the read bytes counter */
      NumByteToRead--;
                }        
为了搞清楚RxNE有没有被置0,我加了个检测该位的语句,
while((I2C_ReadRegister(EEPROM_I2C, I2C_Register_SR1)&0x0040)==0)  /*检测RxNE*/
{
}
可无论是判断条件是=0还是=1, 都可以正常运行,没有陷入死循环。
这是为什么呀?


回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-9-21 22:19 , Processed in 0.054007 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表