I2Cビットバンギング

コントローラがI2Cドライバをサポートしていないため、ビットバンギングを使用してI2Cを実装する必要があります。そのため、SCLクロックを生成するには、ClockのHigh期間とLow期間を生成するように遅延が必要です。 A)nops/forループを使用するか、B)汎用タイマーを使用して生成される遅延を使用するのが最も適切な方法はどれですか。

2

5 答え

それは本当にあなたが同時に何か他のことをする必要があるかどうか、そしてあなたのプロセッサの速度にもよります。 I²Cの実行中にアプリケーションを完全にブロック(メインループ)できる場合は、ソフトウェア遅延を使用する方がはるかに簡単です。しかし、高速プロセッサを使用すると、他のものに使用される可能性がある何百もの命令が無駄になります。

ただし、他のI/Oを処理する必要がある場合、および/またはメインループで同時に計算を実行する必要がある場合は、割り込みを使用することをお勧めします。しかし、割り込みはその性質上、追加のオーバーヘッドを追加するため、ビット間で十分な命令を実行してこれを価値のあるものにすることができます。どちらのアプローチでも、次に何をすべきかを追跡するためにある種のステートマシンを実装する必要があります。

I²Cインタフェースは通常100 kHzまたは400 kHzで動作します。したがって、これはそれぞれ10 µsまたは2.5 µsごとの割り込みを意味します。かなり高速のプロセッサ、例えば80MHzで動作するPIC32の場合、これはビット間の800または200の1サイクル命令を表すので問題ありません。

しかし、8 MHzで動作し、I²Cが400 kHzで動作している場合、割り込みを処理する必要があるため(レジスタの保存と割り込みフラグの確認)、割り込みを使用しても実行できない可能性があるパルス(SCL)、送信するデータビットを取得し、クロックエッジの1/2ビット後にそれを送信(SDA)し、ビットカウンタを更新して状態を確認し、レジスタを復元して戻ります。アセンブリ言語であっても、おそらく20の命令では発生しないでしょう。

1/2ビットタイミングの理由は、クロック(SCL)とデータ(SDA)の両方のパルスを生成しているからです。クロックはデータビットの中央にあるので、スレーブはエッジを使用してデータをそのレジスタにクロックインすることができます(下記参照)。

enter image description here

だから遅いプロセッサでは、おそらくソフトウェアの遅延を使用する必要があるでしょう。 SCLパルスとSDAパルスの両方を生成するために1/2ビット時間を遅らせる関数(またはマクロ)を作成することはできますが、それは次のビットをフェッチしてビットカウンタを更新するオーバーヘッドを考慮していません。そのオーバーヘッドを追加することはあなたのバスが400 kHzより少し遅く走ることを意味するでしょう(しかしうまくいくはずです)。オーバーヘッドをタイミング計算に含めることで(したがって、全体的なタイミングが問題なく実行されるように1/2ビット時間だけ遅らせる)、フルスピードで実行することができます。これは速度を最大にするためにマシンサイクルの慎重なカウントを必要とするでしょう。

5
追加された

ビジー待機(NOP)は通常最悪の選択肢ですが、実装が最も簡単です。

3
追加された
@ xyz101どのアーキテクチャを使用しているのかさえ特定していません。
追加された 著者 jason saldo,
@ robertbristow-johnson最後の文に同意できません。初期化時だけでなく、常に1秒間に複数回I 2 C通信が行われるデバイスがいくつかあります。 (私はMSP430とPICを中心にそのようなデバイスを設計しました。)
追加された 著者 Nick Alexeev,
多忙な待機オプションよりも難しい、そうです。それでも、それは可能です。ステートマシンアプローチの使用を検討してください。
追加された 著者 Evan Wright,
継続的に実行されなければならないタスク。異なるI2Cバス間の切り替え(pca9547) IOエキスパンダー(pca 9535)..継続的に実行する必要があるすべてのタスク
追加された 著者 Evan Wright,
avrfreaks.net/forum/i2c-state- machine のようなものですか実際のアプリケーションではタイマーを使用しますが、必ずしもタイマーは必要ありません。タイマーがステートマシンを実行するようにしてください。
追加された 著者 Evan Wright,
その場合は、温度センサーや湿度センサーを読み取らなくてはいけません。
追加された 著者 Evan Wright,
なぜについてもう少し詳しく説明すると、これは良い答えになり、低品質のキューから削除されます。
追加された 著者 David,
アーキテクチャというのは?
追加された 著者 chandi.ma,
L:私はタイマーを使って同じ参照コードを持つことができます。
追加された 著者 chandi.ma,
しかし、タイマーオプションは実装が困難です。私は正しいですか?
追加された 著者 chandi.ma,
下矢印ではない、トム、しかし私はあなたの「通常最悪の選択肢」の評価に同意しない。通常、I2C通信は組み込みデバイスの初期化期間に行われるため、通常はこれが最善の選択肢であると思います。
追加された 著者 robert bristow-johnson,
@NickAlexeev、確かにあなたは私よりも多くをしました。私の経験は、システムの起動時にコーデックを単にリセットして初期化することです。私は、I²Cが常にデータを報告しているセンサーなどで行われることを知っています。その場合は、I²Cビットバンジャーがリエントラントでなければなりません。他のスレッドも同様にリエントラントであることを確認する必要があります。
追加された 著者 robert bristow-johnson,
@TomLを詳しく説明できますか。
追加された 著者 robert bristow-johnson,

あなたの回路に完全に依存しています。 I2Cデバイスは最大速度とクロックパルス間の最小タイミングを持つ傾向があることに留意してください、しかし低速では完全にリベラルな傾向があります。必要に応じて、非常に低速でI2Cを叩くことができます。私は25 kHzという低い速度で一般的なポートエキスパンダを使用しました、そしてICsはそれに関して一つの問題を抱えていないでしょう。

