9787|27

70

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

str710iic错误 [复制链接]



我在用 str710 的iic 和 isl1208 rtc 芯片连接。 使用过程中发现上电时候出现 iic 总线错误的情况  

具体表象为  iic start 、发送从设备地址后,等待 I2C_ENDAD 死循环。
  /* Generate the START condition */
  I2C_STARTGenerate (I2C, ENABLE);
  /* Wait until SB bit is set */
  while (I2C_FlagStatus (I2C, DIRECT, I2C_SB )== RESET);
  /* Send the EEPROM address with LSB bit reset */
  I2C_AddressSend (I2C,DeviceADDRESS,I2C_Mode7, I2C_TX);
  /* Wait until ENDAD bit is set */  
  while (I2C_FlagStatus (I2C, DIRECT, I2C_ENDAD )== RESET); --》死机

检查寄存器发现:M/SL 被清零  ARLO 被置位。

iic 被从主模式改成了从模式。
此帖出自stm32/stm8论坛

最新回复

                                 我使用的是str710,在I2C上只带了一个时钟芯片:PCF8563,每秒读一次,短至几分钟,长至2天会出现死机,后来经过检查跟楼主主贴描述的情况完全一致:在发送完地址后,无法等到ENDAD。我100%肯定这个问题跟上电过程无关。我认为这是CPU 没有检测到ACK造成的,开始我想有可能是外设因为某种原因没有发出ACK,或者ACK被干扰了,但既然这个问题在楼主的设备里也出现了,应该基本可以断言是CPU本身的bug。至于变长参数,是标准C语言必须支持的,我不认为IAR的编译器会有问题。当然,我没有分析相关汇编代码,只是觉得不太可能!从实用的角度,程序员处理I2C的ACK异常是必须的,其实是手册中给出的通信流程误导了用户,好像每次通信都应该是正常的,好像可以死等ENDAD。只要明白I2C通信是会失败的,软件应该处理偶发的通信失败,那么这个问题实际上就不算什么严重的问题。   详情 回复 发表于 2007-10-6 17:27
点赞 关注
 

回复
举报

72

帖子

0

TA的资源

一粒金砂(初级)

沙发
 

没有人可以回答吗?

                                  
此帖出自stm32/stm8论坛
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

板凳
 

正在处理中。。。。

                                  
此帖出自stm32/stm8论坛
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

4
 

等待中ing

                                  
此帖出自stm32/stm8论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

5
 

iic 错误,调试实况

                                  
此帖出自stm32/stm8论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

6
 

发送地址前

                                  
此帖出自stm32/stm8论坛
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

7
 

等待中 2

                                  
此帖出自stm32/stm8论坛
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

8
 

图片检测

                                 根据你的图片,我对照我的调试,未能重现你的现象,我将将你的问题提交给欧洲的工程师。另外你能否另换一片芯片再测试一下。
此帖出自stm32/stm8论坛
 
 
 

回复

92

帖子

0

TA的资源

一粒金砂(初级)

9
 

它是偶尔出现的

它不是经常性出现的现象,一般在设备上电启动的比较容易出现。 而且,如果上电的时候出现了这样的错误,接下来我继续上电重启还是比较容易出现的。但是,当设备正常运行了,就不会出现这个问题。

我想要了解:
A、它是通过什么判断当前出现 ‘总线冲突’,
B、while (I2C_FlagStatus (I2C, DIRECT, I2C_ENDAD )== RESET);  I2C_ENDAD  在什么条件下被置位, 1、收到从设备的 ack信号。2、缓存中的数据发送完成。3、其他,请解释。

此帖出自stm32/stm8论坛
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

10
 

请楼主把这段程序编译后的汇编列表发给我们

同时把I2C_FlagStatus()函数的汇编列表发给我们。

怀疑是编译器在编译I2C_FlagStatus()函数时有问题。

这个函数中用到了可变参数表的技术,我们要确认不是由于你的编译器所造成的问题。

可发email到:mcu.china@st.com

谢谢


关于I2C_ENDAD的设置,在芯片资料的180页有这样的解释:
ENDAD: End of address transmission.
This bit is set by hardware when:
- 7-bit addressing mode: the address byte has been transmitted;
- 10-bit addressing mode: the MSB and the LSB have been transmitted during the addressing phase.
When the master needs to receive data from the slave, it has to send just the MSB of the slave address once again; hence the ENDAD flag is set, without waiting for the LSB of the address.It is cleared by software by reading SR2 and a following write to the CR or by hardware when the interface is disabled (PE=0).
0: No end of address transmission
1: End of address transmission

即当I2C地址发送完成后,此位置1。
此帖出自stm32/stm8论坛
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

11
 

可变参数

我也注意到了这个问题,这里是直接访问的I2C_FlagStatus (I2C, DIRECT, I2C_ENDAD )  函数里面做了判断做直接访问的时候和 可变参数无关。

另外 “在芯片资料的180页有这样的解释” 很含糊,只是讲发送完成会被置位。但是,没有解释arm 通过什么判断发送完成了。
此帖出自stm32/stm8论坛
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

