第二个我们发送的地址,然后判断了EV6事件,然后程序在这个while中卡死,这是为什么呢,实际上是因为EEPROM在这个时候还在写入数据,我们发送了这个地址过去,然后没有产生应答,所以在这里出现了问题。
所以我们要解决的问题就是,让数据写入以后才继续读取,最简单的放大是写一个延时函数
上代码
void SysTick_Init_ms(uint16_t x)
{
uint32_t i;
for(i=0;i<=x;i++);
}
int main()
{
USART_Configer();
printf("这是一个IIC通讯实验\n");
I2C_EEPROM_Configer();
I2C_EEPROM_Write_Byte(11 , 0x52);
SysTick_Init_ms(0xffff);
I2C_EEPROM_Write_Byte(12 , 0x55);
EEPROM_WaitForWriteEnd();
I2C_EEPROM_Read_Byte( 11, readData,2 );
printf("\r\n接收到数据为0x%x\r\n",readData[0]);
while(1)
{
}
}```
可以看到我们采取一个延时是没毛病的,这里我就不上结果的图了
第二个解决方法就是我们检测写入完成没有
void EEPROM_WaitForWriteEnd(void)
{
do
{
//产生起始信号
I2C_GenerateSTART(EEPROM_I2C,ENABLE);
while(I2C_GetFlagStatus (EEPROM_I2C,I2C_FLAG_SB) == RESET);
//EV5事件被检测到,发送设备地址
I2C_Send7bitAddress(EEPROM_I2C,0XA0,I2C_Direction_Transmitter);
}
while(I2C_GetFlagStatus (EEPROM_I2C,I2C_FLAG_ADDR) == RESET );
//EEPROM内部时序完成传输完成
I2C_GenerateSTOP(EEPROM_I2C,ENABLE);
}
或者把这段代码写到读取函数中
do
{
//产生起始信号
I2C_GenerateSTART(EEPROM_I2C,ENABLE);
while(I2C_GetFlagStatus (EEPROM_I2C,I2C_FLAG_SB) == RESET);
//EV5事件被检测到,发送设备地址
I2C_Send7bitAddress(EEPROM_I2C,0XA0,I2C_Direction_Transmitter);
}
while(I2C_GetFlagStatus (EEPROM_I2C,I2C_FLAG_ADDR) == RESET );
I2C_GenerateSTOP(EEPROM_I2C,ENABLE);
I2C_GenerateSTART(EEPROM_I2C,ENABLE); //产生起始信号
while(I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_MODE_SELECT) == ERROR); //检测EV5
I2C_Send7bitAddress(EEPROM_I2C,0XA0,I2C_Direction_Transmitter); //发送设备地址
while(I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)==ERROR); //检查EV6
I2C_SendData(EEPROM_I2C,addr); //发送到EEPROM哪一个位地址
while(I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_BYTE_TRANSMITTING) == ERROR);
//第二次
I2C_GenerateSTART(EEPROM_I2C,ENABLE);
while(I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_MODE_SELECT) == ERROR);
I2C_Send7bitAddress(EEPROM_I2C,0XA0,I2C_Direction_Receiver);
while(I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)==ERROR);
while(num)
{
if(num==1)
{
I2C_AcknowledgeConfig (EEPROM_I2C,DISABLE);
}
while(I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_BYTE_RECEIVED ) == ERROR);//检测EV7事件
*data=I2C_ReceiveData(EEPROM_I2C);
data++;
num--;
}
//数据传输完成
I2C_GenerateSTOP(EEPROM_I2C,ENABLE);
//重新配置ACK使能,以便下次通讯
I2C_AcknowledgeConfig (EEPROM_I2C,ENABLE);
}
大家可能还会好奇为什么我们写一个停止信号,因为我们写了一个起始信号然后检测事件,发送地址,检测事件,我们要遵循I2C的,所以我们要发送结束信号,然后判断成功了以后,我们再重新发送起始信号等等操作
还有为什么要检测标志位,而不是检测事件呢,
while(I2C_GetFlagStatus (EEPROM_I2C,I2C_FLAG_SB) == RESET);
while(I2C_GetFlagStatus (EEPROM_I2C,I2C_FLAG_ADDR) == RESET );
这个经过我的Debug调试,如果写检测事件,就会在写入函数卡死,具体我也没去仔细看,总之使用flag就不会出现问题
大家也知道32跟EEPROM通信是有一些小问题的, 所以这里就不要去深究为什么判断标志位了
|