3

STM32F2 コントローラと FRAM デバイス FM24V10-G が I2C 経由で接続されています。通常、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 操作が失敗してタイムアウトに達した場合は、1 つのコマンドをスキップするだけで問題ありません。

これを読んでいるすべての人に感謝します!

4

1 に答える 1

2

次のような非常に基本的なタイムアウトを実行できます。

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変数を増やして処理時間を無駄にしたくない場合は、ハードウェア タイマーを使用する必要があります。

于 2013-11-23T01:22:59.937 に答える