PC-8001用 ソフトウェア制御I2Cボード

I2C

以前、KZ80マイコン用に8255(PPI)を使ってI2C通信するボードを作成しました。
おなじようなかたちで、PC-8001にも装備してみたいと8255(PPI)装備のI2Cボードを作りました。

対象とするデバイスについて

KZ80マイコンのI2Cボードでは、RTC DS3231モジュールからの日時データ読み出しや日時データ書き込みができました。今回は、買ってあってI2C通信用なので死蔵していたRTC DS1307+(DIP品)や、I2C EEPROM 24LC1025も読み書きしてみたいと考えました。またRTC DS3231モジュールには小容量ながらもI2C EEPROM(AT24C32)が搭載されています。
※ちなみに、この記事ではRTC DS3231とDS1307まで動作確認しています。

Amazon.co.jp: HiLetgo 3個セット DS3231 AT24C32 時計モジュール リアル時間時計モジュール IICモジュール RTCモジュール Arduinoに対応 [並行輸入品] : 産業・研究開発用品
Amazon.co.jp: HiLetgo 3個セット DS3231 AT24C32 時計モジュール リアル時間時計モジュール IICモジュール RTCモジュール Arduinoに対応 : 産業・研究開発用品
I2C接続RTC(リアルタイムクロック)DS1307+: 半導体 秋月電子通商-電子部品・ネット通販
電子部品,通販,販売,半導体,IC,LED,マイコン,電子工作I2C接続RTC(リアルタイムクロック)DS1307+秋月電子通商 電子部品通信販売

I2Cアドレスを確認したところ、RTC IC同士やEEPROM同士はI2Cアドレスが重複していることがわかりました。

デバイス名I2Cアドレス
RTC DS32310x68
RTC DS1307+0x68
EEPROM 32k 24C320x57(変更可)
EEPROM 1024k 24LC10250x50〜0x57

秋月電子などでI2Cのバスマルチプレクサなどの切り替えICも売ってて何に使うのかなぁとぼんやりと思っていたのですが、意外とI2Cアドレスは重複しがちなんですね。

リセット付き8chI2Cバスマルチプレクサ PCA9547D: 半導体 秋月電子通商-電子部品・ネット通販
電子部品,通販,販売,半導体,IC,LED,マイコン,電子工作リセット付き8chI2Cバスマルチプレクサ PCA9547D秋月電子通商 電子部品通信販売

切り替え回路の案-1

切り替え装置としては、8255(PPI)のI2C用としてはポートCだけを使ってますので、使っていない余ったポートAを使って相手を選択してスイッチングするICで実現できそうと考えました。

以前 ArduinoMEGA用 FM音源ボードの基板をいただいたときに買ってあった 74HC4066アナログスイッチICが良さそうと思い採用。横ちょからスイッチ端子をH/Lレベルで操作してやることで双方向通信を切り替えできそうです。

アナログスイッチTC74HC4066AP: 半導体 秋月電子通商-電子部品・ネット通販
電子部品,通販,販売,半導体,IC,LED,マイコン,電子工作アナログスイッチTC74HC4066AP秋月電子通商 電子部品通信販売

回路図はこんな感じで考えました。

I2CバスマルチプレクサはSCL/SDA両方の信号線を切り替える仕組みが多いですが、MAX4733のプリケーションノートでSDAラインだけのスイッチングをしている作例がありまして(SDAさえ切り替えてしまえばスタートコンディションが該当デバイスにだけ発生するので…)、これなら74HC4066で4デバイス行けそうと思いました。SCLラインは芋づるでつないでしまいます。

I²Cアドレスの競合を軽減する超小型アナログスイッチ | Analog Devices
小型SPDTスイッチは、2線式のアドレス競合を軽減するために使用できます。この簡素な回路で、簡素なスイッチが同じアドレスを持つ2つのコンポーネントに適切なアドレスをどのように提供できるかが分かります。

74HC4066で切り替えできるのは4デバイス分ですが、EEPROM 24LC1025はA0〜A2のピンをH/Lレベルどちらに接続するかでアドレスを設定できるため、芋づるでつなぎます。

実験してみたら….

