AVR Libc Home Page AVRs AVR Libc Development Pages
Main Page FAQ Library Reference Additional Documentation Example Projects

Example using the two-wire interface (TWI)
[Demo projects]

ATmegaシリーズのいくつかの新しいデバイスはマイクロコントローラにtwo-wire bus内蔵機能をサポートしています。これは基本的にPhillipsにより提供されているI2Cと同じものですが、特許の問題よりこのこの用語はAtmelのドキュメントでは回避されています。
Philips のオリジナルドキュメントについては以下を参照ください。

http://www.semiconductors.philips.com/buses/i2c/index.html

TWIへの案内

two-wire interface(以後TWI)は2本の信号線SDA (serial data) 、SCL (serial clock) からなります。(もちろん、さらにGround Lineもあります)
このバスに参加しているすべてのデバイスはお互いいオープンドレインドライバで接続されています。そのため、ワイヤーは適切なプルアップ抵抗で終端処理されていなければなりません。プルアップ抵抗は、要求される最高クロック周波数で決まる制限時間内にラインの持つ静電容量を充電するのに充分小さくなければなりません。また、ドライバが過負荷にならない程度には抵抗値は大きくなければなりません。プルアップ抵抗値の決定に役立つ情報がデータシートにあります。
デバイスはバスに対してマスター (転送を開始する側) にも、スレーブ (マスターから呼ばれたときだけ動作する側) にもなれます。バスは複数のマスターを許容します。また、特定のデバイスがマスターとして働いたりスレーブとして働いたりすることも許容します。デバイスは(Phillipsで管理されている)7bit値のアドレスが振られ、いわゆる「スタートコンディション」の後、最初のバイトとして送信されます。このバイトの最下位bitはRead/Writeフラグで、スレーブへの要求がreadなのかwriteなのかを指定します。
(10-bitアドレスに対するオプションもありますが、今回の使用例では提示しません)

The TWI お手本プロジェクト

ATmegaのTWIハードウェアはマスターとスレーブ双方をサポートします。このお手本は、AVRコントローラをTWI マスターとして使う方法だけを実演します。実装は簡潔に、TWI スレーブと会話するために要求されるステップに集中するため、簡潔にしました; すべての処理はポーリングモードで、次の処理ステップがやってきたことを (TWINT割り込みビットがセットされることで) チェックすることでTWI インタフェースを待ちます。
もしすべてのTWI コミュニケーションをバックグラウンドで行う必要がある場合は、これらすべては割り込みコントロールによる方法で実行される必要があります。スタートコンディションだけは割り込みルーチンの外でトリガされる必要があります。

たくさんの種類のTWIバスに接続可能なスレーブデバイスがあります。今回のお手本の目的には、各社から提供されている工業規格24Cxx(xx=01,02,04,08,16) シリーズEEPROMデバイスを選びました。主にEEPROMがスレーブデバイスとして読み書きでき、双方向対話ができるデバイスであるところから勝手に決めました。今回のお手本でも読み書き双方について紹介します。

普通は、ATmegaシステムにこのようにEEPROMを追加接続する必要なんてありません。というのもハードウェアTWIをサポートする最小のAVRであるATmega8は512バイトのEEPROMを持っており、これは24C04デバイスと同等ですから。ATmega128は24C16の2倍ものEEPROMを持っています。
ただ一つ利点があるとすれば、外部接続されたEEPROMはリムーバブルであるということでしょう。たとえば、SDRAM PCメモリーなどでは、RAM設定情報を持った内蔵TWI EEPROMがついています。

※訳注:AVRにEEPROM付きSDRAMを簡単につけられるという意味ではなく、追加デバイスがその情報を保持するチップを持っているという利益をリムーバブルEEPROMが実現できることを説明していると思われます。

ソースコード