12
 

汇编代码

/*******************************************************************************
* Function Name  : I2C_FlagStatus
* Description    : Checks whether any I2C Flag is set or not.
* Input          : I2Cx ( I2C0 or I2C1 )
*                  Access(DIRECT or INDIRECT)
*                  Flag : the flag to be read
*                  input 4: an (u8) variable needed in the case
*                                     of the INDIRECT access
* Return         : the NewState of the Flag (SET or RESET).
*******************************************************************************/
FlagStatus I2C_FlagStatus (I2C_TypeDef *I2Cx, RegisterAccess Access, I2C_Flags Flag, ...)
{
[0xe92d000f]   stmfd    r13!,{r0-r3}
[0xe92d4008]   stmfd    r13!,{r3,r14}
  u32 Tmp=0;
  
  if (Access == DIRECT)
[0xe1a02001]   mov      r2,r1
[0xe3520001]   cmp      r2,#1
[0xe59d1010]   ldr      r1,[r13,#0x10]
[0x1a000007]   bne      0x400087ec  ; (I2C_FlagStatus + 0x38)
    /* Store in Tmp variable the register where is located the flag */
    Tmp = I2C_GetStatus(I2Cx)&Flag;
[0xe0000001]   and      r0,r0,r1
[0xea000006]   b        0x40008808  ; (I2C_FlagStatus + 0x54)
  else
  { 
  /* Get the fourth register */
    va_list list;  
    
    va_start(list,Flag);
[0xe28d0014]   add      r0,r13,#0x14
[0xe58d0000]   str      r0,[r13,#0]
    Tmp = va_arg(list,u32);
[0xe59d2000]   ldr      r2,[r13,#0]
[0xe59d0014]   ldr      r0,[r13,#0x14]
[0xe2822004]   add      r2,r2,#4
[0xe58d2000]   str      r2,[r13,#0]
    Tmp&=Flag;
[0xe0000001]   and      r0,r0,r1
    // Tmp = ((u16)*((u32 *)&Flag + sizeof(Flag)))&Flag;
  }
  /* Return the Flag NewState */
  return Tmp != 0 ? SET : RESET;
[0xe3500000]   cmp      r0,#0
[0x0a000002]   beq      0x4000881c  ; (I2C_FlagStatus + 0x68)
[0xe3a00001]   mov      r0,#1
[0xe28dd004]   add      r13,r13,#4
......
[0xe3a00000]   mov      r0,#0
[0xeafffffb]   b        0x40008814  ; (I2C_FlagStatus + 0x60)
}
[0xe49df014]   ldr      pc,[r13],#0x14
此帖出自stm32/stm8论坛
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

13
 

STR710 IIC函数调用的错误

从你给出的编译结果看,在函数I2C_FlagStatus()中下面这行的调用I2C_GetStatus()不见了:
Tmp = I2C_GetStatus(I2Cx)&Flag;

另外,在(Access == INDIRECT)的处理可变参数表部分,编译结果似乎是对的。

我们正在修改函数I2C_FlagStatus()的内容,把DIRECT和INDIRECT部分分成两个函数,借此回避可变参数表的使用。不同的编译器对可变参数表有不同的处理,我们也发现IAR在这里的处理有问题;记得前几天有人也提出过类似的问题,好像麻烦不少;回避了可变参数表的使用,也就回避了编译器在这方面的缺陷。


关于芯片通过什么判断发送完成,可以参考174页的图;如Master发送地址的情况,参看7-bit Master transmitter部分EV6的说明,IIC模块是在收到Slave的Acknowledge后置位ENDAD为1。
此帖出自stm32/stm8论坛
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

14
 

修改I2C.c的函数

希望使用i2c的客户目前对I2C.c的函数进行修改,后期我们对I2C.c的函数的修改会在此进行通告。

去除掉i2c.c中的这个函数:FlagStatus I2C_FlagStatus (I2C_TypeDef *I2Cx, RegisterAccess Access, I2C_Flags Flag,...);

将应用程序中的I2C_FlagStatus( I2C1, DIRECT, I2C_SB)函数替换为下面的函数:
FlagStatus I2C_FlagStatus_1 (I2C_TypeDef *I2Cx, I2C_Flags Flag)
{
    return (I2C_GetStatus(I2Cx) & Flag) != 0 ? SET : RESET;        // Return the Flag NewState
}

将程序中的I2C_FlagStatus( I2C1, INDIRECT, I2C_AF, I2CStatus )函数替换为下面的函数:
FlagStatus I2C_FlagStatus_2 (I2C_TypeDef *I2Cx, I2C_Flags Flag, u32 cStatus)
{
    return (cStatus & Flag) != 0 ? SET : RESET;        // Return the Flag NewState
}
此帖出自stm32/stm8论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

15
 

I2C_GetStatus(I2Cx) 是 inline 的

I2C_GetStatus(I2Cx)  是 inline 的. 从看到的现象来判断,寄存器的值已经发生的改变,指示当前遇到总线冲突.并且,iic 返回到了默认的从模式.

要么是我们主板的布线问题,引起了干扰.  但如果是这样的话库函数的设计要修改下,while (I2C_FlagStatus (I2C, DIRECT, I2C_ENDAD )== RESET);  如果数据干扰的时候极其容易死机.
此帖出自stm32/stm8论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

16
 

还是觉得你的函数调用有问题

根据你提供的代码,在应该出现调用I2C_GetStatus()的地方,只有一条指令:
   Tmp = I2C_GetStatus(I2Cx)&Flag;
[0xe0000001]   and      r0,r0,r1

请问这里r0的值等于多少?你说I2C_GetStatus(I2Cx)是inline的,那么对应哪条指令呢?
此帖出自stm32/stm8论坛
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

17
 

interleave disassambly 显示不是很完整的

interleave disassambly 显示不是很完整的,下面才是真正的汇编码

I2C_FlagStatus    [0xe92d000f]   stmfd    r13!,{r0-r3}
400087b8    [0xe92d4008]   stmfd    r13!,{r3,r14}
400087bc    [0xe1a02001]   mov      r2,r1
400087c0    [0xe3520001]   cmp      r2,#1
400087c4    [0xe59d1010]   ldr      r1,[r13,#0x10]
400087c8    [0x1a000007]   bne      0x400087ec  ; (I2C_FlagStatus + 0x38)
400087cc    [0xe5d02000]   ldrb     r2,[r0,#0]
400087d0    [0xe5d03004]   ldrb     r3,[r0,#4]
400087d4    [0xe5d00008]   ldrb     r0,[r0,#8]
400087d8    [0xe1830400]   orr      r0,r3,r0,lsl #8
400087dc    [0xe3c00cc0]   bic      r0,r0,#0xc000
400087e0    [0xe1800702]   orr      r0,r0,r2,lsl #14
400087e4    [0xe0000001]   and      r0,r0,r1
400087e8    [0xea000006]   b        0x40008808  ; (I2C_FlagStatus + 0x54)
400087ec    [0xe28d0014]   add      r0,r13,#0x14
400087f0    [0xe58d0000]   str      r0,[r13,#0]
400087f4    [0xe59d2000]   ldr      r2,[r13,#0]
400087f8    [0xe59d0014]   ldr      r0,[r13,#0x14]
400087fc    [0xe2822004]   add      r2,r2,#4
40008800    [0xe58d2000]   str      r2,[r13,#0]
40008804    [0xe0000001]   and      r0,r0,r1
40008808    [0xe3500000]   cmp      r0,#0
4000880c    [0x0a000002]   beq      0x4000881c  ; (I2C_FlagStatus + 0x68)
40008810    [0xe3a00001]   mov      r0,#1
40008814    [0xe28dd004]   add      r13,r13,#4
40008818    [0xe49df014]   ldr      pc,[r13],#0x14
4000881c    [0xe3a00000]   mov      r0,#0
40008820    [0xeafffffb]   b        0x40008814  ; (I2C_FlagStatus + 0x60)
此帖出自stm32/stm8论坛
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

18
 

I2C_GetStatus(I2Cx) 缺少部分

inline u32 I2C_GetStatus(I2C_TypeDef *I2Cx)
{
  u8 i2c_cr, i2c_sr1,i2c_sr2;

  i2c_cr  = I2Cx->CR;
[0xe5d02000]   ldrb     r2,[r0,#0]
......
[0xe5d01000]   ldrb     r1,[r0,#0]
  i2c_sr1 = I2Cx->SR1;
[0xe5d03004]   ldrb     r3,[r0,#4]
......
[0xe5d02004]   ldrb     r2,[r0,#4]
  i2c_sr2 = I2Cx->SR2;
[0xe5d00008]   ldrb     r0,[r0,#8]
......
[0xe5d03008]   ldrb     r3,[r0,#8]

 return (((i2c_cr)<<14)|(i2c_sr1|(i2c_sr2<<8))&0x3FFF);
[0xe1830400]   orr      r0,r3,r0,lsl #8
[0xe3c00cc0]   bic      r0,r0,#0xc000
[0xe1800702]   orr      r0,r0,r2,lsl #14
......
[0xe1822403]   orr      r2,r2,r3,lsl #8
[0xe3c22cc0]   bic      r2,r2,#0xc000
[0xe1824701]   orr      r4,r2,r1,lsl #14
}
此帖出自stm32/stm8论坛
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

19
 

这个问题,欧洲那边有答案了没?

                                 这个问题还是存在的,现在只是用软件的方法在遇到这个问题的时候避开。但是,最好还是可以知道硬件上面引起这个错误的原因。
此帖出自stm32/stm8论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

20
 

楼主能否把这部分的电路图发上来

请用示波器看一下在出错时SDA和SCL线上波形;这种问题在软件上看不出,而你的硬件情况我们也看不见;在我们的板上没有发现你说的问题。

因为不能正确判断你的问题所在,我们不会把你的问题转到欧洲的工程师,除非涉及到芯片的问题。
此帖出自stm32/stm8论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
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
快速回复 返回顶部 返回列表