抽时间研究了一下从地址输入错误等未接收到从设备地址ACK响应的处理。想来想去,也就是查询一下NACK的flag这一条途径。今天写了代码验证了一下。
int i2c_xfer(uint8_t dev_addr, uint16_t reg_addr, uint8_t reg_len, uint8_t *buf, uint16_t len)
{
int ret = 0;
uint16_t i;
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_BUSY) == SET)
{
;
}
I2C_HandlingTransfer(I2C2, dev_addr, reg_len, I2C_RELOAD_MODE_SOFTEND, I2C_GENERATE_START_WRITE);
if (reg_len == 1)
{
I2C_TxData(I2C2, (uint8_t)(reg_addr & 0x00FF));
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_TXBE) == RESET)
{
if (I2C_ReadStatusFlag(I2C2, I2C_FLAG_NACK) == SET)
{
goto i2c_xfer_end;
}
}
}
else if (reg_len == 2)
{
I2C_TxData(I2C2, (uint8_t)(reg_addr & 0x00FF));
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_TXBE) == RESET)
{
if (I2C_ReadStatusFlag(I2C2, I2C_FLAG_NACK) == SET)
{
goto i2c_xfer_end;
}
}
I2C_TxData(I2C2, (uint8_t)(reg_addr & 0x00FF));
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_TXBE) == RESET)
{
if (I2C_ReadStatusFlag(I2C2, I2C_FLAG_NACK) == SET)
{
goto i2c_xfer_end;
}
}
}
else
{
/* something wrong */
}
I2C_HandlingTransfer(I2C2, dev_addr, len, I2C_RELOAD_MODE_AUTOEND, I2C_GENERATE_START_READ);
for (i = 0; i < len; i++)
{
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_RXBNE) == RESET)
{
if (I2C_ReadStatusFlag(I2C2, I2C_FLAG_NACK) == SET)
{
goto i2c_xfer_end;
}
}
buf[i] = (uint8_t)I2C_RxData(I2C2);
}
i2c_xfer_end:
I2C_EnableGenerateStop(I2C2);
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_STOP) == RESET)
{
;
}
return (ret);
}在Keil中运行一下,并将之前的从设备地址由0xA0修改为0xA2,并添加断点。果然,E030停留在了断点处。

NACK的标志位也确实适用从地址,可以看到APM32E030并没有像其它MCU有一个单独的从设备地址响应标志。把从地址当作一个数据来处理,其实也没有啥不同!
我要赚赏金