ソースファイル:: twitest.c
Note [1]
ヘッダファイル <util/twi.h> は、TWIステータスレジスタで使われるいくつかのシンボリック定数のマクロ定義を含んでいます。これらの定義はAtmelデータシート上の名称と一致しますが、すべての名前の先頭に"TW_" をつけてあります。
Note [2]
このクロック値はコンパイラによってUARTボーレート設定とTWIクロックレート設定などのタイマーの設定値計算に使われます。
Note [3]
24Cxx EEPROMに割り当てられたアドレスは上位4bitに1010で、続く3bitは通常スレーブサブアドレスとして利用可能です。これは同じタイプのデバイスを1つのバス上に複数つけることを可能にします。各デバイスのサブアドレスはEEPROMデバイスに対しハードウェア的に結線することで設定できます。しかしながら、EEPROMアドレス指定に使える、デバイス選択の次のデータパケットはたった8bitしかないので、8bitを越えるアドレスを要求するデバイス(24C04以上)は、要求があればサブアドレスビットを"盗み"、サブアドレス3bitをEEPROMセルアドレスのbit9〜bit11に使います。
この例では単純にすべてのサブアドレスビットは小さなデバイスについては0であると見なしています。そのため24CxxのE0,E1,E2入力ピンはGNDに落としておく必要があります。
Note [4]
システムクロックが遅い場合は2x U[S]ART クロック倍速設定を有効にしてボーレート誤差を改善できます。これにより1MHz補正済み内蔵RC発信器で9600baudを使えるようになります。データシートのボーレートテーブルも参照してください。
Note [5]
マスターモード時、TWBR値を最低10以上にする理由が書かれています。この理由によりシステムクロック3.6MHz未満ではクロックレートを100kHzにできません。クロックを遅くする必要があります。
Note [6]
この関数は標準入出力によって使われています。この例では、デバッグやデモンストレーションの目的で使われています。
Note [7]
TWIバスで送るデータを短くするため、24Cxx EEPROMは1度のリクエストで複数データバイト送信する機能をサポートしています。データバイトが転送される毎に更新される内部アドレスカウンタを持つことで実現しています。データを読み取るときは、もし要求するなら1つのリクエストで全デバイスメモリを読み込むこともできます。(カウンタはデバイスの終端に達した時には0に戻されます。)
Note [8]

EEPROMを読み出す場合、最初のデバイス選択は、読み出しを開始するアドレスを設定するために、書き込みモード(R/Wビットに0を置く)で行わなければなりません。これはマスター送信モード(master transmitter mode)と呼ばれます。TWI通信の個々のステップの完結は、TWCRレジスタのTWINTビットが立つことで示されます。割り込みが許可されていればここでTWI割り込みが起動します。次の通信ステップのための何らかの動作を行った後、割り込みコンディションは手動でクリアする必要があります。これはTWINTビットに1を書き込むことで行われます。他の(一般的な)割り込みと異なり、割り込みルーチンを使っていてもこの手動クリアが要求されます。TWINTがセットされてはじめて次のバス処理が始まるからです。

