使用运算符进行I2c操作

Using operators for I2c operations

本文关键字:I2c 操作 运算符      更新时间:2023-10-16

我有一个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变量,则应该使用硬件计时器。