74

帖子

0

TA的资源

一粒金砂(初级)

41
 

被ST的固件库中的I2C部分整怕了,现在还是用模拟的好

这是ST的官方版本吗?还是民间版本啊。

想当年,为了把I2C调好,使用了网上五六个版本都有问题,最后还是用的模拟方式
此帖出自stm32/stm8论坛
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

42
 

地址问题

弱弱的问一下  我我怎么知道  数据具体是写在那个地址啊?
还有I2C_Comm_MasterRead(I2C1, 0xa0, 5, Rx1_Buffer, 2);    读的话 从设备地址应该是0xA1啊~
此帖出自stm32/stm8论坛
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

43
 

函数第二个参数就是从设备的7位地址左移一位

                                 完全不用考虑通信的方向,读还是写。
此帖出自stm32/stm8论坛
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

44
 

DMA方式运行不下去,求救!

谢谢LZ提供的固件库。

我在万利的199板子上采用DMA主设备方式读写24c02没有成功,都死在
while(i2c_comm_state !=0);
这句中。请LZ或版主指点。

DMA初始化中
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)pBuffer; // from function input parameter
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // fixed for send function
  DMA_InitStructure.DMA_BufferSize = length; // from function input parameter
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // fixed
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // fixed
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte; //fixed
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //fixed
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // fixed
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;  // up to user
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // fixed

其中一句:
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte; //fixed
应当为:
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
此帖出自stm32/stm8论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

45
 

