| ホーム | 私の電子工作作品集 |
[ 初公開日:2013年6月17日 ] |
最近、Yahoo!オークションに少しばかりはまっており、安く落札した各種サイズのスタティック RAM が、どんどんと溜まってきました。 Yahoo!オークションで落札するのはいいのですが、果たしてこれらの RAM は生きているのでしょうか? ・・・ もし不良品であればそんなゴミばかりをいくら集めてもまったく意味がありません。 そこで、各種メモリサイズに対応できる RAM チェッカーを、PICで作ることにしました。 2K バイト、8K バイト、32K バイト、64K バイト、128K バイトの5種類に対応した仕様です。 |
|
ケースに収納 ( 2016/1/26 更新 ) 本機は、長い間、左上写真に示すようにプリント基板のままにしてありましたが、この度、右上写真のようにケースに収納しました。 プリント基板のままで使用していると、何と言っても埃っぽくなってくることと、本機の性格上、頻繁に使用するわけでもないので、 使用しないときの保管性が悪くなることがあげられます。 今まで、本機のために何か良いケースはないものか、と常に思ってはいたのですが、なかなか思わしいものが見つからずにいました。 そこで "CPUの創りかた TD4" で使用した物と同じ、"フリーケース A5 L8998 (サナダ精工株式会社)" を この作品のケースとしてはどうか、と思って使用してみました。 ただ、本機を収納するだけではケースサイズが大き過ぎるので、同種のチェッカー "簡易 S-RAM チェッカー (1 bit/4 bit)" と同居させることにしました。 重大なバグを修正 ( 2018/6/23 更新 ) 本機で SRAM のチェックをしている最中に、PIC の PORTB と入力データの制御用バスバッファ 74HC541 の出力、および SRAM のデータバスと出力データの制御用フリップフロップ 74HC574 の出力が、 それぞれデータ衝突を起こしているという重大なバグがあることが分かりました。 ハードウエアの一部修正とともにプログラムの修正でデータ衝突を起こさないように対処しました。 詳細は、プログラムの項の 該当の説明 を参照してください。 全チェックパタン自動実行の機能追加 ( 2018/7/7 更新 ) 4つのすべてのチェック方法を実施する場合には、DIP スイッチを操作することなくタクトスイッチの簡単な操作だけで、すべてのチェック方法を自動的に実施できる機能を追加しました。 詳細は、プログラムの項の 該当の説明、機能概要と使用法の項の 機能追加 を参照してください。 |
( 2018/6/23 更新 ) 上記の回路図は、プログラムバグの修正に伴うハードウエアの変更と、その他数点の見直しをした変更後のものに差し替えてあります。 変更前の旧回路図(StaticRamChecker4x.gif)も参考のために こちら に残しておきます。 旧回路図では、 LCDの E端子、すなわちPICの RD0 ポートに 47KΩのプルダウン抵抗が付いていましたが、何の目的で付けたのか8年も経った今となっては私自身でも謎です。 間際らわしいので削除しました。 |
| 回路図 (StaticRamChecker.CE3) | ページトップ |
当初、本装置のハードウエア設計をするに当たって、PIC16F877A だけでは I/O数が足りないため、
昔からの古い知識と在庫がいっぱいあると言う単純な理由から、PPI 8255A で I/O数を増やそうと安易に回路に組み込みました。
そしてプリント基板も完成させました。 ところが、いざプログラムを組みだしてから始めて気がつきました。 ・・・ PIC では 8255A は使えない ・・・ 当然ながら 8080A/8085A で 使用するような使い方はできないのです。 8255A を制御するための A0, A1, /CS, /RD, /WR 信号等を、PIC のプログラムで いちいち作り出してやらなければなりません。 がっくりきました。 このままのハードウエアでは、PIC → 8255A → Flip-Flop IC → RAM と、かなり面倒な過程のプログラムに なってしまいます。 もう一度考え直しです。 そして最も手抜きな方法で解決することにしました。 一応完成しているプリント基板には あまり手を加えたくありません。 8255A を ICソケットから抜いてしまい、その後の入出力の信号線を回路図中の ・・・ 線のように直結してしまう、と言うものです。 プログラムも PIC → Flip-Flop IC → RAM の制御でよくなりました。 次に配線を施したフラットケーブル用の ICソケットコネクタの 写真を示します。 8255A 用 ICソケットに差し込みます。 また、本装置では電源供給に、スイッチングレギュレータ等の DC+5V 出力を、直接供給するようにしてしまいましたが、 これはどちらかと言うと失敗でした。 それは RAM の Vcc 電源をトランジスタでスイッチングしているため、当然ながら 0.6V 程度の 電圧降下が起こります。 結果として、RAM のチェックにはあまり影響はなかったようですが、チェッカーとして感心できません。 電圧降下分を上乗せした電圧をスイッチングのトランジスタに与えるべきです。 本装置には DC+9V または DC+12V を供給し、本装置内で一般 IC用の DC+5V と、RAM 用の電圧降下分を上乗せした電圧を作り出すべきです。 次に、それらを考慮した電源部の回路図を参考までに示しておきます。 本装置のチェックに要する所要時間を正確に測定するためには、BUSY 信号が出力されている時間を測定すればいいのですが、そのまま 単純に外部に引き出したのでは少々心許ないし、プリント基板にも空きエリアがありましたので気休めにバッファを入れておきました。 また、その時間測定には "長時間ストップウオッチ/タイマー" を使用するのですが、そちらへの 電源供給も簡単に行なえるように、プリント基板上に供給用の電源端子も設けておきました。 |
| ページトップ |
冒頭でも述べたように、本機の "簡易 S-RAM チェッカー (8 bit)" と 姉妹機の
"簡易 S-RAM チェッカー (1 bit/4 bit)" を、同一ケース内に同居させました。 ケース内の上部約 1/3
に位置する部分に "簡易 S-RAM チェッカー (1 bit/4 bit)" を、その下部の約 2/3 に位置する部分に "簡易 S-RAM チェッカー (8 bit)"
を収納しました。 下の写真からも分かるように、ケース内の上下スペースには空きがなくいっぱいいっぱいですが、本機の右横には中途半端なサイズのスペースが 空いています。 どちらのチェッカーも、プリント基板の左横側に電源供給の DCジャックが取り付けてありますので、ケース内に収めたときに プリント基板の左側にはスペースを空けられません。 (ケースの左側面には、それぞれの電源供給用のプラグが挿入できるように、 ○穴が開けてある) そこで、この中途半端なサイズのスペースの有効利用方法が特にありませんので、写真(黒色部分)のように、とりあえず導電スポンジを 敷き詰めておきました。 これは、被測定用 S-RAM の一時的な退避場所に使用することを想定しています。 あとは本機を使用しないときに、 電源供給用の小型スイッチングACアダプタをこのスペースに収納しておく、くらいの利用方法しか思い付きません。 |
|
| ページトップ |
|
| ページトップ |
実際に RAM をチェックするに当たって、具体的にはどのようなことを行なえばいいのか、実のところ
良くわかっていません。 基本的には、ある番地に書き込んだ内容を一定時間後に読み出してみて、両者の内容が比較一致すれば
問題はない ―― と判断をしました。 200n Sec の基準クロックで動作しているPICで RAM のアクセスタイムがどうの ・・・
と言っても始まりません。 そこでとりあえず次の4つの方法を考えてみました。 高級言語風のプログラムらしきものは、
チェックする方法の考え方の概要を表します。 実際には SELECT_1,0 スイッチの指定でどの方法でも選択できるように、
それぞれのチェックパタンを割り当てています。 (1) sel_sw = b'00' の場合 1つのメモリアドレスに付き、まず h'00' のデータを書き込んで次にすぐ読み出し、両者のデータ内容を比較して一致すれば OK で、 次にデータを h'01' にして同様チェックをし、次々にデータを1ずつインクリメントしながら h'FF' まで繰り返す。 h'00' から h'FF' までの 256 種類の全データパタンが終了したなら、次に、1つインクリメントした次のメモリアドレスについて同様チェックを 行なう。 ・・・ これを 0 番地から MAX 番地までの全アドレスについて行なう、というものです。 for ADDRESS = 0 to max for W_DATA = 0 to 'ff' (write) (read) if R_DATA = W_DATA then OK else NG endif next next(2) sel_sw = b'01' の場合 1つの同一のデータパタンを、まず 0 番地から MAX 番地までの全アドレスについて一気に書き込みます。次にまた 0 番地に戻って、 その内容を読み出し先に書き込んだ内容と比較して一致すれば OK で、1ずつインクリメントした次々のメモリアドレスについて 同様チェックを行ないます。 MAX 番地までの全アドレスについて比較チェックが済んだなら、次にデータを1つインクリメントして 同様、全アドレスについてチェックを行ないます。このようにデータ内容を h'00' から h'FF' までの 256 種類の全データパタンに ついて繰り返しチェックします。 for W_DATA = 0 to 'ff' for ADDRESS = 0 to max (write) next for ADDRESS = 0 to max (read) if R_DATA = W_DATA then OK else NG endif next next(3) sel_sw = b'10' の場合 基本的には (2) のチェック方法と同じですが、書き込むデータ内容が異なっています。(2) ではアドレスのループ内で扱うデータ 内容は一定ですが、この (3) ではアドレスのループ内で扱うデータは常に1ずつインクリメントしています。要するに、隣同士の アドレスでは扱っているデータの内容が1ずつ異なっています。 for wk = 0 to 'ff' W_DATA = wk for ADDRESS = 0 to max (write) W_DATA = W_DATA + 1 next W_DATA = wk for ADDRESS = 0 to max (read) if R_DATA = W_DATA then OK else NG endif W_DATA = W_DATA + 1 next next(4) sel_sw = b'11' の場合 (1) と同様に、まず1つのメモリアドレスに着目しながら、 0 番地から MAX 番地までの全アドレスについてチェックを行なって いく方法をとりますが、書き込むデータパタンが異なっています。 (1) のように全データパタンは書き込みません。ある人の 意見を取り入れたものですが、全データパタンを書き込まなくても、 h'01', h'02', h'04', h'08', h'10', h'20', h'40', h'80', h'00' の9つのパタンだけで十分と言うものです。 h'FF', h'55', h'AA' については私が付け加えたものです。 for ADDRESS = 0 to max for W_DATA = '01','02','04','08','10','20','40','80','00','ff','55','aa' (write) (read) if R_DATA = W_DATA then OK else NG endif next nextSRAM タイプの事前整合性チェック(機能追加) 初めはチェックする SRAM が最もメモリ容量の大きなもの、すなわちICピン数が最も多いものと仮定してチェックを行い、書き読みの 結果がNGだった場合には、順次、次のメモリ容量のもの・・・というように仮定するメモリ容量を変更しながら試験をしていきます。 これはICの Vcc ピンが最も外側に配されていることを考慮したもので、不用意に Vcc ピン以外に電源を繋がないようにと 配慮をしたためです。 チェックの内容は、それぞれの SRAM タイプにしたがった最終アドレスに、h'FF' のデータを書き込み、次に同アドレスを読み出して、 その内容が h'00' 以外であれば、とりあえず書き読みができたものとしてループを抜け出し、次にその整合性の判定をします。 すなわち、仮定した SRAM タイプと実際にセットした SRAM タイプが一致していれば整合性はOKとなる訳です。 ただし、最終アドレスだけの単純な方法ではそれぞれのタイプの区別がつきません。そこで一工夫を凝らして区別がつくようにサイズ別に 考慮をしています。(詳細はプログラムリストを参照のこと) for Ram = 128K, 64K, 32K, 8K, 2K if Ram < Type exit for endif ADDRESS = max W_DATA = 'ff' (write) (read) if R_DATA <> '00' then if Ram <> 2K (A11 bit check) select case Ram case 128K (A16 bit check) case 64K (A15 bit check) case 32K (A13 bit check) case else exit for end select if R_DATA <> '00' then exit for endif else exit for endif endif next if Ram >= 2K then if Ram = Type OK else NG endif else NG endif |
重大なプログラムバグを修正 (Ver. 1.05) ( 2018/6/19 更新 ) 先日、本機 S-RAM チェッカーと同種(似ている)の回路図、およびプログラムを作成していて、本機には重大な誤りがある事に気が付きました。 それは、そもそも本機では当初の設計では PIC の PORTB と SRAM の DATA バス間の接続には、間に PPI 8255A を挟んで専用の入力ポートと出力ポートに分けて制御するつもりでいたのですが、 その制御が面倒になることが予測されたので PPI 8255A の使用は止めて、入出力データをまとめて PIC の PORTB と直結してしまったことが一因で、また、74HC574(データ出力)用と 74HC541(データ入力)用の2個の ICを制御するために、インバータで反転してはいますが同一の信号(PC4)で行っていることに起因しています。 次のリストは、その重大な誤りがあった部分をプログラムリスト(修正前の rdata_lcd_ram サブルーチン)から抜き出したものに、より分かりやすくするために Flip_Flop_Set マクロ命令を展開した命令群を コメントとして付け加えたものです。 そして、リストの一番右側に記した(データ衝突−1)から(データ衝突−4)の4か所の部分でデータ衝突を起こしています。 ---(修正前リスト)--- : : movlw ramOE xorlw h'ff' andwf ram_cont,F ;SRAM /OE だけを 'L' にする Flip_Flop_Set ram_cont, PC5,2 ;bit5: 74HC273(コントロール) CK ;; movf ram_cont,W ;; ┐ ;; movwf SRAM ;; │ ;; bsf CONT,PC5 ;; (マクロ展開) SRAM が Read モードになる ..... (1) ;; ┐ ;; nop ;; │ ;; │ ;; bcf CONT,PC5 ;; ┘ ;; │(データ衝突−1) ;; │ bsf CONT,PC4 ;74HC541(データ入力) /G1,/G2 有効, 74HC574(データ出力) /OE 無効 ..... (2) ;; ┤ ;; │ bcf STATUS,RP1 ;バンク 1 ;; │(データ衝突−2) bsf STATUS,RP0 ;; │ movlw b'11111111' ;; │ movwf TRIS_RAM ;RB7-0: 入力 の設定 ..... (3) ;; ┘ ; bcf STATUS,RP1 ;バンク 0 bcf STATUS,RP0 movf SRAM,W ;SRAM データの読み出し movwf ram_data_i ;SRAM の 入力データ ; bcf STATUS,RP1 ;バンク 1 bsf STATUS,RP0 clrf TRIS_RAM ;RB7-0: 出力 の設定 ..... (4) ;; ┐ ; bcf STATUS,RP1 ;バンク 0 ;; │ bcf STATUS,RP0 ;; │(データ衝突−3) ;; │ bcf CONT,PC4 ;74HC541(データ入力) /G1,/G2 無効, 74HC574(データ出力) /OE 有効 ..... (5) ;; ┤ ;; │ movlw ramOE ;; │ iorwf ram_cont,F ;SRAM /OE を再び 'H' にする (SRAM を Write モードにする) ;; │(データ衝突−4) Flip_Flop_Set ram_cont, PC5,2 ;bit5: 74HC273(コントロール) CK ;; │ ;; movf ram_cont,W ;; ┐ ;; │ ;; movwf SRAM ;; │ ;; │ ;; bsf CONT,PC5 ;; (マクロ展開) SRAM が Write モードになる ..... (6) ;; ┘ ;; nop ;; │ ;; bcf CONT,PC5 ;; ┘ : :(データ衝突−1)では、命令(1)の実行直後に SRAM が Read モードになるため、その SRAM からの出力データと 74HC574(データ出力)の出力データとが衝突し合います。 その衝突状態は命令(2)が実行されて 74HC574(データ出力)の出力が High Z(impedance) になるまで続きます。 しかし、命令(2)が実行されると今度は 74HC541(データ入力)の High Z が解かれて、その出力データと PIC の SRAM (PORTB) ポートからの出力データとが(データ衝突−2)を起こします。 その衝突状態は命令(3)が実行されて PIC の SRAM (PORTB) ポートが入力設定されるまで続きます。 また、(データ衝突−3)では、命令(4)の実行直後に PIC の SRAM (PORTB) ポートが再び出力設定されるため、(データ衝突−2)と同じ状態に戻ってしまいます。 その衝突状態は命令(5)が実行されて 74HC541(データ入力)の出力が High Z になるまで続きます。 ところが、命令(5)が実行されると今度は 74HC574(データ出力)の High Z が解かれて、その出力データと SRAM からの出力データとが衝突し合って、再び(データ衝突−1)と同じ状態になります。 その衝突状態は命令(6)が実行されて SRAM が Write モードになるまで続きます。 これらの不具合が発生する関係を概略回路図で表したものが左下の図で、今回その不具合を修正したものが右下の図となっていますが、それには下リストに示すようにプログラムも修正する必要があります。 両者の回路で大きく異なっている点は 74HC541(データ入力)を制御する信号で、左図では 74HC574(データ出力)用の制御信号 RC4 をインバートした信号で制御をしているのに対して、 右図では独立した制御信号 RC7 をインバートした信号で制御をしています。 これは左図では RC7 がたまたま空きポートになっていたために、右図で使用することができました。 これによって、74HC574(データ出力)と 74HC541(データ入力)の各 ICを制御するタイミングが連動していたのを、それぞれ独自のタイミングで決めることができるようになり、 左図回路での不具合を回避できるようになりました。 また、これらのデータ衝突は個々には数命令分が実行する間の時間で、ほんの一瞬であるかもしれないですが、1アドレスにつき4回、かつ、全データパタン(h'00' 〜 h'ff')の 256 回起こります。 たとえば、2K バイトの SRAM の場合には 4 x 2,048 x 256 = 2,097,152 回も起こり、何と 128K バイトの SRAM の場合には 4 x 131,072 x 256 = 134,217,728 回も起こることになります。 いや、現実に起こっていたのです。 最悪でした。 以下に各 ICの真理値表を示しておきます。 (真理値表の内 74HC574、74HC541、74HC273については東芝の、また CXK5864B については SONY の各データシートより抜粋)
---(修正後リスト)--- : : bsf CONT,PC4 ;74HC574(データ出力) /OE 無効 (High Z) movlw ramOE xorlw h'ff' andwf ram_cont,F ;SRAM /OE だけを 'L' にする (SRAM を Read モードにする) Flip_Flop_Set ram_cont, PC5,2 ;bit5: 74HC273(コントロール) CK bcf STATUS,RP1 ;バンク 1 bsf STATUS,RP0 movlw b'11111111' movwf TRIS_RAM ;RB7-0: 入力 の設定 ; bcf STATUS,RP1 ;バンク 0 bcf STATUS,RP0 bsf CONT,PC7 ;74HC541(データ入力) /G1,/G2 有効 (PC7:インバータ出力) movf SRAM,W ;SRAM データの読み出し movwf ram_data_i ;SRAM の 入力データ bcf CONT,PC7 ;74HC541(データ入力) /G1,/G2 無効 (High Z) ; bcf STATUS,RP1 ;バンク 1 bsf STATUS,RP0 clrf TRIS_RAM ;RB7-0: 出力 の設定 ; bcf STATUS,RP1 ;バンク 0 bcf STATUS,RP0 movlw ramOE iorwf ram_cont,F ;SRAM /OE を再び 'H' にする (SRAM を Write モードにする) Flip_Flop_Set ram_cont, PC5,2 ;bit5: 74HC273(コントロール) CK bcf CONT,PC4 ;74HC574(データ出力) /OE 有効 : :データ衝突というものは ICにとってどの程度のダメージを与えるものなのでしょうか。 もちろん、そのデータ衝突の起こり方などの条件にもよるとは思うのですが。 電源をオンすると同時にデータ衝突状態となり、電源をオフするまでの長時間にわたってその状態が続くような場合。 本機のように SRAM からデータを読み出すときだけに、しかも、 全体からするとほんの一瞬のみのデータ衝突状態ですが、SRAM の全アドレス全データパタンにわたってその状態を繰り返すような場合。 当然、条件は大きく異なってきます。 本機でチェックをしたときにダメージを受ける対象となる ICは4個。 PIC16F877A、74HC574(データ出力)、74HC541(データ入力)、それとチェックをする SRAM です。 SRAM についてはその個体のチェックをするときだけで済みますが、他の ICたちは本機を運用する度にダメージを受けることになります。 本機を製作した直後、私が所有している SRAM の全数(約 350個)すべてについてチェックを実施しました。 このことから、SRAM はともかく、本機内の3個の ICたちが受けたダメージは相当なものであったことと想像されますが、一応現在でも個々の ICとしての正常な動作を維持している(らしい)ので、 結果として ICが破壊されるような大事には至らなかったようです。 いずれにしても、たとえ一瞬にしろ本機がデータ衝突状態を起こしていたのは事実のことです。 本機を製作してから8年余り(ホームページに公開してから5年)、 その間今までは一度も内容までの見直しなどはしたことがなかったのですが、今回、ひょんなことからこの不具合を発見することになって、作者の私としてはそんな不具合を含んだまま 8年間も放置していた恥ずかしさと、それを遅まきながら修正することができてホッとした安堵感が入り混じった気持ちです。 |
チェック時間短縮の小改善の試み (Ver. 1.06) ( 2018/6/23 更新 ) 上記したように 重大なプログラムバグを修正 (Ver. 1.05) を実施後に、チェックにかかるその所要時間を測定したところ、LCD を表示させた場合には数秒ですが多く要する ようになってしまいました。 具体的には、代表として 2K バイトと 8K バイトの2個の SRAM について、それぞれ2回ずつ測定をしてみたのが次表に示すような結果(Ver. 1.05: 黄色で示した部分)で、 8年前に測定した結果(Ver. 1.04: 水色で示した部分)とを見比べてみてください。 (Ver. 1.04)から(Ver. 1.05)に修正した部分は、上記したように rdata_lcd_ram サブルーチン( SRAM から読み出し)内のみで、各命令の並び順は変更をしてありますが、新たに2命令 : : bsf CONT,PC7 ;74HC541(データ入力) /G1,/G2 有効 (PC7:インバータ出力) : : bcf CONT,PC7 ;74HC541(データ入力) /G1,/G2 無効 (High Z) : :を追加しただけで、他に命令の増減はありません。 本機では 20MHz のセラロックを使用のため基準クロックは ( 1 / 20MHz ) x 4 = 0.2μS となります。 したがって、この2命令が全体の所要時間に影響をもたらすのは、SRAM の種類別、およびチェック方法別で 考察をしてみると、 2K バイト SRAM では、チェック方法 (1) b'00'、(2) b'01'、(3) b'10' ..... 0.2μS x 2,048(アドレス)x 256(データ)x 2(命令)= 209,715.2μS = 0.2097152 秒 ≒ 0.21 秒 チェック方法 (4) b'11' ..... 0.2μS x 2,048(アドレス)x 12(データ)x 2(命令)= 9,830.4μS = 0.0098304 秒 ≒ 0.01 秒 8K バイト SRAM では、チェック方法 (1) b'00'、(2) b'01'、(3) b'10' ..... 0.2μS x 8,192(アドレス)x 256(データ)x 2(命令)= 838,860.8μS = 0.8388608 秒 ≒ 0.84 秒 チェック方法 (4) b'11' ..... 0.2μS x 8,192(アドレス)x 12(データ)x 2(命令)= 39,321.6μS = 0.0393216 秒 ≒ 0.04 秒となり、これらの値がそれぞれ(Ver. 1.04)の所要時間にプラスされることになります。 次表の(Ver. 1.04)と(Ver. 1.05)の実測値を比べてみると、LCD を非表示にした場合で チェック方法が (1) b'00'、(2) b'01'、(3) b'10' の場合には、ぴたっと計算値通りになっているのが分かります。 しかし、LCD を非表示にした場合でチェック方法 (4) b'11' の場合の実測値では、2K バイト SRAM で 0.14 秒、8K バイト SRAM で 0.45 秒の差となっており、計算値よりも 10倍以上の値で、 この点についてはどうも納得がいかない* ところです。 ( 2018/7/3 追記 * については、後述 を参照 )
; LCD へコマンドを出力 lcd_cmd bcf LCD,_RS ;RS = 0 (コマンドモードに設定) goto lcd01 ; LCD へデータを出力 lcd_data bsf LCD,_RS ;RS = 1 (データモードに設定) nop lcd01 bcf LCD,_RW ;R/W = 0 (書き込みモードに設定) call lcd_out ;上位4ビットを転送 swapf lcdtmp,W ;一時保存データの上位下位入れ替え call lcd_out ;下位4ビットを転送 call lcd_busy ;LCD ビジーチェック ;; LCD ビジーチェック return ; 4ビット一回の送出 lcd_out movwf lcdtmp ;コマンド/データを一時保存 movlw h'0f' ;下位4ビットの andwf LCD,F ;コントロールポートの内容を残し movlw h'f0' ;上位4ビットデータ andwf lcdtmp,W ;を取り出して iorwf LCD,F ;コントロールとOR bsf LCD,_E ;E = 1 (動作起動信号の設定:Hでストローブ) nop ;E のパルス幅を220ns以上確保するため bcf LCD,_E ;E = 0 (動作起動信号の設定:Lに戻す) return ; LCD ビジーチェック lcd_busy bsf STATUS,RP0 ;バンク 1 movlw b'11110000' ;上位4ビットを入力ポート iorwf TRIS_LCD,F bcf STATUS,RP0 ;バンク 0 bcf LCD,_RS ;RS = 0 (コマンドモードに設定) nop bsf LCD,_RW ;R/W = 1 (読み出しモードに設定) lcd_busy01 bsf LCD,_E ;E = 1 (動作起動信号の設定:Hでストローブ) ;; ─┐ movf LCD,W ;DDRAM からのデータ(上位4ビット)の読み出し ;; │ bcf LCD,_E ;E = 0 (動作起動信号の設定:Lに戻す) ;; │ ; andlw h'f0' ;上位4ビット ; │ movwf lcdtmp ;読み出しデータを一時保存 ;; │ ; swapf lcdtmp,F ;下位4ビットに移動 ; │ ; この部分が何度も繰り返される bsf LCD,_E ;E = 1 (動作起動信号の設定:Hでストローブ) ;;(ビジーフラグ _BF = 0 movf LCD,W ;DDRAM からのデータ(下位4ビット)の読み出し ;; になるまでループする) bcf LCD,_E ;E = 0 (動作起動信号の設定:Lに戻す) ;; │ ; andlw h'f0' ;上位4ビット ; │ ; iorwf lcdtmp,F ;上位4ビット + 下位4ビット ; │ ; swapf lcdtmp,F ;上位4ビットと下位4ビットを入れ替え ; │ btfsc lcdtmp,_BF ;ビジーフラグのチェック (読み出しデータの7ビット目) ;; │ goto lcd_busy01 ;_BF=0 になるまでループ ;; ─┘ bcf LCD,_RW ;R/W = 0 (書き込みモードに設定) bsf STATUS,RP0 ;バンク 1 movlw b'11110000' ;上位4ビットを出力ポートに戻す xorwf TRIS_LCD,F bcf STATUS,RP0 ;バンク 0 returnなお、所要時間の測定には、(Ver. 1.04)のときに使用した "長時間ストップウオッチ/タイマー" と同じものですが、1年ちょっと前にプログラム変更を 行ってはいますが、ストップウオッチに使用している LCD 表示の内、秒と秒以下( 1 / 100 秒 )の区切り記号の ":(コロン)" を ".(ピリオド)" に変更しただけで他の変更はありません。 そのような訳で、(Ver. 1.05)になって余分に費やしてしまう時間を、何とか取り戻すことができないものかと試みたのが、次に示す(Ver. 1.06)のリストで、 全アドレスにわたって 必ず実行されるのが、次の wdata_lcd_ram サブルーチン(SRAM への書き込み)と rdata_lcd_ram サブルーチン(SRAM から読み出し)です。 wdata_lcd_ram サブルーチン内では、(Ver. 1.05)で5命令だったのを(Ver. 1.06)では2命令にして計マイナス3命令、ただし、2K バイトの SRAM だけはこのルーチンを通らないのでプラスマイナス零です。 また、rdata_lcd_ram サブルーチン内では、すべての SRAM の種類において5命令だったのを2命令にして計マイナス3命令となり、したがって、両者を合わせると全体では 2K バイト SRAM ではマイナス3命令、 それ以外の SRAM ではマイナス6命令となります。 この命令数を減らしたことによる全体の所要時間に影響をもたらす効果を、上記の場合と同様に SRAM の種類別、およびチェック方法別で考察をしてみると、 2K バイト SRAM では、チェック方法 (1) b'00'、(2) b'01'、(3) b'10' ..... 0.2μS x 2,048(アドレス)x 256(データ)x -3(命令)= -314,572.8μS = -0.3145728 秒 ≒ -0.31 秒 チェック方法 (4) b'11' ..... 0.2μS x 2,048(アドレス)x 12(データ)x -3(命令)= -14,745.6μS = -0.0147456 秒 ≒ -0.01 秒 8K バイト SRAM では、チェック方法 (1) b'00'、(2) b'01'、(3) b'10' ..... 0.2μS x 8,192(アドレス)x 256(データ)x -6(命令)= -2,516,582.4μS = -2.5165824 秒 ≒ -2.52 秒 チェック方法 (4) b'11' ..... 0.2μS x 8,192(アドレス)x 12(データ)x -6(命令)= -117,964.8μS = -0.1179648 秒 ≒ -0.12 秒となります。 この計算値を上表の LCD を非表示にした場合の(Ver. 1.05: 黄色で示した部分)と(Ver. 1.06: 緑色で示した部分)の実測値の差と比べてみると、 すべてのチェック方法において見事に一致しますので、上式で示すだけの効果が現れていることが分かります。 : : ramOEb equ 1 ;SRAM /OE: アウトプットイネーブルのビット位置 ;;(Ver.1.06 で追加) ramWEb equ 2 ;SRAM /WE: ライトイネーブルのビット位置 ;; ramOE equ h'02' ;SRAM /OE: アウトプットイネーブル ramWE equ h'04' ;SRAM /WE: ライトイネーブル : : wdata_lcd_ram ; SRAM 書き込み : : wdata02 ;; movlw ramWE ;;(Ver.1.06 で変更) ;; xorlw h'ff' ;; ;; andwf ram_cont,F ;SRAM /WE だけを 'L' にする ;; bcf ram_cont,ramWEb ;; : : ;; movlw ramWE ;;(Ver.1.06 で変更) ;; iorwf ram_cont,F ;SRAM /WE を再び 'H' にする ;; bsf ram_cont,ramWEb ;; : : rdata_lcd_ram ; SRAM 読み出し : : ;; movlw ramOE ;;(Ver.1.06 で変更) ;; xorlw h'ff' ;; ;; andwf ram_cont,F ;SRAM /OE だけを 'L' にする (SRAM を Read モードにする) ;; bcf ram_cont,ramOEb ;; : : ;; movlw ramOE ;;(Ver.1.06 で変更) ;; iorwf ram_cont,F ;SRAM /OE を再び 'H' にする (SRAM を Write モードにする);; bsf ram_cont,ramOEb ;; : :なお、依然として納得がいかない点は、上記でも述べたように LCD を非表示にした場合でチェック方法が (4) b'11' のときの実測値が、(Ver. 1.04)と(Ver. 1.05)では 計算値のようにはならず 10倍以上の値を示していることです。 計算値では rdata_lcd_ram サブルーチン(SRAM から読み出し)の命令数の増加だけで計算をしていますが、 その他にも私の考慮不足な要素* が実際にはあるのでしょうか。 ( * これについては、次の追記を参照 ) ( 2018/7/3 追記 ) 原因が分かりました。 バックアップをしてある(Ver. 1.04)と(Ver. 1.05)以降の各ソースファイルの、チェック方法が (4) b'11' のときの該当する部分を見比べてみると、 ---(Ver. 1.04)--- ;;;;;;; チェックパタン '11' の場合 ptn_tbl dt h'01',h'02',h'04',h'08',h'10',h'20',h'40',h'80' dt h'00',h'ff',h'55',h'aa' : : chk15 call tbl_read ;テーブルデータの読み出し : : movf ram_data_o,F ;;相違部分 btfss STATUS,Z ;SRAM の 出力データ = '00' か? goto chk15 ;No : : ---(Ver. 1.05),(Ver. 1.06)--- ;;;;;;; チェックパタン '11' の場合 ptn_tbl dt h'01',h'02',h'04',h'08',h'10',h'20',h'40',h'80' dt h'00',h'ff',h'55',h'aa' : : chk15 call tbl_read ;テーブルデータの読み出し : : movlw h'aa' ;;相違部分 subwf ram_data_o,W ;; btfss STATUS,Z ;SRAM の 出力データ = 終了'aa' か? goto chk15 ;No : :と両者では異なっていました。 書き込みデータの定義としてはどちらも同じで 12 個並んでいますが、その読み出しを(Ver. 1.04)では h'00' で打ち切ってしまって、残りの h'ff'、h'55'、h'aa' についてはチェックを行っていません。 それに対して(Ver. 1.05)以降ではすべてのチェックを行っていて、この3個のデータ数の違いが両者でのチェックに要する時間の差となって表れているのです。 勿論、(Ver. 1.05)以降のリストの方が意図することを行っていて正しいのですが、これは(Ver. 1.04)から8年経った今回のプログラム修正で直したものではありません。 上の(Ver. 1.04)のファイルは 私のPCのバックアップ用ホルダにあったもので、(Ver. 1.05)および(Ver. 1.06)に更新した最新用のホルダにあった元ファイルとは異なっています。 どうやら、(Ver. 1.04)でも2種類のファイルがあったようで、既に8年前に上リストのようにテーブルデータの読み出しの終了判断する部分を修正したのに、そのバージョン番号を 更新していなかったようです。 そして、8年前の前回のチェックでは、そのように修正する前のプログラムでチェックの実施をしてしまったようです。 というよりも、チェックの実施後にその間違いに気が付いて プログラムリストの修正だけを行っていたようです。 |
全チェックパタン自動実行の機能追加 (Ver. 1.07) ( 2018/7/7 更新 ) データ衝突という重大なプログラムバグを修正( (Ver.1.05)、(Ver.1.06) )したのを機に、現在、私が所有している SRAM の全数のチェックを、もう一度やり直してみたのですが、400 個以上ある SRAM 1個1個に対して (1)〜(4) のすべてのチェック方法を実施するために、SELECT 1, 0 スイッチ( DIP スイッチ)で切り替え指定をするだけでも大変な作業でした。 そこで、すべてのチェック方法を実施する場合には、DIP スイッチを操作することなくタクトスイッチの簡単な操作だけで、すべてのチェック方法を自動的に実施できる機能を追加しました。 具体的には、チェックのスタート促進メッセージが表示されているときに、CONTINUE (→(RIGHT)スイッチと兼用) スイッチを押しながら ENTER スイッチ を押すだけでその機能を実現できます。 (詳細は、機能概要と使用法 の項の 機能追加 と、次のプログラムのソースファイルを参照してください。) |
現在の最新バージョン: Ver. 1.07 |
| ページトップ |
今回チェックの対象としたスタティック RAM の、サイズ別のピンアサインを次に示します。 これは上記 回路図 の該当部分を拡大して再掲したものです。 | |||||||||||||||||||||||||||||||||||||||
|
| ページトップ |
中央右に位置するゼロプレッシャーソケットですが、右写真では ARIES社の 28P が写っています。 これは今手持ちには 28P のものしか
ないためで、本来は 64K バイト以上の RAMに対応するためには、32P のものが必要です。 ところが、秋月電子通商では 32P のものを扱っていません。 言い遅れましたが、左のパターン図に示すように、プリント基板上には 32P の通常の丸ピンソケットがハンダ付けしてあります。 その上に ARIES社の 32P のゼロプレッシャーソケットを積んで使用するつもりでした。 実は TEXTOOL社の 32P の製品なら手持ちがあるのですが、足ピンの形状が幅広のため この丸ピンソケットに嵌りません。 本機を作製当時は、ARIES社の 32P のゼロプレッシャーソケットが、すぐ入手できるものと思っていたためで失敗でした。 初めから TEXTOOL社の 32P の製品を、 直接プリント基板にハンダ付けをして使用すればよかった、と思います。 ( 2016/1/26 追加 ) プリント基板をケースに収納することによって、基板の上部に取り付けてあった "長時間ストップウオッチ/タイマー" に接続するための、BUSY 信号端子と電源端子がL型端子のため、共に使用できなくなってしまいました。 そこで下パターン図に示すように、 LCDの下の僅かな空きスペースにもう1組の垂直端子を取り付けました。 |
| プリント基板パターン図 (部品面) (StaticRamCheckerPC.CE3) | ページトップ |
| プリント基板パターン図 (ハンダ面) (StaticRamCheckerPC1.CE3) | ページトップ |
使用したケースは、"フリーケース A5 L8998 (サナダ精工株式会社)" というもので、サイズ:幅241 x 奥行167 x 高さ39 mm、材質:ポリプロピレン です。
|
| ケース加工図 (StaticRamCheckerCS.CE3) | ページトップ |
その昔、正規(?)に販売店で購入したものが数十個と、最近 Yahoo!オークションで落札し、いつの間にか溜まった
SRAM メモリの数が、合わせて約300個。これら全数(SOP を除く)について今回 ( 2010/07 )、本装置でメモリチェックを行なってみました。 下の表がその結果です。 (1)〜(4) が上記 プログラム の項で説明したチェック方法で、各方法とも左欄は 液晶(LCD)に表示するのをパスしたときで、右欄は進行状況を液晶(LCD)に表示したときのチェック所要時間を表しています。 表中左欄 すなわち液晶(LCD)に表示するのをパスした方法については、今回メモリIC全数について (1)〜(4) のすべてを実施しました。 右欄の進行状況を液晶(LCD)に表示した方法については、それぞれの型名の中で代表的に1固体についてのみの実施です。 これらを見ると明かに大きな時間差が出ており、右欄では本来のチェック時間よりも、その殆どが液晶(LCD)の表示に費やしている ことが分かります。また、どの方法においても左欄の本来のチェック所要時間では、同固体を数回チェックしてみましたがバラつきは まず見られませんでしたが、右欄の進行状況を液晶(LCD)に表示したときには、その所要時間にはかなりのバラつきがありました。 しかも、32K バイトサイズの SRAM の測定時で数十秒台のバラつきがありましたので、これらの表中には一応秒以下の値まで書き入れてはありますが、 その絶対値にはあまり意味がありません。したがって、右欄の測定値の十秒台以下はあくまでも参考程度です。 また、方法 (4) ではさすがにその所要時間が短くて、容量の大きな SRAM でもあまり気にはなりませんが、その他の方法では 容量が大きくなるにつれて、進行状況を液晶(LCD)に表示したときには、デモンストレーションとしてはいいけれど実用的ではありません。 せいぜい2Kバイトまでがいいところでしょう。 なお、これらの時間測定には今回専用に開発した、"長時間ストップウオッチ/タイマー" を使用しました。
上表の結果についてですが、NG数欄が "0" 以外のエラーが起こったものでは、いずれにも共通点がありました。 それは4つのチェック方法の内、表からは分かりませんが、どれもが (3) の方法のときにエラーが起こっている、ということです。 メモリIC全数について (1)〜(4) のすべてを実施して、(3) 以外の (1) (2) (4) の方法では何ら問題がなかったのに、(3) の方法に限って エラーが起こった、というものです。 しかし、今回 293 個のメモリICをチェックしてみて、その殆どの 272 個のメモリICがOKだったことから、(3) のチェック方法に 問題がある、とは考えられません。 |
( 2010/9/26 追加 ) また、たくさんの SRAM を入手しました。 2K バイトにしては型名が少々変だと思って調べてみると、オリジナルはどうも INTEL のようで、MILITARY 仕様になっています。 当初、60 個中 3 個エラーになりましたが、全数チェック後に改めてチェックし直すと、何ら問題はありませんでした。 どうやら接触不良のようでした。
|
( 2018/7/3 追加更新 ) データ衝突という重大なプログラムバグを修正( (Ver.1.05)、(Ver.1.06) )したのを機に、また、前回(8年前)のチェック時以降に新たに入手をした SRAM を含めて、 現在、私が所有している SRAM の全数のチェックを、もう一度やり直してみました。 試験方法は前回と同様に行い、表中の各結果の左欄、すなわち液晶(LCD)に表示するのをパスした方法については、今回もメモリIC全数について (1)〜(4) のすべてを実施しました。 右欄の進行状況を液晶(LCD)に表示した方法については、それぞれの型名の中で代表的に1固体についてのみの実施です。
上表が今回のチェック状況の一覧ですが、表を見て、まず目立つのが前回に比べて全体的に SRAM の数量が増えている点と、実施日欄に "行方不明中" と記されたものがある点で、 この "行方不明中" というのは、前回の表にはチェック対象としてその結果があったものですが、今回はその存在を見つけられずチェックをすることができなかったものです。 チェック結果がNGになったものの中で、まず、サイズが 2K バイトの TMM2016P と TMM2016P-2 ですが、前回では両者をまとめて 13 個中 4 個がNGとなっていたもので、今回のチェックでは 1個の "行方不明中" を除いて、両者を合わせると 12 個中 10 個がNGとなってしまいました。 これは確実に ICの劣化が進んでいるということだと思われます。 このメモリICは、私にとっては特別な思い入れがあるもので、30 数年も以前に "秋月電子" で 12 個購入したもので、当時価格として1個 1,750 円であったと記録に残っています。 私の他のページ "8080A CPU コンピュータシステム" で紹介しているものとは違う、セカンド・システム用にと購入をしたもので、プリント基板のソケットに実装 された形で現在に至っていますが、未だそのセカンド・システムは未完成の状態のために本来での通電はしたことがなく、前回のメモリチェックで初めて通電をしたもの(今回が2度目)です。 この ICの劣化とは逆に、32K バイトの W24257AK-15 については、前回のチェックでは 4 個中 2個がNGとなっていたものが、今回のチェックではすべてがOKでNGのものはありませんでした。 不良だったものが8年経って良くなるということは到底考えられませんので、これは、前回のチェックでは ICピンが接触不良を起こしていたのではないかと思います。 この接触不良を起こす― ということはよくあることで、今回も 400 個以上のメモリICを扱っていると、ときどきそんな現象を経験します。 そんなときにはゼロプレッシャーソケットへの着脱を 数回繰り返すことによって大抵の場合には正常に戻ります。 それでもダメな場合には ICピンの目視チェックもした上でメモリICの不良と判断をしています。 サイズが 8K バイトの IS61C64AH-15N については、前回のチェックでも 15 個すべてがNGでしたが、今回は 59 個がチェック対象で、何と、やはりすべてがNGという結果となりました。 もちろん ICピンの接触不良などではなく、間違いなくエラー症状を起こします。 このメモリICは、他のものと違ってアクセスタイムが 15 nS と極端に高速で特別な存在です。 その影響があるのかどうかは分かりませんが、本機でのチェック方法ではだめなのかもしれません。 結局、今回のチェックでは "行方不明中" のもの 14 個を除いて 434 個がチェック対象でしたが、その内、 10 個の TMM2016P(TMM2016P-2 を含む)と 59 個の IS61C64AH-15N でエラーが発生したのですが、 前回( 上述 )のように「4つのチェック方法の内、どれもが (3) の方法に限ってエラーが起こった」というようなことはなく、(1)〜(4) のすべての方法でエラーとなり、 しかも、そのエラーの発生の仕方は単発的に起こるというものではなく、どの場合にも多発的に頻繁に起こって明らかに異常を感じさせました。 そして、そのエラー時の様子を 機能概要と使用法 の項で説明をした ポーズ動作 をさせて調べてみると、たとえば、同一アドレスにも拘らず h'0F' と書き込んだのに h'07' と読み出したり(この場合には bit3 の欠け)、h'09' と書き込んだのに h'08' と読み出したり(この場合には bit0 の欠け)と、そのときの不良ビットがバラバラで定まっていません。 このように、エラーが起こった ICでは、(1)〜(4) のすべてのチェック方法で同様に、バラバラにビットの欠けが生じており、逆のビットの湧き出しは起こっていない様子でした。 また、上表全体においてのチェック所要時間についてですが、SRAM のサイズ別、チェック方法別がもし同一であれば、たとえメーカーや型名が異なっていても実行されるプログラムは同じものですから、 その所要時間についても本来は同一になる筈です。 実際に上表を見てみても液晶(LCD)を非表示にした場合には、最下桁(10m 秒桁)を除いては同一になっています。 この最下桁の僅かな差は周囲の温度差によるものが大きく、実際に部屋のエアコンを入れたときと 切ったときとでは変化することが確認できました。 今は夏場のためエアコンを入れて部屋の温度が下がると 最下桁の値が増加しました。 本機では 20MHz のセラロックを使用のため基準クロックは ( 1 / 20MHz ) x 4 = 0.2μS の筈ですが、実際には温度が下がることによって基準クロックも僅かに増加するもの と思われます。 そして、プログラムの項の チェック時間短縮の小改善の試み で計算値を示して述べたのと同様に、基準クロックの僅かな変化がアドレスの最大値倍になり、かつ、書き込み(読み出し)の データ数倍となって大きなループでプログラムが実行されるため、結果として最下桁(10m 秒桁)に影響を与えることになります。 一方、チェックの進行状況を液晶(LCD)に表示をした場合には、上述 したように PIC と LCD とのインターフェースでは、ループ動作で PIC が LCD に待たされる部分がある (LCD からのビジーフラグをチェックしている(lcd_busy サブルーチン))ために、たとえ SRAM のサイズ別、チェック方法別が同一であっても全体としての命令の実行数が異なってくるために、 上表のように数秒の差が生じるものと思われます。 |
| ページトップ |
(主要部品: IC, トランジスタ等) | (データシート) | ||
PICマイコン | .................... | PIC16F877A | |
HC-MOS IC (NOR Gate) | .................... | HD74HC27P | |
HC-MOS IC (D-Type Flip Flop) | .................... | HD74HC273P | |
HC-MOS IC (Bus Buffer) | .................... | HD74HC541P | |
HC-MOS IC (D-Type Flip Flop) | .................... | TC74HC574AP | |
トランジスタ | .................... | 2SC3669Y | |
LCDモジュール | .................... | SC1602BS-B | |
圧電ブザー | .................... | PKM13EPY |
| 部品表 | Excel ファイル (StaticRamChecker_parts.xls) | ページトップ |
2716〜27512,8748,49用 ROMライター
http://rd.vector.co.jp/soft/dos/hardware/se022884.html
WRDOC.DOC: 2716〜27512 ROMライターの製作 (有)アクト電子 下間憲行氏
| ページトップ | ホーム |