HaviG 2026-01-06 16:57 采纳率: 66.7%
浏览 1

STM32的I2C 使用问题

STM32使用I2C1,通过PB67可以正常调用PCA9685,输出信号控制LED(这里没有接上拉电阻也可以);但是把接口切换到I2C2,PB10和PB11,pca9685就不能工作是什么原因(这里先是用上拉电阻4.7KΩ,不能使用,1.5KΩ 也不行电阻在这里是并联在SCL和SDA上的,即:PB10--4.7kΩ--3.3V,PB10--PCA9685.SCL;PB11--4.7kΩ--3.3V,PB11--PCA9685.SDA)?查了资料说,I2C1内置有上拉电阻,不用上拉也能使用,I2C2没有上拉电阻,我配置了上拉还是不行;我感觉大概率是配置I2C初始化的问题,但是检查了代码感觉代码也没问题?下边是I2C的初始化代码,这里的注释还没改,只是先把代码改了

// I2C初始化
void I2C_Configuration(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    I2C_InitTypeDef I2C_InitStructure;
    
    // 使能GPIOB和I2C1时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
    
    // 配置I2C1引脚:PB6-SCL, PB7-SDA
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;  // 开漏输出
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    
    // I2C1配置
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = 0x00;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_ClockSpeed = 100000;  // 100kHz
    
    I2C_Init(I2C2, &I2C_InitStructure);
    I2C_Cmd(I2C2, ENABLE);
}

  • 写回答

2条回答 默认 最新

  • 檀越@新空间 2026-01-06 16:58
    关注

    下午好🌅🌅🌅
    本答案参考通义千问

    你提到的问题是关于STM32的I2C接口在使用I2C1和I2C2时的行为差异,特别是在切换到I2C2后无法正常与PCA9685通信。以下是可能的原因及解决方案


    一、问题分析

    1. I2C1与I2C2的硬件差异

    • I2C1:某些STM32系列(如STM32F103)的I2C1引脚默认配置为开漏输出,并且内置上拉电阻,因此即使不接外部上拉电阻也可以工作。
    • I2C2:通常没有内置上拉电阻,必须通过外部上拉电阻(如4.7kΩ或1.5kΩ)来确保信号稳定。

    2. 代码中可能存在的错误

    • 你提到代码中注释未更新,但实际代码中使用的是I2C2,这可能导致理解上的混淆。
    • 你的代码中RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);是正确的,但需要确认是否在初始化前调用了该函数。
    • GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; 是正确的,但需确认PB10和PB11是否被正确配置为I2C2的SCL和SDA引脚(不同型号可能有差异)。

    3. 上拉电阻的配置问题

    • 你提到已经连接了上拉电阻,但仍然无法工作。可能是:
      • 上拉电阻值不合适(建议使用4.7kΩ);
      • 上拉电阻连接方式错误(应并联在SCL/SDA与3.3V之间);
      • 上拉电阻损坏或接触不良。

    4. I2C模式配置问题

    • 你使用的GPIO_Mode_AF_OD是开漏输出,这是正确的配置,但需确保I2C外设也处于正确的模式(如I2C_Mode_I2C)。
    • 检查是否启用了I2C的ACK功能(I2C_Ack = I2C_Ack_Enable),否则可能导致通信失败。

    二、解决方案

    1. 检查并修正I2C2的初始化代码

    确保以下几点:

    • 正确启用I2C2的时钟;
    • 正确配置PB10(SCL)和PB11(SDA)为开漏输出;
    • 使用合适的I2C参数(如时钟频率、占空比等)。

    修改后的代码如下

    // I2C初始化
    void I2C_Configuration(void) {
        GPIO_InitTypeDef GPIO_InitStructure;
        I2C_InitTypeDef I2C_InitStructure;
    
        // 使能GPIOB和I2C2时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
    
        // 配置I2C2引脚:PB10-SCL, PB11-SDA
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;  // 开漏输出
        GPIO_Init(GPIOB, &GPIO_InitStructure);
    
        // I2C2配置
        I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
        I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; // 根据具体需求调整
        I2C_InitStructure.I2C_OwnAddress1 = 0x00;
        I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
        I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
        I2C_InitStructure.I2C_ClockSpeed = 100000;  // 100kHz
    
        I2C_Init(I2C2, &I2C_InitStructure);
        I2C_Cmd(I2C2, ENABLE);
    }
    

    注意:如果你使用的是STM32F4或其他系列,请确认PB10和PB11是否支持I2C2功能。部分型号可能需要使用其他引脚(如PA14/PA15)作为I2C2的SCL/SDA。


    2. 确保上拉电阻正确连接

    • 上拉电阻应并联在SCL和SDA与3.3V之间,而不是直接连接到GPIO引脚。
    • 常用阻值为 4.7kΩ,避免使用过小的电阻(如1.5kΩ)导致电流过大或不稳定。

    3. 检查PCA9685的地址和通信协议

    • 确认PCA9685的I2C地址是否为0x40(默认地址)。
    • 使用逻辑分析仪或示波器检查SCL和SDA信号是否正常。
    • 如果使用I2C扫描工具(如I2C Scanner)检测设备是否存在,可以快速判断是否是通信问题。

    4. 添加I2C调试信息

    • 在发送数据前后打印状态寄存器,查看是否有错误标志(如I2C_GetFlagStatus(I2C2, I2C_FLAG_BTF))。
    • 如果使用标准库,可以添加如下调试代码:
    if (I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_ADDRESS_ACKNOWLEDGED)) {
        // 地址响应成功
    } else {
        // 地址响应失败
    }
    

    三、总结

    | 问题点 | 解决方案 | |--------|----------| | I2C2无内部上拉电阻 | 必须外接4.7kΩ上拉电阻 | | 引脚配置错误 | 确认PB10和PB11为I2C2的SCL和SDA | | 初始化代码错误 | 修正代码中的注释和配置 | | 通信协议问题 | 检查PCA9685地址和通信协议 | | 信号稳定性问题 | 使用示波器或逻辑分析仪检测SCL/SDA波形 |


    如果以上方法仍无法解决问题,建议使用逻辑分析仪或I2C调试工具进一步排查信号是否正常。希望这些内容能帮助你定位问题!

    评论

报告相同问题?

问题事件

  • 创建了问题 1月6日