我有一个STM32F2控制器和一个通过I2C连接的FRAM设备FM24V10-G。通常,为了与I2C设备通信,我使用了一个基于libopencm3的库。然而,使用FRAM需要稍微不同的I2C操作顺序(如发送开始、7位地址等),这意味着我不能使用读写等标准库函数,这对我使用其他I2C设备有帮助。在这个库中,I2C被实现为一个类,并且它具有过载的流运算符,以便以所需的顺序发送这些I2C命令。
例如:
I2c& I2c::operator<< (operation_t operation)
{
switch (operation) {
case Start:
i2c_send_start(_reg);
while (!checkEvent(SR2(I2C_SR2_BUSY | I2C_SR2_MSL) | I2C_SR1_SB));
break;
case Stop:
i2c_send_stop(_reg);
break;
case Wait_End:
while (!checkEvent(I2C_SR1_TxE));
break;
return *this;
}
有时,其中一些命令无法执行,导致CPU等待某个标志(如Wait_End),从而使整个系统停止运行。
所以我的问题是:有没有办法在上面的代码中返回某种超时标志?对我来说,让系统始终运行是至关重要的,如果I2C操作失败并达到超时,只需跳过一个命令即可。
感谢所有阅读本文的人!
你可以做一个非常基本的超时,如下所示:
I2c& I2c::operator<< (operation_t operation)
{
int count = 0;
const int TIMEOUT = 4242;
switch (operation) {
case Start:
i2c_send_start(_reg);
while (!checkEvent(SR2(I2C_SR2_BUSY | I2C_SR2_MSL) | I2C_SR1_SB)
&& count != TIMEOUT) {
count++;
}
break;
case Stop:
i2c_send_stop(_reg);
break;
case Wait_End:
while (!checkEvent(I2C_SR1_TxE) && count != TIMEOUT) {
count++;
}
break;
}
if (count == TIMEOUT) {
//error handling
return -1;
}
return *this;
}
当然,如果您需要精确的超时,并且不想浪费处理时间来增加count
变量,则应该使用硬件计时器。