上記回路で、いろいろと実験してみたのですが、どうもデバイス切り替えがうまくいきませんでした。試作したユニバーサル基板はこんな感じです。

テスターであたってみたりして気がついたのですが、よく考えると前回の8255(PPI)でI2C通信を実施する記事でも書きましたが、I2C信号線のHレベル/Lレベルの切り替えは8255(PPI)のポート設定についてコントールワードを送信することで「入力(HiZ)=Hレベル」「出力=Lレベル」を切り替えています。8255(PPI)のコントロールワードはポートごとの設定とはいかず全ポートの情報を出力します。よって今回の設定変更に関係ないポートまで初期化されてしまうのでした。(あたりまえ)8255(PPI)は出力用に初期化されると、全ビットがLレベルとなります。….. orz
つまり、8255 ポートAにI2Cデバイスの選択信号を出力していてもI2C通信が始まるとポートAは全ビットLに落ちてしまうので切り替えスイッチの用をなしません。考えてみたらあたりまえ。

切り替え回路の案-2

改良?した回路図がこちらです。

結局、8255(PPI)の外側にラッチIC 74HCT573を配置しまして、I2Cデバイス選択信号を保持してもらうことにしました。8255(PPI)がちゃんとラッチの機能をもっているのに、外側にラッチを持つのは負けた感じです。データラッチタイミングもPA7端子をL→H→Lみたいに操作するというちょっと不格好なソフトウェアとなりました。

最初の回路ではアドレスデコーダーの74LS138にZ80のIOREQ をENABLE端子に入れてRDWR を直接8255につないでみましたが、タイミングの関係うまく動作しなかったため74LS32のORゲートで IORQIOWR信号を生成するかたちへ変更しました。

ひとまずこれでRTC DS3231との通信ができましたので、githubではリリース1としてリリースしました。

Release リリース1.0 · kuninet/PC8001-I2C
8255PPIの入出力を切り替えてI2C通信を実施するバージョンです。 通信中 何度もPPI初期化がかかるため若干使いづらいと思います。 次のバージョンからは74HC07(オープンドレイン)を使用してPPI2ポートを使って通信する方式へ変更する予定です。

ユニバーサル基板上にはICを搭載するスペースが無かったので、苦肉の策で子基板を作成して74HC4066のICソケットを嵩上げして対応しました。不格好ですが…

RTC DS3231はOK、DS1307+はナゼかNG

つぎに苦しんだのが、KZ80マイコンでI2C通信ができたRTC DS3231は通信できたものの、同じ手順で通信できるはずのDS1307+ DIPとの通信がいくらやってもNGなことでした。当初はあまりデータシートを読まず、以下のような回路としていたのでした。
DS1307+はバックアップ電源用にVbat端子を持っています。通常はCR2032などを直結しておくと思うのですが、電池交換しなくて良いように私が以前作った他のRTCボードと同様電気二重層コンデンサを使おうと思いました。Vccから逆流防止用のダイオードと、突入電流防止の抵抗100Ωを通じて1F 5.5Vの電気二重層コンデンサを充電し、Vccが切れたら電気二重層コンデンサから給電する仕組みとしてみました。この回路だとどうしてもDS1307+がI2C通信に返事をしません。

ためしに、バックアップ用の電源をつながずに、ブレッドボードなどでKZ80マイコンのI2Cボードなどで動かしてみると普通に日時データの読み書きがOKでした。また今回作ったボードの切り替え回路を通さないI2C外部端子に、件のブレッドボードで仮設して作ったDS1307+をつなぐと動作するのであります。

結局のところ問題はVccとVbatの電位差の問題でした。データシートを読むとVBATにつなぐ電圧は以下のように2.0V〜3.5Vなのですが、テスターで計測してみたところ電気二重層コンデンサの両端は4.5Vとなっていました。定格オーバーです。もともとCR2032などボタン電池でバックアップする仕様となっているようです。

DS1307 DATASHEET

また、DS1307データシートのVBAT端子の説明が以下のようになってまして、Vccが低下してVbat x 1.25倍になったらアクセス禁止状態になるみたいでした。つまり、VBATが4.5Vもあるとアクセス禁止です。

DS1307 DATASHEET