SCLのハイとローのクロック動作間の遅延は、最小タイミングを満たすのに十分なだけ遅くする必要があります。

0
追加された

もう1つ検討すべき点があります。まず、どの問題を解決する必要があるかを検討する必要があります。これは、一般的なI2C接続ですまたは特定の1つまたは2つのチップに接続するだけです。

任意のI2Cチップと通信できる汎用のI2Cホストを作成する必要がある場合は、クロックストレッチを含む遅延を正しく実装する必要があります。ただし、特定のICと通信するだけの場合は、そのICのデータシートでタイミングの要件を確認し、テストも行ってください。特定のタイミングを要求するように特別に設計されたIC内の回路はおそらくないでしょう。バスのタイミング要件は、プルアップ電流、静電容量、配線長、最大ファン出力の条件を満たす必要があるためです。アウト、これとそれ。チップ自体はおそらく認識可能なSDA、SCLエッジおよびレベルを必要とし、プロセスの限界で機能することができます。これはメガヘルツを意味します(そのチップがラインをサンプリングしI2Cをエミュレートするソフトウェアを使用している場合を除く)。

I2Cバスがわずか2〜3チップの間のPCB内でのみ走っている場合は、プルアップ抵抗についても同じことを考慮してください。バスに対する電気的要件は、一般的なI2Cバスに対する要件よりもはるかに簡単です。たとえば、バスを駆動しているときはプルアップ抵抗に頼るのではなくSDAピンとSCLピンの通常のプッシュプル駆動を使用し、ACKを上書きすることも可能です。

I2Cを実装するためにマイクロコントローラピンを使用している場合、I2C仕様ではピンが平らに開いていることが要求されるため、仕様 に従って完全に実装することは非常に困難です。コレクター - バス上のチップを独立してパワーアップまたはパワーダウンさせるために、ハイサイドにリークがあってはいけません。 一般的なマイクロコントローラピンはこれを満たすことができません、ハイサイド保護構造を常に持っているためです。繰り返しますが、これはあなたがバスの完全な制御権を持っているのであなたが唯一のマスターであり、従ってバスラインへの電力供給を制御できるのであれば問題ありません。マイクロコントローラのデジタル電源電圧まで引き上げることができます。しかし、システムの他の部分に電源が入っている間に電源を切る必要があるスレーブICを設計している場合、これは問題となります 。 I2Cバスのこの側面を尊重する必要がある場合は、外部回路が必要です。

要約すると、私が考えているのは、おそらくあなたが解決する必要があるものよりも大きな問題を解決するべきではないということです。ただし、エラーに対して十分なマージンを持って、 that をできるだけ実行してください。それほど費用がかからないのであれば、拡張性、アップグレード性、デザインの再利用といった側面も 注意してください。

See also: I2C Isolation using Switch

0
追加された

私は前の答えとは異なる意見を表明します。

"タイミングループ" (NOPとFORまたはDOループ)を使用して遅延を生成するのは簡単で信頼性が高く、再入可能ではありません。つまり、I²C通信時にマイクロコントローラに迷惑をかけるような作業が他にない場合は、それが可能です。そのため、これはアクティブなマルチスレッドのコンテキストでは使用できません。

他の タスクにも向いている必要があるときにビットバンギングI²Cが行われている場合は、タイマーを使用してこれを行うための再入可能コードを記述する必要があります。あなたは迅速かつ効率的な方法で各タスクのスレッドを循環する必要があります。各スレッドは、そのタスクに注意が必要かどうかを迅速にチェックし、そうでなければ素早く抜け出さなければなりません。

そして、どのスレッドのタスクにも注意が必要な場合は、必要に応じて注意を向けてすぐに抜け出す必要があります。特定のタスクが必要とする注意が素早いアクションではない場合、そのスレッドをどうにかして優先順位を下げて、I 2 Cのビットバンガが混乱しないようにする必要があります。

さらに、他のスレッドがどれだけのMIPSまたは時間を使用しているのかわからないため、他のスレッドの動作に起因するジッタが他のスレッドに比べて小さくなるようにI²CSCLラインのクロックレートを下げる必要がありますクロック周期

私はADI SHArCアプリケーション(ありますに内蔵のI²Cまたは「TWI」を使用していますが、使用していません)に取り組んでいます。タイミングループを使用したエントラントビットバンギングコードサイズが大幅に削減され、リセット時に周辺チップの制御レジスタを初期化するためだけにI²C通信が行われていたため、アクティブな割り込みや競合するスレッドはありませんでした。再入可能コードは単に必要ではありませんでした。

0
追加された
この答えは、再入可能性とスレッドの安全性(関連していますが同一ではありません)、そして単純なマイクロコントローラで実行されるマルチスレッドと協調的マルチタスクを混同しているようです。
追加された 著者 David,
I2Cは完全に非同期なので、どの程度のジッタが発生してもかまいません。 1クロック周期は10usで、次の5msであり、最小時間に従う限り、すべてうまくいくでしょう。例外は、安全対策として、クロック周期が長すぎると一部のスレーブデバイスがリセットすることです。しかし、これらのタイムアウトは、私の知る限りでは、数十ミリ秒から数百ミリ秒です。それでも割り込みを処理しながら、タイミングループでビットバンギングを実行することは合理的に安全です。
追加された 著者 DoxyLover,
「割り込みを処理しながらタイミングループでビットバンギングを実行するのは合理的に安全です。」 - あなたはおそらく正しいのですが、それでもやはり不安になります。
追加された 著者 robert bristow-johnson,