I2C外接FM24CL64存储器,100KHZ的速度读写;用JLINK仿真器在全速运行时一切正常。如果设置断点在程序中,I2C总线出错;但是后来我重新初始化I2C总线后BUSY位一直有效,检查到SDA引脚一直是低电平;但是我尝试把FM24CL64的VCC电源关闭,问题依旧,不知道怎么回事?
总线出错后我都会对I2C总线重新初始化,但是SDA引脚一直是低电平。
SDA引脚一直是低电平,很可能是外部设备拉低了总线。
外部设备还在等待时钟,设置断点,中断了一次I2C操作的过程,造成外设拉低总线。
我对FM24CL64进行了重新上电,SDA引脚一直还是低电平,现在都不知道该如何处理这个麻烦事了。
最简单的办法是系统重新上电,即STM32与外部设备同时断电再上电。
我现在的方法是CPU上电后控制FM24CL64后上电,先将CPU的I2C端口设置为普通IO口对24CL64进行复位后,再把端口配置成为I2C模式,进行正常的读写;如果出错后重复上面的步骤。不过这个I2C总线上拉4.7k的电阻、400KHZ、单次读写16字节时通讯的时候出错的概率10%,而且好像一次读写数据多出错的概率会大一点;100KHZ的时候基本上100%正确。
主要就是接收完最后1个字节之前需要先使能非应答以及停止位;我觉得可能是这里有问题,这个是我读EEPROM时候的代码,帮忙看看。
ErrorStatus I2cRecToBuff( u8* buf,u16 Len )
{
do{
if( 1 == Len )
{
I2C_AcknowledgeConfig(I2C1, DISABLE);
I2C_GenerateSTOP(I2C1, ENABLE);
}
if( I2cWaitEvent(I2C_EVENT_MASTER_BYTE_RECEIVED) == SUCCESS )
{
Len--;
*buf++ = I2C_ReceiveData(I2C1);
}
else
{
I2C_AcknowledgeConfig(I2C1, ENABLE);
I2C_GenerateSTOP(I2C1, ENABLE);
return ERROR;
}
}while(Len);
I2C_AcknowledgeConfig(I2C1, ENABLE);
return SUCCESS;
}