ちゃんと3.3Vのレギュレーターなどをつなげようかなど色々と考えた結果、抵抗分圧で良いのでは?ということで以下のような回路としました。この回路定数でだいたい3.5Vあたりまでで安定します。もうちょっとR5の抵抗値が大きいほうが安全かもしれないです。(800Ωあたりとか)

I2Cボード・リリース2の検討

I2Cについては以下の参考書なども読みまして、内容はH8やPICの話がベースですが大変参考になっているわけであります。

マイコンの1線2線3線インターフェース活用入門―PICとH8で具体的な1-Wire、SPI、I2Cプログラミングを行う (マイコン活用シリーズ) | 中尾 司 |本 | 通販 | Amazon
Amazonで中尾 司のマイコンの1線2線3線インターフェース活用入門―PICとH8で具体的な1-Wire、SPI、I2Cプログラミングを行う (マイコン活用シリーズ)。アマゾンならポイント還元本が多数。中尾 司作品ほか、お急ぎ便対象商品は当日お届けも可能。またマイコンの1線2線3線インターフェース活用入門―PICとH...

この書籍のコラムに「汎用I/OポートでI2C通信をする場合」に関するコラムがありまして、KZ80マイコンやPC-8001用I2Cポートリリース1で実装したポートをHiZ(Hレベル)と出力Lレベルでコントロールする方法とは別に、汎用入出力ポート2つを使って通信をするという話が出てました。I2C信号線それぞれに出力用と入力用の2ポートを使うという構成です。これだと入出力方向の決定は初期設定時1回でOKとなります。その代わり、出力ボートに74HC07などのオープンコレクタ(オープンドレイン)のバッファゲートICを装備する必要があります。
8255(PPI)のポートCは8ポート中2ポートを使っているだけですし、4bit分づつ入力/出力設定を分けることも出来ますので行けそうです。
中日電工さんがロジックICで同様のI2C通信回路を公開されていますが、信号線のところに74HC03を使用されています。

マイコン独立大作戦「ROM/RAM/RTCボードの製作」
ROM/RAM/RTCボードの製作

I2Cボード・リリース2の回路図と動作確認

回路図はこのような感じになりました。I2Cデバイスの切り替えについては74HC4051を新たに買ったので8分岐にチャレンジです。(当面は4デバイスしか手持ちは無いですが)

あとは、またユニバーサル基板で試作するので配線の都合上74HC4051でつくるI2C SDAライン切り替えのコントロールは、8255(PPI)ポートBを使用することにしました。自作した基板はこんな感じです。

RTC DS1307、DS3231との通信ドライバーもシンプルになりまして、SDA、SCL信号線をON/OFFするロジックもリリース1のように8255(PPI)の初期化をしまくるのではなく、以下のように純粋にポートCの各ビットのON/OFFとなりました。(詳しくは、こちらをご覧ください。)

;--------------------------------------
; SDA_ON/OFF
;--------------------------------------
SDA_ON:
	LD  	A,SDA_HIGH
	OUT	(PPI_CTL),A
	RET

SDA_OFF:
	LD  	A,SDA_LOW
	OUT	(PPI_CTL),A
	RET

;--------------------------------------
; SCL_ON/OFF
;--------------------------------------
SCL_ON:
	LD  	A,SCL_HIGH
	OUT	(PPI_CTL),A
	RET

SCL_OFF:
	LD  	A,SCL_LOW
	OUT	(PPI_CTL),A
	RET

このZ80機械語ドライバー部分を取り込んだRTC読み書き機械語サブルーチンを、N-BASICのUSER関数からCallできるようにしまして、N-BASICのDATE$、TIME$で日時設定できるうようになりました。機械語サブルーチンとN-BASIC間は文字列でやりとりするようにしています。
こちらがハード、ソフトの完成写真です

いったんハード、ソフトが出来上がりましたのでgithub上もリリース2としてタグ付けしました。まだEEPROMのテストが未済なので、今後テストしていきたいと思ってます。

Release リリース2.0 · kuninet/PC8001-I2C
REV2基板です I2C信号SCL/SDAラインにオープンドレインバッファを装備して、PPIの入出力ポートを2つづつ使用する形へ変更しました。

コメント