第二个我们发送的地址,然后判断了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通信是有一些小问题的, 所以这里就不要去深究为什么判断标志位了
|