【スレーブモードの使い方】
スレーブモードでは下記の手順で動作します。
(1) まずStartシーケンスを検出するのを待ち、その後に続く8ビットデータを受信する。
信号の受信はすべてマスターから送られてくるクロックSCLでサンプリングします。
(2) 最初に送られて来るアドレスデータを受信してSSPSRレジスタに格納します。
(3) 受信が正常完了したらACK信号をハードウェアが自動応答し、SSPBUFにデータを
転送します。
(4) しかし下記の場合にはNACKを自動返送します。
・受信完了以前にBFビットがセットされバッファーフルになっているとき
・オーバーフロー状態になっているとき(SSPOVがOn)
そしてこのときにはSSPSRからSSPBUFには転送されません。
(5) アドレスが自分のアドレスと一致したら、それに続くデータを順次受信し、正常であ
ればACKを返送してSSPBUFに格納するので、それを取り込みます。
(6) Stopシーケンスを検出して転送の終了となる。
【7ビットアドレスモードの場合】
《アドレッシング手順》
・Startシーケンス検出を待ち、その後に続く8ビットデータを受信しSSPSRレジスタに
格納する。
・その後SSPSRレジスタの上位7ビットについて、SSPADDにあらかじめセットされて
いる自アドレスとの比較をします。
・アドレスが一致かつBFビットとSSPOVビットがOffの時だけSSPSRレジスタからSSP
BUFにデータを転送します。同時にBFビットをセットしてACKを自動返送し、SSPIF
ビットをセットしてデータ受信を通知します。このとき割込みが許可されていれば割
込みが発生します。
・ここでSSPSTATで送受信の判定をして、その後の手順を送信、受信で区別して進み
ます
・受信の場合には、プログラムでSSPBUFを空読みしてから、SSPIFをクリアすれば次の
データ受信待ち状態となります。
送信の場合にはSSPBUFに送信データをセットしてからSSPIFをクリアすればデータの
出力が自動的に開始されます。
SSPIFがクリアされるまでは、スレーブ側がSCLラインを強制的にLowにしたままにする
ので、マスター側がクロックを出力するのを待つことになります。
《データ受信手順》
アドレス受信データ内にあるR/Wビットが0になっていればデータの受信モードとします。
SSPSTATで判定できますので、その後は受信状態の動作に移行します。
・引き続くデータを8ビット毎に受信し、正常であればACKを自動返送してからSSPBUFに
転送しSSPIFをセットします。これによりデータ受信を通知するとともに、割込み許可と
なっていれば割込みが発生します。
・プログラムでSSPBUFの内容を読み込んでからSSPIFをクリアすれば次のデータ受信
待ちとなります。
・Stopシーケンスの受信によりデータ受信を完了します。
☆7ビットアドレスモードでスレーブ側が受信のときのシーケンス
《データ送信手順》
受信アドレスデータに含まれているR/Wビットが1になっていれば送信状態とします。
・送信の場合にはSSPBUFに送信データをセットしてからSSPIFをクリアすれば自動的に
クロックに同期させて送り出します。
・データの送信が完了すればSSPIFがセットされ、割込みが許可されていれば割込みが
発生します。
正常完了しマスタ側からACKが返送されていれば、SSPBUFに次のデータをセットして
からSSPIFをクリアすれば自動的に次のデータを送信開始します。
・もしマスタ側からACKでなくNACKが返送されて来た場合には、送信を自動的に完了さ
せSSPIFをセットします。
プログラムでSSPSTATを読んでエラーを確認したあとSSPIFをクリアすると初期状態と
なって次のStartシーケンスの検出を待ちます。
☆7ビットアドレスモードでスレーブ側から送信の時のシーケンス
【10ビットアドレスモードの場合】
《アドレッシング手順》
この場合には2バイトのアドレスデータが必要になるため、最初のアドレスデータの
上位5ビットが一定のパターン("1111 0 A9 A8 0)となっています。
・アドレスの1バイト目を正常受信すると、SSPBUFにデータが転送され、BFビットとUA
ビットがセットされます。
・プログラムでSSPBUFの内容を空読みしてから、SSPADDレジスタを下位のアドレスに
入れ替え、その後SSPIFをクリアします。これでクロック(SCL)ラインが開放され、次の
2バイト目のアドレスデータの受信が可能となります。
・引き続く2バイト目を正常受信するとBFとUAビットがOnになります。SSPADDのアドレス
と一致すればSSPBUFにアドレスデータが転送されますのでこれをプログラムで空読み
してから、SSPADDレジスタを上位のアドレスに入れ替え、その後SSPIFをクリアし、
再Startシーケンスを待ちます。
・再Startシーケンスでは無く次のデータの受信があったときは受信モードと判定して
引き続くデータを受信します。
・再Startシーケンスを検出したら再度上位アドレスを受信します。正常受信しアドレスが
一致すればSSPBUFにアドレスデータが受信されるので、アドレスデータを空読みし、
SSPSTATでデータの送信要求を確認してから送信データをSSPBUFにセットして、
SSPIFをクリアします。
・これでデータの送信開始となりますので、引き続くデータを送信します。
《データ受信手順》
2バイト目のアドレスを受信後、再Startシーケンスでは無く、データ受信の状態となった時
は受信要求で、プログラムでSSPSTATを読んでこれを確認してから、SSPBUFの内容を
データとして読み込み格納してからSSPIFをクリアします。そうすると次のデータ受信準備が
完了したということで、次の受信を開始します。
これをStopシーケンスを検出するまで繰り返し続けます。
《データ送信手順》
再Startシーケンスを検出したときは、送信要求ということになり、次の1バイト目のアドレスを
受信して、SSPSTATでR/Wを確認し、送信要求であれば、送信すべきデータをSSPBUFに
セットしてから、SSPIFをクリアします。これで自動的に送信が開始されます。
送信完了によりSSPIFがセットされ、許可されていれば割込みが入りますので、続けて次の
送信データをSSPBUFにセットしてからSSPIFをクリアすれば同様に送信が開始されます。
こうしてStopシーケンスが検出されるまで送信を続けます。
【同報アドレッシング】
MSSPでは同報アドレスで全スレーブに一斉に送信を行うことができます。これを
「General Call Address」と呼んでいます。
このためのアドレスは、"0000 000"または"00 0000 0000"でR/W=0となっています。
つまりアドレスがすべて0のときは一斉同報として扱います。
同報機能はスレーブ側のSSPCON2のGCENビットがOnになっていることが必要です。
このGCENがOnのスレーブは引き続くデータを受信し割込みを発生するので、これを
順次取り込みます。受信手順は通常受信と同じです。
【プログラム例】
実際にI2C通信のスレーブとして作成したプログラム例です。この例題では、1台の
マスタに複数台のスレーブを接続し、スレーブのアドレス指定により、相手を特定して
通信を行います。
スレーブ側の機能としては、
@ マスタから送信された文字列データを受信して、液晶表示器に表示します。
データが改行コードの場合には、カーソルを液晶表示器の2行目先頭に移動します。
A マスタからの送信要求により、30Hから順に文字列を返送し、ストップシーケンスで
終了します。
以上の機能を実現したプログラム例が下記となります。
(a) 初期設定とメインループ
例題ではスレーブアドレスをB6Hとしています。クロックストレッチを
許可することで、液晶表示器に毎回受信して表示する間、マスタ側を
待たせています。
(b) 割込み受付と受信処理
毎回の送受信ごとに割込みを使って受付ています。そして送受信
の区別をしてそれぞれの処理に分岐しています。
受信の終了はSTOPシーケンスで判定します。
(c) 送信処理部
送信の場合には30Hから順番に文字を送信します。
そしてSTOPシーケンスで終了を判定しています。
下記がスレーブのプログラムファイルです。ダウンロードしてお使い下さい。
★ スレーブ側プログラムリスト(i2csleve3.lzh) i2cslave3.asm + lcdlib18.asm