STM32
直播中

zhongnian

8年用户 1363经验值
擅长:MEMS/传感技术
私信 关注
[问答]

IIC总线一直忙是怎么回事?

我用IIC写东西,仅仅是写,读都不要,初始化的时候直接写,却一开始就总线忙(风驰里面的IIC代码),具体如下:
<1>main    /*************/                    (大概就是这意思,工程太大,我把主要涉及的搬上来)
{INIT_TAS5756();}           
<2>   void INIT_TAS5756(void) //初始化从器件
{
        I2C_MASTERMODE_Init(STANDARDSPEED); //初始化IIC
        u8NumOfReg = sizeof(tas5756_LR_init)/sizeof(Struct_Tas5756);  
        for(i=0;ivoid I2C_MASTERMODE_Init(I2C_SpeedMode_TypeDef I2C_Speed) //IIC的初始化函数
{
        I2C_Init(I2C_Speed, I2C1_SLAVE_ADDRESS7, I2C_DUTYCYCLE_2,
                I2C_ACK_CURR, I2C_ADDMODE_7BIT, CLK_GetClockFreq()/1000000);        
        I2C_Cmd(ENABLE);
}
<4>void I2C_EERROM_WriteOnePage(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)   //IIC写的函数
{
    /* 等待空闲 */
    while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));     //什么都没干,这一句就卡住了

    /* 发起始位 */
    I2C_GenerateSTART(ENABLE);

    /* 测试EV5 ,检测从器件返回一个应答信号*/
    while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));

    /* 设置I2C从器件地址,I2C主设备为写模式*/
    I2C_Send7bitAddress(WriteAddr, I2C_DIRECtiON_TX);

  //I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_TX);
    /* 测试EV6 ,检测从器件返回一个应答信号*/
    while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));


    //I2C_SendData((u8)(WriteAddr));
    /* 测试EV8 ,检测从器件返回一个应答信号*/
    while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));  

    /* 不断往从设备写数据*/
    while(NumByteToWrite--)  
    {

      I2C_SendData(*pBuffer);

      /*指针指向下一个地址*/
      pBuffer++;

      /* 测试EV6 ,检测从器件返回一个应答信号*/
      while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
      I2C_AcknowledgeConfig(I2C_ACK_CURR);
    }

    /* 发结束位*/
    I2C_GenerateSTOP(ENABLE);
}

<5>FlagStatus I2C_GetFlagStatus(I2C_Flag_TypeDef I2C_Flag)  //总线忙的函数,就是卡在这
{
  uint8_t tempreg = 0;
  uint8_t regindex = 0;
  FlagStatus bitstatus = RESET;

  /* Check the parameters */
  assert_param(IS_I2C_FLAG_OK(I2C_Flag));

  /* Read flag register index */
  regindex = (uint8_t)((uint16_t)I2C_Flag >> 8);
  /* Check SRx index */
  switch (regindex)
  {
      /* Returns whether the status register to check is SR1 */
    case 0x01:
      tempreg = (uint8_t)I2C->SR1;
      break;

      /* Returns whether the status register to check is SR2 */
    case 0x02:
      tempreg = (uint8_t)I2C->SR2;
      break;

      /* Returns whether the status register to check is SR3 */
    case 0x03:
      tempreg = (uint8_t)I2C->SR3;
      break;

    default:
      break;
  }

  /* Check the status of the specified I2C flag */
if ((tempreg   (uint8_t)I2C_Flag ) != 0)
  {
    /* Flag is set */
    bitstatus = SET;    //只能跑到这了,
  }
  else
  {
    /* Flag is reset */
    bitstatus = RESET;   //一直到不了这个,iic一直忙
  }
  /* Return the flag status */
  return bitstatus;
}

回帖(1)

kasdlak

2024-5-11 17:19:41
I2C总线一直忙的原因可能有以下几点:

1. 总线冲突:在I2C总线上可能存在多个设备,如果它们同时尝试通信,可能会导致总线忙。确保其他设备没有在相同时间进行通信。

2. 硬件问题:检查I2C总线连接是否正确,以及是否有短路或断路的情况。

3. 软件问题:检查I2C初始化和通信代码是否正确。以下是一些建议:

   a. 确保I2C初始化函数(如I2C_MASTERMODE_Init)正确设置I2C速率、时钟等参数。

   b. 在初始化函数中,检查是否正确设置了I2C从设备的地址。

   c. 在写入数据之前,确保I2C总线处于空闲状态。可以使用I2C_IsBusBusy()函数检查。

   d. 在写入数据时,确保使用正确的I2C通信协议,如I2C_Write()或I2C_MasterWrite()。

4. 从设备问题:检查从设备(如TAS5756)是否正常工作,以及其地址和通信协议是否与主设备匹配。

5. 电源问题:确保I2C总线上的所有设备都有足够的电源供应。

针对您提供的代码片段,我建议您:

1. 检查I2C_MASTERMODE_Init函数中的参数设置,确保它们正确无误。

2. 在INIT_TAS5756函数中,添加I2C_IsBusBusy()检查,确保总线空闲后再进行通信。

3. 如果可能,请提供更完整的代码,以便更准确地诊断问题。

4. 如果问题仍然存在,尝试使用其他I2C通信库或示例代码,以排除库本身的问题。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分