Note [9]
TWIバスは複数マスターを許容するので、あるマスターがバスアクセスを開始するときバスの取り合いが起こる可能性があります。通常は、TWIバスインタフェースユニットは他ユニットによって起こされた開始条件を検出し、バスがbusyの時は開始条件を送出しないようになっています。
2つのマスターが全く同時に開始条件を送ってしまった場合は、バス調停機能が働きます。(※自身と同時に開始されたマスターが走っていないという保障はないので、)マスターはどんな送信動作中でも(※他のマスターの存在に気づき)調停に破れる(※マスター権を他に譲り、自分は身を引くことになる)可能性があります。調停に破れたマスターはプロトコルに従い、速やかにバスに書き込むのを止めなければなりません。また、(※調停に破れた場合は)アクティブなマスターからの進行中の送信を壊さないために、決して停止条件を送信してはなりません。今回の例では、調停に破れた場合はすべての送信はやり直しとなります。これは、新しい開始条件を送ることになりますが、(※既に現在のアクティブマスターが開始条件を送ってバスを占有しており、こちらのTWI機構はそれを感知していますので、開始条件を送っても) 現在のアクティブなマスターがバスを離すまで待たされます。
Note [10]
次に、スレーブデバイスは ( いわゆる再送開始条件によって) 再選択されます。再送開始条件は現在のマスターによりバスを占有し続けることを保証します。これは同じスレーブアドレス(SLA)で、しかし今度は読み込みモード(R/Wbitが1)で行われます。
Note [11]
1個又は複数個のセル書き込み後、EEPROMデバイスがまだbusyである場合は、EEPROMは単純に自身のバスインタフェースドライバをハイインピーダンス状態(切り離し)にして、スレーブ選択に対し反応しないようにします。デバイスを選択しているマスターは、SLA+R/Wパケット送信後、SDAがHighになっているのを見て、これを選択要求に対するNACKと認識します。
スレーブ選択プロセスは単にデバイスが反応するまで開始条件をやり直します。(※マスターはすでに開始条件を送っているので、)これは再送開始条件になります。このこのポーリング動作は書き込み時busy wait timeを最小限にとどめるために24Cxxデータシートによって推奨されています。デバイスが壊れていたり、選択に全く応じない場合(たとえば目的のスレーブデバイスがなかったという場合など)もあることに注意してください。これは無限ループに陥ってしまうおそれがあります。そこで、ここではデバイスが反応しない場合の繰り返しの最大数をMAX_ITERで設定し、反応がない場合にはエラーを返すようにしています。
Note [12]
これはマスター受信モード(master receiver mode)と呼ばれます。 バスマスターはSCLクロックを供給しますが、スレーブデバイスはSDAラインを適切なデータに従って操作します。8つのデータビット後、スレーブからさらなるデータ転送を要求する場合は、マスターはSDAをLowに引きACKビットで反応します。これ以上データ要求をしない場合は、SDAラインをHighのままにします(NACK)。これはスレーブに対し送信を止めるよう指示します。ACKを返すにはTWCRレジスタのTWEAビットを、今回の転送を開始する時にセットして行います。
Note [13]
次のデータパケット転送を要求するためのコントロールワードは、最初にTWEAをセットしACKを返すようにします。最後の繰り返しループでは、TWEAはセットされず(NACKを返し)、これにより依頼側はこれ以上の転送は望まないことを伝えます。
※データ受信完了時にバスにACKが送られます。受信完了時にこれ以上データを要求するかどうか判断してACK/NACKを送るのはタイミング上きわどいので、ACK/NACK送信は送信要求時(最終データ受信前)に設定して、最後のデータの要求の時にTWEAをクリアして要求する形をとります。
Note [14]
調停敗北時以外では、すべてのバス処理はマスターにより終了条件送信を行い、適切に終了されなければなりません。
Note [15]
EEPROMへの書き込みは、マスター送信モードだけで済むので読み出しよりシンプルです。SLA+Wの後の最初のパケットは常に次の操作のためのEEPROMアドレスとなっていることに注意してください。(このパケットは前記のデバイス読み出し例で、読み出し前に送ったものと同じものです。) マスター送信モードで1個を越えるデータを送る場合は、続くパケット(2番目以降のデータパケット)すべては指定されたアドレスに書き込まれるデータバイトと見なされます。内部のアドレスポインタは書き込み操作毎に1つ増やされます。
Note [16]
24Cxx デバイスは ~WC ピンを Logic-Highに結線することでライトプロテクト状態になります(未結線状態も許容されており、これはLogicLowLevelとなり、ライトプロテクトなしとなります)。ライトプロテクトされたデバイスでは、すべてのデータ転送(※スレーブへの書き込み)の試みはデバイスからNACKを返されます。いくつかのデバイスはこの機能を持っていないかもしれません。

Automatically generated by Doxygen 1.4.1 on 23 Jan 2006.