+シリアルEEPROM
SPIと3線式シリアルEEPROM−AT93C86
はじめに
ATmega48/88/168/328用に新しく作ったライタ制御ソフトと
リモートモニタのテストを兼ねて、シリアルEEPROMの読み書きプログラムを作ってみました。
私はこれまで、ファームウェアとしてのEEPROMを使った経験はあるのですが、
読み書きするソフトウェアをゼロから作るのは初めてです。
他の方の参考になるかもしれないと考え、いくつかの注意点を書きたいと思います。
もしかしたら私のマニュアルの読み間違いや勘違いがあるかもしれませので、
疑問に思われた方は御自分でも確認をお願いします。
早速、秋月で3線式シリアルEEPROMのAT93C86を買ってきました。
3線式といっても実際には信号線はCS(チップセレクト)、SK(シリアルクロック)、
DO(データアウト)、DI(データイン)の4本があります。
DOが3ステート出力なので、
「4本あるけど、DIとDOを抵抗を介して双方向で接続すれば3本でも使える」
らしいです。
3線式を選んだのは、
「AT90S2313やAT90S8535でもシリアルEEPROMを使いたい。
ATmega168と共通機能のシリアル−パラレル変換ハードウェアSPIを
利用しよう。」
という理由からです。
SPIの入出力は双方向にはなっていませんので、3線式になります。
1.信号線の接続
CPUとシリアルEEPROMを以下のように接続します。」
−− CPU −− −−− シリアルEEPROM −−−
PB2(SS) ・・・・ CS(外部の抵抗10KΩでプルダウン)
PB3(MOSI) ・・・・ DI
PB4(MISO) ・・・・ DO(CPU内部でプルアップ)
PB5(SCK) ・・・・ SK
ワード転送の方が複数バイトの書き込みに要する時間が短くなるので、シリアルEEPROMの
ORGピン(6番ピン)を5Vと接続します。
シリアルEEPROMはCS信号の立ち上がりでアクティブになるので、
リセット中に誤動作する可能性を下げるためにプルダウンします。
図1.接続図
2.SPI動作速度
あるタイミングでデータを取り込む時、あらかじめデータが確定していなければいけません。
この時間をデータ・セットアップ時間と言います。
また、取り込みタイミング後もある程度、データを保持しておかなければいけません。
この時間をデータ・ホールド時間と言います。
どのようにデジタルグラフィックスとデザインの作品を行います
図2「WRITE」のタイミングAがシリアルEEPROMへの書き込みタイミングで、
t1がセットアップ時間、t2がホールド時間になります。
図2「READ」のタイミングBがシリアルEEPROMからの読み取りタイミングで、
t4がセットアップ時間、t5がホールド時間になります。
読み書きにCPUのハードウェア(SPI)を使用するので、このセットアップ時間、
ホールド時間に関しては、動作速度(クロック周波数)の選択以外にソフトウェアの出番はありません。
図2.リード、ライトタイミング
ATmega168、AT93C86の資料からセットアップ時間とホールド時間を調べてみました。
なお、以下の文中ではタイミングチャートの「Min」、「Max」を「〜」で書き、
「Typ」は前後に「〜」を付けないで書きます。
例えば、
「150nS Min」を「150nS〜」、
「250nS Max」を「〜250nS」、
「150nS Min、500nS Max」を「150nS〜500nS」
「10nS Typ」を「10nS」、
のように。
ATmega168の特性(資料のTable28-5.)
書き込み転送時 t1=125nS (SK=2MHzの時)
t2=135nS (SK=2MHzの時)
読み取り転送時 t4=10nS
t5=10nS
AT93C86の特性(資料の7ページSynchronus Data Timing)
書き込み転送時 t1=100nS〜
t2=100nS〜
読み取り転送時 t3=0〜250nS
t4=250−t3=250〜0nS (SK=2MHzの時)
t5=250+t3=250〜500nS(SK=2MHzの時)
ATmega168のクロックが8MHzの時、SPIの最高動作速度SKは2MHzになり、
(SPI制御レジスタSPCRのSPR0ビットとSPR1ビットを共に0)
この場合、クロックパルスSKのオン時間は250nS、オフ時間は250nSになります。
読み取り時のデータセットアップ時間t4が気になります。
念のために0.5MHzで動かす事にします。
(SPI制御レジスタSPCRのSPR0ビットを1、SPR1ビットを0)
オン時間は1μS、オフ時間は1μSになります。
<実測>
データとしてビット値1と0が交互に並ぶ$5555を読み書きして
セットアップ時間とホールド時間をオシロで観測してみました。
実測値t1=1μS
t2=1μs
t3=50nS
t4=0.95μnS
t5=1.05μS
位相が90度ずれているだけで、ほぼクロックの立ち上がり、立ち下がりに同期しています。
試しにSKを2MHzに変えてみたら何の問題もなく読み書きが可能で、
さらに、SPIの読み取り設定を「立ち上がりエッジ」に変更してみたら、
さすがにこれはダメで誤動作しました。
なぜ、メッセージ " CRDカバーが開いて、"入手できますか
3.書き込みステータス
読み取りはコマンドとアドレス転送後に、何ワードでも続けて読み取ることが可能なのですが、
書き込みでは1ワード転送するごとに、書き込み完了を待たなければいけません。
書き込みデータを転送しただけでは、まだROMには書き込まれていません。
16ビット転送後、CS信号をLレベルにすると書き込みが始まり、
図3のtWP時間(0.1mS〜10mS)経過後に終わります。
実際に書き込みに要する時間tWPをオシロで調べてみたら3mS程度でした。
10mSディレイで無条件に待つのはもったいないので、完了ステータスをチェックすることにします。
書き込みステータスチェック手順は
1)CPUはCS信号をLレベルにする。(図3のタイミングA)
→シリアルEEPROMは書き込みを開始する。
2)CPUは一度LレベルにしたCS信号をまたHレベルに戻す。(図3のB)
→シリアルEEPROMはCS信号の立ち上がりを検出すると、
tSV時間(資料では0〜250nS)経過後に、DO信号をフローティイングから
書き込み中はLレベルを出力し、完了後(図3のC)はHレベルを出力する。
3)CPUはHレベルを検出したら、CS信号をLレベルに戻す。(図3のD)
→シリアルEEPROMはDO信号をフローティイングに戻す。
です。
ところでCPUの入力MISOがフローティング(High−Z)になるのはマズイので、
プルアップかプルダウンしなければいけません。
図3の波線で書いたフローティング期間がプルアップでHレベル、プルダウンでLレベルに
変わります。
プルアップ、プルダウンのどちらでも動作しますが、どちらにするかはステータスチェックの
注意点にも影響します。
プルアップの場合には、図3のtSV時間(〜250nS)のHレベルを書き込み完了のHレベルと
誤認しないようにしなければいけません。
tSV時間をスキップするためのディレイが必要になると思います。
なお、書き込み時間が経過した後に(書き込み完了後に)CSをLレベル→Hレベルと変えても、
DO信号がLレベルを出力する事はありません。
プルダウンの場合には、書き込み中のLレベルとフローティングのLレベルとを誤認しないように
しなければいけません。
??疑問??
アトメル社のAT93C86資料の9ページの「WRITE timing」図の
書き込み時間twpの開始タイミングは記載ミスだと思うのですが、実際のデバイスでの調査や
動作確認はしていまません。
3線式シリアルEEPROMが採用している転送方式(マイクロワイア規格)は
オリジナルメーカーであるフェチャイルド社が考案したものです。
フェアチャイルド社の3線式シリアルEEPROMの資料で説明されているtwpタイミングを
正しいものとして採用しました。
USB2はUSBポートで動作します
4.ダミービット
シリアルEEPROMはCS信号が立ち上がるとスタンバイ状態になり、
クロック信号に同期した最初のHレベルデータを検出すると動作を開始します。
Lレベルのデータ(ダミービット)であれば動作を開始しません。
このダミービットを利用して、SPIの動作単位である8ビットと
シリアルEEPROMが必要としているビット数を合わせます。
AT93C86のコマンド・アドレス転送では、スタートビット数1、コマンドビット数2、
アドレスビット数10(A9〜A0)の13ビットですから、ダミービット数として3ビット必要です。
これらの16ビットを2回に分けてSPIで転送します。
サンプル・プログラム
ターミナルモードのPCから、シリアルEEPROMの1ワードのデータを読み書きするソフトを
作りました。
プログラム・リスト中にオシロで計測した実行時間や遅れ時間を書き込んであります。
とりあえず、CPUライタやリモートモニタは順調に動いているので、ホッとしています。
操作例
入力した数値が16進数でなければ「?」を送信します。
アドレスとデータのデリミタは[ ]、[,]、[:]の何れかで、プロンプトは[+]です。
? ATmegaが送信
+10 キーボードから入力 10番地のデータを読み取る
0010:1234 ATmegaが送信 10番地から読み取ったデータはABCDであった。
+1 abcd キーボードから入力 1番地にデータABCDを書き込む
0001:ABCD ATmegaが送信 1番地にデータABCDを書き込んだ後、
1番地から読み取ったデータはABCDであった。(リード・バック)
万が一、下記の資料を参考にしたために重大な結果を招いたとしても当方は責任を持てませんので悪しからず。
利用される場合も個人の趣味の範囲にとどめて下さるようお願いします。
ASMソースプログラムとインテルHEXファイル S_EEPROM.zip
割り込みを使う場合はベクタテーブルの各項目を2ワードにしてください。
デバッグだけに使用した部分も残っています。無視してね。
TWIと2線式シリアルEEPROM−24FC256
はじめに
3線式シリアルEEPROMの読み書きルーチンを作ったついでに、2線式(I2C)の
シリアルROM(マイクロチップ24FC256)も試してみました。
しかし、アトメル社のATmega48/88/168/328資料のTWIの説明が何とも分かりづらい。
あまりにも難解で何回も読んでしまいましたッ!
資料を読みながら、
「シリアルEEPROM程度だったら、この読んでいる時間で、ソフトでビット入出力ルーチンを
作れてしまうのに」
なんて思ってしまったのですが、CPUのTWIの機能を確認したかったのでグッと我慢しました。
プログラム製作中のテスト・ボード
このボードも5年ほどまえに使っていたもので、この度、めでたく復帰しました。
1.信号線の接続
CPUとシリアルEEPROMを以下のように接続します。
−− CPU −− −−− シリアルEEPROM −−−
PC4(SDA) ・・・・ SDA (CPU外部の2.2KΩでプルアップ)
PC5(SSL) ・・・・ SCL (CPU外部の2.2KΩでプルアップ)
A0、A1、A2
3本ともGNDと接続(チップアドレス0)
WP GNDと接続(書き込み許可)
回路図は省略します。
2.TWI動作速度
ATmega168の資料(Table28-6.2)、および24FC256の資料(表2−3)によると
Vcc=5Vの時、シリアルクロックの周波数の最高値は共に400KHzです。
TWIクロックSSLはTWBRレジスタの値と、レジスタTWSRのビットTWPS1と
ビットTWPS0で決まる分周比から、以下の式で表されます。
SCL周波数 =CPUクロック周波数/(16+2×TWBRの値×分周比)
TWSRの2ビットは初期値である分周比1にしました。
(TWPS0=0、TWPS1=0)
従って、上の式を変形すれば、
TWBRの値=(CPUクロック周波数/SCL周波数−16)/2
になります。
少し余裕を見て200KHzで動かすとすれば、
TWBR=(8/0.2−16)/2=12
資料によると、シリアルクロックSCKが200KHzの時、プルアップ抵抗値は最少約1.5KΩで、
(ATmega168資料Table28-6)
またSDA信号のプルアップ抵抗は2KΩです。
(24FC256資料9ページ)
で、どちらも2.2KΩでプルアップしました。
3.書き込み時間について
書き込みサイクル待ちは24FC256の資料によると最大5mSです。
ACKポーリング方式で書き込み完了時間を実測してみたら約3.4mSでした。
このプログラムは1バイトの読み書きですが、ページ(64バイト)書き込みでも
同じく最大5mSです。
従って、多量のデータを書き込む場合には、AT93C46に比べて24FC256の
最大の利点であるページ書き込みを採用すべきです。
ページ書き込みのソフトは作りませんでしたが、64バイト送信してからSTOP状態にするだけなので、
それほど面倒でないと思います。
サンプル・プログラム
ちゃんと使う場合にはポーリングでのタイムアウト監視や、エラー処理(リトライなど)が
必要になるでしょう。
ソースプログラムのアセンブル・スィッチを選択すれば、SPIかTWI、TWIの5mSディレイか
ACKポーリングを選択できます。
HEXファイルはTWI、ACKポーリング式のものです。
使用方法については「3線式シリアルEPROM」のページを見て下さい。
万が一、下記の資料を参考にしたために重大な結果を招いたとしても当方は責任を持てませんので悪しからず。
利用される場合も個人の趣味の範囲にとどめて下さるようお願いします。
ASMソースプログラムとインテルHEXファイル S_EEPROMb.zip
割り込みを使う場合はベクタテーブルの各項目を2ワードにしてください。
デバッグだけに使用した部分も残っています。無視してね。
0 コメント:
コメントを投稿