I2C デバイス検出プログラム

STM32用に書いているライブラリを使って、I2Cデバイスの検出プログラムを書いてみました。

このプログラムはI2Cのアドレス0からアドレス127(0X7F)まに順にダミーの出力を書き込んで、ACK/NAKのどちらが帰ってくるかを見ています。書き込みデータ長は0ですので、ACK/NACKの判定はI2Cデバイスがアドレスに対して返すACK/NACKについて行います。デバイスがないときにはマスターはNACKと判断するため、結果的にACKのところだけにデバイスがあると判断できます。

inline void MasterTask::TaskBody(const void* ptr)
                                 {
    uint8_t tx_buf[1];


    murasaki::debugger->Printf("            Probing I2C devices \n\r");
    murasaki::debugger->Printf("   | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n\r");
    murasaki::debugger->Printf("---+------------------------------------------------\n\r");


    for ( int v = 0; v < 128; v+=16)
    {
        murasaki::debugger->Printf("%2x |", v);
        for ( int h = 0; h <16; h++)
        {
            murasaki::I2cStatus result;
            // check whether device exist or not.
            result = murasaki::platform.i2c_master->Transmit(v+h, tx_buf, 0);
            if ( result == murasaki::ki2csOK)		// device acknowledged.
                murasaki::debugger->Printf(" %2X", v+h);
            else if ( result == murasaki::ki2csNak)	// no device
                murasaki::debugger->Printf(" --");
            else
                murasaki::debugger->Printf(" ??");	// unpredicted error.
        }
        murasaki::debugger->Printf("\n\r");
    }

    while (true)	// dummy loop
    {
        murasaki::platform.led1->Toggle();	// toggling LED
        murasaki::Sleep(static_cast<murasaki::WaitMilliSeconds>(700));
    }
}

とくに変わったことはありません。128アドレスを行列に並べるため、2重ループになっています。

内側のループではデバイスに0を送ってACKが帰ってくれば現在のアドレスを、NACKならば”–“を、それ以外のエラーなら”??”を出力します。「紫」ライブラリではI2Cの実行結果を返り値として表明しますので、その値で出力を決めています。NACKが帰る場合、STM32 HALではエラー割り込みが発生しますが、紫ではこの割り込みをクラス変数内部で処理しているため、ユーザーからは割り込みも送受信のステータスとして見えることになり、使い勝手が良いです。

実行結果は以下のとおりです。0x50番地にあるのはI2Cメモリ、0x7C番地にあるのはSTM32L152上のI2C2ポートです。このポートはCubeMXで0x7Cをアドレスとして設定しており、紫のI2Cスレーブ・クラスを別スレッドで使用してI2Cデバイスとして動かしています。

 

 

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください