关于void I2C_EE_WaitEepromStandbyState(void)的疑问
void I2C_EE_WaitEepromStandbyState(void)
7 {
8 vu16 SR1_Tmp = 0;
9
10 do {
11 /* 发送起始信号 */
12 I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);
13
14 /* 读 I2C1 SR1 寄存器 */
15 SR1_Tmp = I2C_ReadRegister(EEPROM_I2Cx, I2C_Register_SR1);
16
17 /* 发送 EEPROM 地址 + 写方向 */
18 I2C_Send7bitAddress(EEPROM_I2Cx, EEPROM_ADDRESS,
19 I2C_Direction_Transmitter);
20 }
21 // SR1 位 1 ADDR:1 表示地址发送成功,0 表示地址发送没有结束
22 // 等待地址发送成功
23 while (!(I2C_ReadRegister(EEPROM_I2Cx, I2C_Register_SR1) & 0x0002));
24
25 /* 清除 AF 位 */
26 I2C_ClearFlag(EEPROM_I2Cx, I2C_FLAG_AF);
27 /* 发送停止信号 */
28 I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE);
29 }
火哥这的解释是
每 次 数 据 写入 通 讯前 调 用 了
I2C_EE_WaitEepromStandbyState 函数等待 EEPROM 内部擦写完毕.
实现是向 EEPROM 发送它设备地址,检测 EEPROM 的响应,若
EEPROM 接收到地址后返回应答信号,则表示 EEPROM 已经准备好,可以开始下一次通
讯。函数中检测响应是通过读取 STM32 的 SR1 寄存器的 ADDR 位及 AF 位来实现的,当
I2C设备响应了地址的时候,ADDR会置 1,若应答失败,AF 位会置 1。
刚开始看到这个函数能明白个大概,但是关于这一句SR1_Tmp = I2C_ReadRegister(EEPROM_I2Cx, I2C_Register_SR1);
并没有太过详细解释,网上也没搜到一个明确的解答,一堆问这个是啥作用的,于是有点懵,实在没有办法,怎么办呢?只能拿着32中文手册对
照着看呗,看着看着终于发现了一点端倪,可以看到在I2C_SR1寄存器的SB位的描述如下:
SB:起始位(主模式) (Start bit (Master mode)) 位0
0:未发送起始条件;
1:起始条件已发送。
– 当发送出起始条件时该位被置’1’。
– 软件读取SR1寄存器后,写数据寄存器的操作将清除该位,或当PE=0时,硬件清除该位。
所以,结合这里就猜想对SR1的读取可能就是为了满足SB位的清零条件!当对SR1读取过后条件满足了一半了,再写地址I2C_Send7bitAddress其实
就是写数据寄存器,因为写地址其实就是发生数据,用到了数据寄存器。这下条件满足了,正好清除该位。结合前面的I2C_GenerateSTART
,不难发现,正好是在开始信号之后读取SR1及写DR,而作用正好吻合,用来清除开始标志位SB。另外手册上也并没有说SB位可以软件清零。只能用
这种方式清零。所以作此猜想 读取是否为了满足清楚清除的条件? |