楼主,我的总线超时。

                                 楼主,我用原来的ST的库可以正常读写,但这个总是说总线忙超时,我已经把总线忙超时改成很大了,不知道为啥还是不行:(
此帖出自stm32/stm8论坛
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

46
 

回复laotong

都死在while(i2c_comm_state !=0);
说明I2C通信没有结束。由于该变量表示此次通信处于什么状态,
typedef enum i2c_state
{
  COMM_DONE  = 0,  // done successfully
  COMM_PRE = 1,
  COMM_IN_PROCESS = 2,
  CHECK_IN_PROCESS = 3,
  COMM_EXIT = 4 // exit since failure
}I2C_STATE;
不为0,表示没有结束,你看看值是多少,就知道通信死在哪个阶段。当然具体看哪里出错还是要看看波形。

我这里读写e2prom都没有问题的。

另外你提到的修改部分,确实如此,笔误了一下,谢谢。

还有就是,DMA的文档和主/从项目已经更新了。
此帖出自stm32/stm8论坛
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

47
 

回复hugoliang

你“把总线忙超时改到很大了”,你应该用的是第一种查询的方式。

返回总线忙,是因为在发起I2C通信之前,察看总线没有处于空闲状态,即不是SDA和SCK都为高电平。由此函数判断这种情况下,有其他设备在I2C总线上通信。但是对于大多数用户,仅有两个设备在总线上的情况下,这种总线非空闲状态,往往由于前一次通信不正确结束造成。

建议你先察看总线电平的状态。
此帖出自stm32/stm8论坛
 
 
 

回复

57

帖子

0

TA的资源

一粒金砂(初级)

48
 

多种中断情况下,还是不能正常读写

                                 在万理199板子上,如果只是单一的I2C读写E2PROM,都能正常的工作。现在的问题是程序中存在多种中断,USART,TIM,SYSTICK等等。就不能对E2PROM正常的读写,就会死在循环中。给I2C设了最高级的中断也不能通过。
此帖出自stm32/stm8论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

49
 

和应用(其他)中断相关的话,那么

如果中断发生,并且过了较长时间才返回,就是说在下一个数据传输完成之前都没有返回,那么会有BTF置位的情况,并发生时钟延展(clcok stretch)。

如果中断发生在读取状态寄存器和和BTF置位之前,会造成后续通信的问题。针对此,大体两个解决办法,使用DMA;或者使用中断方式,但是中断优先级最高。

laotong,现在我想确定四点:
1. 你用的DMA还是中断方式的库? 
2. 如果是DMA方式的话,请采用更新后的DMA库函数(还在32楼)
3. 示波器看一下波形,通信死在哪里?
4. 在通信死的附近,确定周围其他应用中断的情况,比如先排除,以确定是哪个应用中断造成的I2C“死机”,然后在该应用中断里toggle一下,比较I2C通信死的时候的波形。

给你造成的不便深表歉意。
此帖出自stm32/stm8论坛
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

50
 

怎么写跨页函数啊。。

                                 我用的EEPROM是24C02 PAGESIZE是8.但是我自己写不出来翻页函数。。。有人能给一个么。。。麻烦了。。自己试着写 但是没用。还是一次只能写3个字节。想一次把数组里面的所有数据都写进去。麻烦各位高手了。。。写地址是Oxa0.
此帖出自stm32/stm8论坛
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

51
 

跨页写EEPROM必须分开先写前一页再写后一页

                                 不可能一次跨页写。
此帖出自stm32/stm8论坛
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

52
 

翻页函数可以参考ST例程库中

                                 I2C-E2prom例子中的Buffer_write()。里面就有根据用户需要写的起始地址和长度,以及目标芯片的page size处理如何split into好几个Page_write()来。
此帖出自stm32/stm8论坛
 
 
 

回复

88

帖子

0

TA的资源

一粒金砂(初级)

53
 

I2C的写

谢谢LZ:
在多种中断共存的情况下,不能顺利的写EEPROM,这个问题困惑我很久了。
我基本上把IAR和MDK自带的例程都试过了。LZ的三种方式也试过了。
在单独读写EEPROM时,所有的例程都能顺利通过。

我利用的万利改的IAR E5例程(里面有分页写的功能)加上其它中断就挂了。
也把查询、中断、DMA方式都试了一下,还是不行。手边没有示波器,问题也难找。

我感到STM32写FLASH,EEPROM,SD,如果和其它中断一起用,还是头疼的事。肯定是整个资源的配置上不合理造成的。但苦于没找到解决问题的办法。如果LZ有时间的话,能不能留个其他的请教办法给我?在坛子里有些困难。

我是试验把USART中断收到的数据转存到EEPROM中 ,发现写EEPROM有点难。
此帖出自stm32/stm8论坛
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

54
 

联系方式已经短消息给你啦

对中断影响下的I2C通信问题,感兴趣

经过验证,发现通信失败是由有用户自己的程序造成的:代码越界了,无意中把slave addree这个变量给修改了。于是,后来在发起I2C通信,发送地址时,自然就是无法响应咯。

欢迎大家继续使用并验证I2C封装库,谢谢!
此帖出自stm32/stm8论坛
 
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

55
 

方法不全

                                 没区号.
此帖出自stm32/stm8论坛
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

56
 

re: bayi255 ,应该没有问题

这一段是说,当I2C写e2prom的操作完成后,开始以轮询的方式检查目标e2prom自己内部的写逻辑是否已经完成,姑且称这个后续检查为"check phase"。

由于之前的通信以stop结尾,所以check phase开始之前,要先检查总线是否空闲,才发送start。如果上个stop结束后,其他I2C主设备占用了总线,那么这个check phase就要等待别人完成。

这里这是CHECK_TIMEOUT为1秒,就是说,如果等待了1秒,总线还没有释放,就不用再检查刚才的目标e2prom是否完成内部写逻辑,因为它肯定已经完成了。于是整个写操作,返回。
此帖出自stm32/stm8论坛
 
 
 

回复

86

帖子

0

TA的资源

一粒金砂(初级)

57
 

请教lut1lut

                                 在你的DMA例程中,PV_flag_1 这个变量没有赋初值,按照程序应该初值为0,是这样吗?
此帖出自stm32/stm8论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

58
 

如何操作24C512的字节读写?

是不是在写偏移的时候,把那个偏移地址按照24C512的时序,把数据地址,写2遍,先写高8bit,再写低8bit。

我这样改了,好像还是不行。

  /* send offset if needed *///对于24C512这里增加一个地址
    if (offset != 0xffffffff)
    {
      HiByte=(offset>>8)&0xff;
      LiByte=offset&0xff;
      //先发高地址
      I2C_SendData(I2Cx, HiByte); 
      *(u32 *)0xe000e014 = SEND_DATA_TIMEOUT; //SysTick_SetReload(SEND_DATA_TIMEOUT);
      *(u32 *)0xe000e018 = 0;                 //SysTick_CounterCmd(SysTick_Counter_Clear);
      *(u32 *)0xe000e010 |= 1;                //SysTick_CounterCmd(SysTick_Counter_Enable);
      while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED) || I2C_OT));
      *(u32 *)0xe000e010 &= 0xfffffffe;       //SysTick_CounterCmd(SysTick_Counter_Disable);
      if (I2C_OT)
      {
        I2C_OT = FALSE;
        I2C_GenerateSTOP(I2Cx, ENABLE);
        while ((I2C1->CR1 & 0x200) == 0x200);   //wait while stop bit not cleared 
        if(I2C_GetFlagStatus(I2Cx, I2C_FLAG_AF)) 
          I2C_ClearFlag(I2Cx, I2C_FLAG_AF);
        return DATA_TIMEOUT;
      }

      //后发低地址
      I2C_SendData(I2Cx, LiByte); 
      *(u32 *)0xe000e014 = SEND_DATA_TIMEOUT; //SysTick_SetReload(SEND_DATA_TIMEOUT);
      *(u32 *)0xe000e018 = 0;                 //SysTick_CounterCmd(SysTick_Counter_Clear);
      *(u32 *)0xe000e010 |= 1;                //SysTick_CounterCmd(SysTick_Counter_Enable);
      while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED) || I2C_OT));
      *(u32 *)0xe000e010 &= 0xfffffffe;       //SysTick_CounterCmd(SysTick_Counter_Disable);
      if (I2C_OT)
      {
        I2C_OT = FALSE;
        I2C_GenerateSTOP(I2Cx, ENABLE);
        while ((I2C1->CR1 & 0x200) == 0x200);   //wait while stop bit not cleared 
        if(I2C_GetFlagStatus(I2Cx, I2C_FLAG_AF)) 
          I2C_ClearFlag(I2Cx, I2C_FLAG_AF);
        return DATA_TIMEOUT;
      } 
    }
此帖出自stm32/stm8论坛
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

59
 
看来,主要还是在读数据的时候,读一个字节、读两个字节、读三个字节的状态检测位不一样
这个设计也真是厉害,一般人哪里搞得懂
此帖出自stm32/stm8论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

60
 
i2c_comm.c 584行有个bug
while ((I2C1->CR1 & 0x200) == 0x200);  //应该是 while ((I2Cx->CR1 & 0x200) == 0x200);
此帖出自stm32/stm8论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 2/10 下一条
ADI &文晔 探索季第一站,邀您在活动帖跟帖,ADI资深工程师将与您一道寻求解决之道! ...
春晚,最出圈当属穿着棉马甲跳秧歌的机器人”秧Bot”。
转手绢、飞手绢、变换队形,精准度和稳定性甚至超越人类,这背后少不了电机控制技术。

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表