MCCでのI2C

MCC(MPLAB Code Configurator)でI2Cもできるので、Master/SlaveともGenerateさせて試してみた。

両方とも、PIC16F1938を使い、どちらも、I2CとUSARTを有効にして、USBシリアル変換モジュールをつないでMacでモニターできるようにした。

Slave側は128バイトのEEPROMのエミュレータが生成されるので、そのまま動かせる。

Master側は特に機能は生成されないが、生成されるi2c.hに実際のEEPROMのアクセス処理のサンプルコードがコメントに書いてあるので、それをコピペして、アドレス0から16バイトをバッファに読み込むコードと、バッファの内容をUSARTにダンプするコードを書いて動作を確認してみた。

すると、なぜか1バイトずれて読み込まれる現象が…
Slave側でI2Cの処理中にUSARTを使うとI2Cに影響するので、大きめのバッファを用意して、トレース情報を書き込んで後でUSARTに出力させて調べた。
そしたら、Slave側のEEPROMエミュレータはアドレスが1バイトとして処理していて、Master側はアドレスとして2バイト送っているので、アドレスの上位バイト(0)がアドレスとして、下位バイト(0)が書き込みデータとして処理されるので、EEPROMのアドレス0に0が書き込まれて、アドレスが1進められる。で、次のReadリクエストでアドレス1からのデータを返すので1バイトずれて読み込まれるという現象になっていた。

Master側のアドレスを1バイトにしたらちゃんと読み込まれるようになった。

この後、書き込み処理もコピペ&関数化して、16バイト書き込んだ後、同じアドレスから16バイト読み込んでダンプし、書き換えられていることを確認しようとしたら、フリーズしたように進まなくなった。

16バイト書き込みの処理が1バイト毎に書き込んでいるので、どこまで処理が進んでいるのか各所にprintf文を入れて確認したら動いた。
連続してI2Cの関数をコールすると不具合が出るんだろうということで、__delay_xxを入れたら動くだろうと、怪しそうなところに入れてみた。

I2C_MasterWriteのコールの後で、ステータスがI2C_MESSAGE_PENDINGの間ループをして処理が終わるのを待っているところに__delay_ms(5);を入れたら動くようになった。

MCCによるI2Cのテスト(PIC16F1938)

MCCによるI2Cのテスト(PIC16F1938)

MCCによるI2Cの回路図(PIC16F1938)

MCCによるI2Cの回路図(PIC16F1938)

pic16f1938_i2c_master.X
pic16f1938_i2c_slave.X

カテゴリー: PIC, ソフトウェア, 回路 タグ: , , , , パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


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