I2C上拉电阻问题分析(基于stm32 HAL库)

I2C上拉电阻问题分析(基于stm32 HAL库)

在使用stm32读写 ST温湿度hts221时,使用I2C总线,总线上还挂在了别的传感器,发现有时候可以读出数据,有时候读不出数据,一直是0。
首先,stm32 配置I2C IO时,使用的是AF_OD,即使用复用开漏输出,这也是官方I2C所要的方式,电流电压取决于外部电路。同时IO也配置了内部上拉。

/**
  * @brief I2C MSP Initialization 
  *        This function configures the hardware resources used in this example: 
  *           - Peripheral's clock enable
  *           - Peripheral's GPIO Configuration  
  *           - DMA configuration for transmission request by peripheral 
  *           - NVIC configuration for DMA interrupt request enable
  * @param hi2c: I2C handle pointer
  * @retval None
  */
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{
    GPIO_InitTypeDef  GPIO_InitStruct;
    RCC_PeriphCLKInitTypeDef  RCC_PeriphCLKInitStruct;

    /*##-1- Configure the I2C clock source. The clock is derived from the SYSCLK #*/
    RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C1;
    RCC_PeriphCLKInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_SYSCLK;
    HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);
    __I2C1_CLK_DISABLE();
    /*##-2- Enable peripherals and GPIO Clocks #################################*/
    /* Enable GPIO TX/RX clock */
    I2C1_SCL_GPIO_CLK_ENABLE();
    I2C1_SDA_GPIO_CLK_ENABLE();
     /* Enable I2Cx clock */
    I2C1_CLK_ENABLE(); 
    /*##-3- Configure peripheral GPIO ##########################################*/  
    /* I2C TX GPIO pin configuration  */
    GPIO_InitStruct.Pin       = I2C1_SCL_PIN;
    GPIO_InitStruct.Mode      = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull      = GPIO_PULLUP;
    GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = I2C1_SCL_SDA_AF;
    HAL_GPIO_Init(I2C1_SCL_GPIO_PORT, &GPIO_InitStruct);

    /* I2C RX GPIO pin configuration  */
    GPIO_InitStruct.Pin       = I2C1_SDA_PIN;
    GPIO_InitStruct.Alternate = I2C1_SCL_SDA_AF;
    HAL_GPIO_Init(I2C1_SDA_GPIO_PORT, &GPIO_InitStruct);
}

查看硬件原理图,I2C总线外部也使用了上拉电阻。而最终的问题就在于这里。
I2C上拉电阻问题分析(基于stm32 HAL库)_第1张图片
刚开始没有在意这个上拉的阻值,通过使用逻辑分析仪发现,当不工作的时候,I2C的时钟一直是处于低电平,猜测这个10K可能有点大,因为芯片的供电电压是2.5V,一般要求上拉电阻不宜小于1K,不宜大于10K。
当时手头上没有合适的电阻,于是把I2C的 IO输出改为AF_PP,即使用复用推完输出,这时候发现可以正常工作了,证明了自己的猜测,这部分的上拉电阻太大了。
经过测试,把上拉电阻换成3.9K,还是不能正常工作,当换成1K时,可以正常工作了。
I2C规定,标准模式,100Kbps总线的负载最大容限<=400pF;快速模式,400Kbps总线的负载最大容限<=200pF,至于如何计算,后面再来讨论。

你可能感兴趣的:(物联网,stm32)