打印
[应用相关]

关于i2c完全没用,很不可靠

[复制链接]
5256|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kq800|  楼主 | 2008-8-15 22:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用i2c读写24c512,好不容易可以读写了,但是不能长期可靠运行.发现一个致命问题,只要外部sda线为0,STM32的I2C就不要想工作了,不管芯片复位,i2c都没法工作,只有一个办法,关掉电源,等一段时间启动.stm32的i2c只要判断SDA为0,busy就始终为1.i2c就不会工作了.
沙发
McuPlayer| | 2008-8-15 22:17 | 只看该作者

不会吧,我用得还可以

我后期板子转SPI Flash了,大容量EEPROM比较贵。
但是STM32读写24芯片没有什么问题,我用的也是24C412。

另外现在24芯片很多山寨片,采购的时候注意些。

使用特权

评论回复
板凳
香水城| | 2008-8-15 22:18 | 只看该作者

楼主见过哪一款单片机在I2C总线被外部设备拉低后还能正常

你最好仔细地看看I2C的协议。

使用特权

评论回复
地板
dragon_hn| | 2008-8-15 22:25 | 只看该作者

楼主应该是程序问题

楼主太偏激了.应该是程序问题,当然也可能是STM32问题(没用过).I2C协议经过了那么多厂家和芯片的考验,不会有问题的.

使用特权

评论回复
5
john_light| | 2008-8-16 10:56 | 只看该作者

I2C总线只要任何一条线非高,总线肯定处于忙状态。

任何一个主设备都不允许(也不可能)发起START条件。

使用特权

评论回复
6
kq800|  楼主 | 2008-8-16 10:58 | 只看该作者

我用的24c512通过软件已经可以可靠运行了.

没有采用stm32的i2c,有两个可能性,所以最好不要用stm32的i2c读取24c之类的芯片.第一个就是24c系列在读取过程中,例如SDA输出0时,stm32由于多种原因中断退出,致使SDA始终为0而且24c不会释放SDA,这样stm32复位再启动BUSY一直有效,接下来stm32的i2c就不会工作了.第二个就是stm32的i2c例程和库都只是示例,不能实用.例如示例是去比较EV5,EV8之类的信号,我看了stm32的库文件就是简单的把SR1,SR2读出然后和定义的EV条件比较,只要不等就死.而SR1,SR2表示的状态很全面,例如在EV5时BTF标志有效,那就要死机.所以有以上两种问题我就干脆放弃了,软件构成读写24c很可靠,毕竟是做产品还是可靠为第一.

使用特权

评论回复
7
kq800|  楼主 | 2008-8-16 11:09 | 只看该作者

附上i2c读写24c的程序参考,基本上按照开发板上示例搬来的.

附上i2c读写24c的程序参考,基本上按照开发板上示例搬来的.

ErrorStatus I2C_24c16_Status(void)
{
  u32 I2C_TimeOut = 0x3FFFF;

  /* Clear the I2C1 AF flag */
  I2C_ClearFlag(I2C1, I2C_FLAG_AF);

  /* Enable I2C1 acknowledgement if it is already disabled by other function */
  I2C_AcknowledgeConfig(I2C1, ENABLE);

  /*----- Transmission Phase -----*/
  
  /* Send I2C1 START condition */
  I2C_GenerateSTART(I2C1, ENABLE);
  
  /* Test on I2C1 EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))  /* EV5 */
  {
  }
  //I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT);
  /* Send STLM75 slave address for write */
  I2C_Send7bitAddress(I2C1, AT24C512_Addr, I2C_Direction_Transmitter);
  
  while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) && I2C_TimeOut)/* EV6 */
  {
    I2C_TimeOut--;
  }

  if(I2C_GetFlagStatus(I2C1, I2C_FLAG_AF) != 0x0)
  {
    return ERROR;
  }
  else
  {
    return SUCCESS;
  }
}



/*******************************************************************************
* Function Name  : Read24c16
* Description    : Displays the temperature in Celsius and fahrenheit degree.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void Read24c16(u8 *RamAddress,u16 RomAddress,u8 bytes)
{
    

    
    if(I2C_24c16_Status() == SUCCESS)
  {
      I2C_SendData(I2C1, (u8)(RomAddress >> 8));
  
  /* Test on I2C1 EV8 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) /* EV8 */
  {
  }
  I2C_SendData(I2C1, (u8)(RomAddress &0xff));
  
  /* Test on I2C1 EV8 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) /* EV8 */
  {
  }
  /*----- Reception Phase -----*/
  /* Send Re-STRAT condition */
  I2C_GenerateSTART(I2C1, ENABLE);
  
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))  /* EV5 */
  {
  }
  
  /* Send STLM75 slave address for read */
  I2C_Send7bitAddress(I2C1, AT24C512_Addr, I2C_Direction_Receiver);
  
  /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))  /* EV6 */
  {
  }

  /* Test on EV7 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))  /* EV7 */
  {
  }
  
  /* Store I2C1 received data */
  while(bytes!=1) {
    *RamAddress=I2C_ReceiveData(I2C1);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))  /* EV7 */
  {
  }
    RamAddress++;
    bytes--;
    }
  
  /* Disable I2C1 acknowledgement */
  I2C_AcknowledgeConfig(I2C1, DISABLE);
  
  /* Send I2C1 STOP Condition */
  I2C_GenerateSTOP(I2C1, ENABLE);
  
  /* Test on EV7 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))  /* EV7 */
  {
  }
  
  /* Store I2C1 received data */
   
   *RamAddress=I2C_ReceiveData(I2C1);
  /* Return Temperature value */
  
   }
   
  }
void Write24c16(u8 *Wdata,u16 RomAddress,u8 bytes)
{
    
    if(I2C_24c16_Status() == SUCCESS)
  {
      I2C_SendData(I2C1, (u8)(RomAddress >> 8));
  
  /* Test on I2C1 EV8 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) /* EV8 */
  {
  }
  I2C_SendData(I2C1, (u8)(RomAddress &0xff));
  
  /* Test on I2C1 EV8 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) /* EV8 */
  {
  }
  for(;bytes!=0;bytes--) {
//        Write8Bit(*Wdata);
     I2C_SendData(I2C1, *Wdata++);
  
  /* Test on I2C1 EV8 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) /* EV8 */
  {
  }
        
        
    }
    
    
  
  /* Send I2C1 STOP Condition */
  I2C_GenerateSTOP(I2C1, ENABLE);
  Delay(10);
       }
  }

使用特权

评论回复
8
dfftt133| | 2008-8-19 14:08 | 只看该作者

关于i2c完全没用,很不可靠

SDA为什么会为0,为0的原因你找到啦吗,STM32为什么会退出,不解,你可以禁止到STM32 IIC再打开试试

使用特权

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

本版积分规则

9

主题

52

帖子

1

粉丝