STM32L151芯片进行I2C通信不稳定

2019-07-14 13:35发布

项目中使用的STM32L151这个芯片进行I2C通信总是不稳定,用使用过的吗?能帮我分析一下,谢谢。

现在的问题时:现在读数据是很多时候停在了while(!I2C_CheckEvent(sEE_I2C,  I2C_EVENT_MASTER_MODE_SELECT))这个位置。

有的时候还继续运行下去。

读取的数据只有一个字节,如果读取2个字节,第二个字节都是00。

void I2C_Init(void)
{
  GPIO_InitTypeDef   GPIO_InitStructure;
I2C_InitTypeDef  I2C_InitStructure;
   
  /*!<  sEE_I2C Periph clock enable */
  RCC_APB1PeriphClockCmd(sEE_I2C_CLK,  ENABLE);
  
  /*!< sEE_I2C_SCL_GPIO_CLK and sEE_I2C_SDA_GPIO_CLK Periph  clock enable */
  RCC_AHBPeriphClockCmd(sEE_I2C_SCL_GPIO_CLK |  sEE_I2C_SDA_GPIO_CLK, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  
  /*  Reset sEE_I2C peripheral */
  RCC_APB1PeriphResetCmd(sEE_I2C_CLK,  ENABLE);
  
  /* Release reset signal of sEE_I2C IP */
   RCC_APB1PeriphResetCmd(sEE_I2C_CLK, DISABLE);
   
  /*!< GPIO  configuration */  
  /* Connect PXx to I2C_SCL*/
   GPIO_PinAFConfig(sEE_I2C_SCL_GPIO_PORT, sEE_I2C_SCL_SOURCE,  sEE_I2C_SCL_AF);
  /* Connect PXx to I2C_SDA*/
  GPIO_PinAFConfig(sEE_I2C_SDA_GPIO_PORT,  sEE_I2C_SDA_SOURCE, sEE_I2C_SDA_AF);
  /*!< Configure sEE_I2C pins: SCL */   
   GPIO_InitStructure.GPIO_Pin = sEE_I2C_SCL_PIN;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
   GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
   GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
   GPIO_Init(sEE_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
  /*!< Configure sEE_I2C pins: SDA */
  GPIO_InitStructure.GPIO_Pin =  sEE_I2C_SDA_PIN;
  GPIO_Init(sEE_I2C_SDA_GPIO_PORT,  &GPIO_InitStructure);




  /*!< I2C configuration  */
  /* sEE_I2C configuration */
  I2C_InitStructure.I2C_Mode =  I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
   I2C_InitStructure.I2C_OwnAddress1 = I2C_SLAVE_ADDRESS7;
   I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
   I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
   I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
  
  /* sEE_I2C Peripheral  Enable */
  I2C_Cmd(sEE_I2C, ENABLE);
  /* Apply sEE_I2C configuration  after enabling it */
  I2C_Init(sEE_I2C, &I2C_InitStructure);
//   /* Enable the sEE_I2C peripheral DMA requests */
//    I2C_DMACmd(sEE_I2C, ENABLE);
}



uint8_t I2C_ReadNByte (uint8_t sla, uint32_t suba, uint8_t *s, uint32_t  num)
{
sEETimeout = sEE_FLAG_TIMEOUT;
  while(I2C_GetFlagStatus(I2C2,  I2C_FLAG_BUSY))
  {
    if((sEETimeout--) == 0) return sEE_FAIL;
   }

  I2C_GenerateSTART(sEE_I2C,  ENABLE);//------------------------------------------------------------
  
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(!I2C_CheckEvent(sEE_I2C,  I2C_EVENT_MASTER_MODE_SELECT))
  {
    if((sEETimeout--) == 0) return  sEE_FAIL;
  }
  
   I2C_Send7bitAddress(sEE_I2C, sla,  I2C_Direction_Transmitter);//----------------------------------------------
  /*!< Test on EV6 and clear it */
  sEETimeout =  sEE_FLAG_TIMEOUT;
  while(!I2C_CheckEvent(sEE_I2C,  I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if((sEETimeout--) ==  0) return sEE_FAIL;
  }
I2C_Cmd(I2C2, ENABLE);

   I2C_SendData(sEE_I2C, suba);               //-----------------------------

  sEETimeout =  sEE_FLAG_TIMEOUT;
  while(I2C_GetFlagStatus(sEE_I2C,  I2C_EVENT_MASTER_BYTE_TRANSMITTED) == RESET)
  {
    if((sEETimeout--) ==  0) return sEE_FAIL;
  }
  
  I2C_GenerateSTART(sEE_I2C,  ENABLE);   //---------------------------------------------------
  
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(!I2C_CheckEvent(sEE_I2C,  I2C_EVENT_MASTER_MODE_SELECT))
  {
    if((sEETimeout--) == 0) return  sEE_FAIL;
  }
  
   I2C_Send7bitAddress(sEE_I2C, sla+1, I2C_Direction_Receiver);   //-----------------------------------

sEETimeout =  sEE_FLAG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C,  I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) == RESET)
{
  if((sEETimeout--)  == 0) return sEE_FAIL;
}     

I2C_AcknowledgeConfig(sEE_I2C, DISABLE);

(void)sEE_I2C->SR2;

I2C_GenerateSTOP(I2C2,  ENABLE);

sEETimeout =  sEE_FLAG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C,  I2C_EVENT_MASTER_BYTE_RECEIVED) == RESET)
{
  if((sEETimeout--) == 0)  return sEE_FAIL;
}  

  do
  {   

    *s = I2C_ReceiveData(sEE_I2C);
   
    num--;        
   
    sEETimeout  = sEE_FLAG_TIMEOUT;
    while(sEE_I2C->CR1 & I2C_CR1_STOP)
     {
      if((sEETimeout--) == 0) return sEE_FAIL;
    }  
  
   }while(num!=0);

  I2C_AcknowledgeConfig(I2C2, ENABLE);
(void)sEE_I2C->SR2;

  return sEE_OK;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。