硬件I2C从机通讯,偶尔发生错误:主机发起读操作,从机在向外吐数据,然后在某个SCL为高的时刻,SDA发生翻转。导致出现STOP信号,通讯出错。
初始化代码
GPIO_InitTypeDef IICGPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
RCC_APB2PeriphClockCmd(GPIO_CLK, ENABLE);
IICGPIO_InitStructure.GPIO_Pin = SCL_GPIO_PIN | SDA_GPIO_PIN;
IICGPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
IICGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SCL_GPIO_PORT, &IICGPIO_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
I2C_DeInit(I2C2);
//I2C2 configuration
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = SMB_SLAVE_ADDR;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 100000;
I2C_Init(I2C2, &I2C_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = I2C2_EV_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = I2C2_ER_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
I2C_ITConfig(I2C2, I2C_IT_BUF | I2C_IT_EVT | I2C_IT_ERR, ENABLE);
I2C_Cmd(I2C2, ENABLE);
不知道你这个问题是否已经解决, 如果还没有解决的话:在上述代码中,你已经完成了硬件I2C从机的初始化配置。然而,在处理偶尔出现的通讯错误时,你可能需要在初始化代码的基础上进行进一步的优化和调试。以下是一些建议来解决这个问题:
确认硬件连接:首先,请确保硬件连接没有问题。检查SDA和SCL线是否正确连接到从机设备。
降低时钟速率:尝试将I2C时钟速率降低,比如减少到50 kHz。降低时钟速率可以增加通讯的稳定性。
I2C_InitStructure.I2C_ClockSpeed = 50000; // 50 kHz
I2C_InitStructure.I2C_Ack = I2C_Ack_Disable;
检查从机设备:确认从机设备是否正常工作,并且其响应主机请求的正确性。可以通过连接其他主机或使用逻辑分析仪等工具来检查从机设备的响应情况。
添加延时:在从机向外输出数据时,尝试在SCL高电平期间添加一个适当的延时,以确保SDA线的稳定性。
添加I2C中断处理函数:实现I2C2_EV_IRQHandler和I2C2_ER_IRQHandler中断处理函数,用于处理I2C事件和错误。在这些中断处理函数中,您可以进一步调试通讯错误并进行错误处理。
检查I2C总线的负载:确保I2C总线上连接的设备负载合理,避免超出I2C总线的驱动能力范围。
检查其他中断:如果在I2C通讯中使用了其他中断,例如DMA中断等,请确保它们的优先级设置正确,以避免干扰I2C中断的正常处理。
检查主机和从机之间的通讯协议:确认主机和从机之间的通讯协议是否正确,并符合硬件设备的规格要求。
请注意,解决硬件I2C通讯问题可能需要一定的调试和排查过程。建议逐步尝试上述建议,并在每次更改后仔细测试和验证通讯的稳定性和正确性。在必要时,你可以使用逻辑分析仪等工具来监测I2C信号的波形,以进一步帮助你定位问题所在。