yzy1 发表于 2025-6-11 18:20

KF32F330KQV芯片的I2C无法进行通信

按照芯片手册说明,在发起Start的时候标志位ISIF会置1,但是我在执行以下函数的时候会卡死在判断条件这里:// 清除I2C中断标志
    I2C_Clear_INTERRUPT_Flag(I2C0_SFR);
    // 启用I2C
    I2C_Cmd(I2C0_SFR, TRUE);
    // 生成I2C起始信号
    I2C_Generate_START(I2C0_SFR, TRUE);
    // 等待中断标志置位
    while (!I2C_Get_INTERRUPT_Flag(I2C0_SFR))
      ;
清除中断标志后启动I2C,在生成起始信号,按照芯片手册所描述应该会生成中断标志,但是在while循环这里死循环了,我使用的代码是官方提供的i2c eeprom的代码,

yzy1 发表于 2025-6-11 18:25

而且,我在调试模式下查看对应的寄存器器的值是没有问题的,代码配置如下:
#define I2C0_DRIVER_SFR      (GPIOC_SFR)
#define I2C0_DRIVER_SCL_PIN(GPIO_PIN_MASK_11)
#define I2C0_DRIVER_SDA_PIN(GPIO_PIN_MASK_12)
#define I2C0_DRIVER_RMP      (GPIO_RMP_AF8_I2C0)

void i2cDriver_Init(I2C_SFRmap *I2Cx, i2c_dirver_clk_t clk)
{
I2C_InitTypeDef I2C_InitStruct; // 定义I2C初始化结构体
GPIO_InitTypeDef I2C_GPIO_InitStruct; // 定义GPIO初始化结构体
I2C_GPIO_InitStruct.m_Mode = GPIO_MODE_RMP;                                 // 配置GPIO重映射功能
      I2C_GPIO_InitStruct.m_OpenDrain = GPIO_POD_OD;                              // GPIO开漏输出
      I2C_GPIO_InitStruct.m_Speed = GPIO_HIGH_SPEED;                              // IO配置为高速
      I2C_GPIO_InitStruct.m_Pin = I2C0_DRIVER_SCL_PIN | I2C0_DRIVER_SDA_PIN;      // Px11 Px12
      I2C_GPIO_InitStruct.m_PullUp = GPIO_PULLUP;                                 // 配置GPIO上拉
      I2C_GPIO_InitStruct.m_PullDown = GPIO_NOPULL;                               // 不使能GPIO下拉
      GPIO_Pin_RMP_Config(I2C0_DRIVER_SFR, I2C0_DRIVER_SCL_PIN, I2C0_DRIVER_RMP); // 配置PC11为I2C0 SCL
      GPIO_Pin_RMP_Config(I2C0_DRIVER_SFR, I2C0_DRIVER_SDA_PIN, I2C0_DRIVER_RMP); // 配置PC12为I2C0 SDA
      GPIO_Configuration(I2C0_DRIVER_SFR, &I2C_GPIO_InitStruct);                  // 配置GPIO
I2C_Reset(I2Cx);                                 // 复位I2C外设
    I2C_InitStruct.m_Mode = I2C_MODE_I2C;            // 设置I2C模式为I2C
    I2C_InitStruct.m_ClockSource = I2C_CLK_SCLK;       // 选择SCLK作为时钟源,频率为120M
    I2C_InitStruct.m_BADR10 = I2C_BUFRADDRESS_7BIT;    // 配置7位从机地址
    I2C_InitStruct.m_MasterSlave = I2C_MODE_SMBUSHOST; // 设置SMBus类型为主机模式
I2C_InitStruct.m_BaudRateL = 89; // 设置I2C波特率低电平时间周期,值不能小于3
      I2C_InitStruct.m_BaudRateH = 89; // 设置I2C波特率高电平时间周期,值不能小于3
I2C_InitStruct.m_AckEn = TRUE;            // 使能应答
    I2C_InitStruct.m_AckData = I2C_ACKDATA_ACK; // 选择应答信号为ACK

    I2C_Configuration(I2Cx, &I2C_InitStruct); // 配置I2C外设

    I2C_Cmd(I2Cx, TRUE);            // 使能I2C模块
    I2C_Clear_INTERRUPT_Flag(I2Cx); // 清I2C中断标志位
}

因为KF32F330的主频是72M,所以重新计算了400k的时钟周期

钟爱柳州 发表于 2025-6-13 08:42

看看硬件连接图,示波器或逻辑分析仪抓一下SDA和SCL信号

钟爱柳州 发表于 2025-6-13 08:52

/**
*   ##### 通用输入输出端口(GPIO)重映射配置函数 #####
*/
/**
* 描述配置GPIO端口引脚重映射。
* 输入GPIOx: 指向GPIO内存结构的指针,取值为GPIOA_SFR~GPIOH_SFR。
*       GpioPinNum: 指定端口引脚,取值为GPIO_Pin_Num_0~GPIO_Pin_Num_15中的一个
**/
void GPIO_Pin_RMP_Config (GPIO_SFRmap* GPIOx, uint16_t GpioPinNum, uint8_t PinRemap)
这个函数的第二个参数是uint16_t GpioPinNum

而你的源代码是GPIO_PIN_MASK_11,重映射错了,将宏改一下再试试:
#define I2C0_DRIVER_SCL_PIN(GPIO_Pin_Num_11)
#define I2C0_DRIVER_SDA_PIN(GPIO_Pin_Num_12)
页: [1]
查看完整版本: KF32F330KQV芯片的I2C无法进行通信