8279は、普通の使い方で64個までのキーボード入力と8個か16個の7セグメントLED表示を行うことができるLSIです。
組み込み用途でも多数のプッシュボタンを必要とするものがあります。関数電卓並みのスイッチの並ぶ操作卓なんてものを考えなくても、たとえば自動販売機だって20個くらいはスイッチが並んでいるでしょう。工業用の装置でも0から9までの数字キーに10種類くらいの機能ボタンが並ぶなんてことは、よくあります。
量産の予定がある装置なら、タイマ割り込みとソフトウェアでスキャンして、どのキーが押されたか判定して、内部コードに変換するようにすれば、部品が少なくて済み、コストダウンできます。でも、少量しか生産されず、しかも納期が厳しくてソフトウェア開発時間を短縮したいなんて時には、キー入力専用のLSIがあったらなぁ、なんて考えてしまうわけです。
LEDに数字を表示させるのだって同じ事がいえます。ソフトウェアで行えばハードウェアコストは最小にできるかもしれないけれど、ソフトウェアの方のコストや時間的なコストを最小にしたいという場合だってあります。
また、LEDの場合にはソフトウェアで行うと別の危険があります。多数の数字表示器を駆動する場合、ダイナミックスキャンを行って表示するのが普通です。ひとつのLEDを1 ms程度だけ光らせて、次の桁のLEDを同じ時間だけ光らせて、というように、CRT表示のように時分割で表示します。こうすれば、LEDを駆動するトランジスタの数や配線の量を減らすことができます。ただし、スタティックに表示させた場合の10分の1くらいの時間しか光りませんから、常に電流を流して光らせた場合と同じだけの電流を流したら暗くて見にくくなります。ですからスタティック表示の時の10倍くらいの電流を(一瞬だけ)流して強く発光させ、平均すると同じ程度の明るさにします。LEDをこのような使い方をすることはLEDメーカも保証していて、連続して流していたら破壊する電流でもパルスでなら流してかまわない限度があるとして、その最大値などを規定しています。しかし、ダイナミックスキャンをソフトウェアだけで行っていて、割り込みなどでダイナミックスキャンが途中で止まってしまう瞬間があると、各桁の明るさにムラが出るばかりか、連続で流してよい電流値を越えてしまっていてLEDが破壊する危険すらあります。極端なことをいえば、ノイズか何かでコンピュータが暴走してしまえば、ウォッチドッグタイマが働いて自動復帰する間の時間にLEDが焼き切れる危険だってあるのです。単純なハードウェアでCPUと無関係に常にLEDをリフレッシュしていれば、暴走やソフトウェアの都合で明るさにムラがでたりLEDが破壊する危険はずっと少なくなります。
キースキャンやLEDのダイナミック表示用のソフトウェアモジュールを一度作ってしまえば、あとは納期が厳しいときだって再利用すればよいのではないかという意見は正論で実際にうまく行くことも多いのですけど、割り込みやら時間管理やらが厳しい組み込み用システムでは再利用しにくい場合もあってつらいところです。たとえば、あてにしていたタイマ割り込みを別の用途に使う必要があったりとか、(プログラムを手早く作成するためには)必ず一続きでまとめて処理しなければいけない作業があって、その時間をLEDのダイナミック表示に使えないとか、なかなか宣言部を少しいじってライブラリをリンクすればOKってな形にならないことがあります。
そこでプログラムでめんどうをみなくても勝手にキーやLEDのスキャンを行ってくれる標準的ハードウェアがあれば、ソフトウェアで楽ができるってなことなんですが、それが8279でした。
結構便利に使ってました。上がIntel社の8279でCERDIPパッケージ。下は同じくプラスチックパッケージ。
最大32個の7セグメントLEDによる数字表示と64個のスイッチ(とシフトキーとコントロールキーの同時押し)入力が可能で、付加的な機能もいくつかあります。キー入力を使わない場合には、64接点までの接点入力の状態を常時監視するようなことも可能です。
内部には16 Byte分の表示用バッファメモリと8文字分のキーボード用FIFOを備えています。表示用バッファメモリのアドレスには、CPUからのアクセスがない時には4 bitのカウンタの出力が接続されて、常時スキャンされています。カウンタ出力と、その信号をアドレスとして読み出された表示用バッファメモリの内容が、8279の外部に引き出されています。カウンタ出力を74LS138などでデコードして7セグメントLEDのコモン端子を駆動し、小数点も含めた各セグメント合計8セグメントを表示用バッファメモリの出力に対応付けて駆動すれば、16個までの7セグメントLEDに任意のパターンを表示させることができます。7セグメントLEDに数字を表示するだけで良いのなら、表示用バッファメモリの読み出しデータ8 bitを4 bit単位のふたつに分け、それぞれにBCDコードから7セグメント表示のビットパターンに変換する回路である7セグメントデコーダを接続すれば、2倍の32個までの7セグメントLEDに表示させることができます。逆に8個のLEDまでで良いのなら、CPUからのコマンドによってカウンタの最上位ビットを未使用にして8 Byte分のバッファしかスキャンしないように設定することもできます。
LEDのスキャン用のカウンタ出力の下位3 bitをデコードしたものは、キーボードや接点入力のスキャンにも使用されます。8×8のマトリックスに配置したスイッチの一方を、そのスキャン出力に接続し、それと直交する8本のリターン線はそのまま8279の入力に接続します(おっと、プルアップ抵抗も忘れてはいけない)。リターン線の信号を適切なタイミングで読み取って、新たな有効キー入力が認められたとき、8本のリターン線の値を3 bitにエンコードしてスキャン用カウンタの3 bitの値と合わせて6 bitのキーデータに変換します。それにシフトキーとコントロールキーの状態を表す2 bitを付け加えた8 bitデータをFIFOに格納し、CPUがそれを読み取って利用できるようにしておきます。
コマンド設定によっては、64個までの接点入力の状態をスキャンするたびに内部8 Byte分のFIFOに使用するはずのメモリに反映させて、計64 bitの各ビットの1と0に対応させてCPUから読み取れるようにすることもできます。また、普通のキー入力モードの時も、ほぼ同時に複数のキーが押されたときの処理として2キーロックアウトとNキーロールオーバのどちらかを選択することもできます。さらに、エンコーダ付きのキーボードを接続することも可能で、8 bitデータとストローブパルスを8279に与えてFIFOに格納してCPUに読み取らせることもできますし、キー入力が不要でLED表示中心に使用する際には8 bitの入力ポートとしてもそれなりに使用可能です。
レジスタには次の3種類があります。
A0 | R/W | レジスタ名 |
0 | R | data register |
0 | W | data register |
1 | R | status register |
1 | W | command register |
ここでA0は8279のレジスタ選択端子でR/Wはそれぞれ読み出し(R)と書き込み(W)を意味します。
つまりただひとつのデータ転送用のデータレジスタと、書き込み専用のコマンドレジスタと読み出し専用のステータスレジスタがCPUから直接アクセスできるもののすべてです。キーボード用FIFOやLED表示用バッファメモリには、コマンドで種類やアドレスを指示してデータレジスタを介してアクセスします。
コマンドは1 Byteのものだけで、上位3 bitによって次の8種類に分類されます。
コマンドコード 意味 b7 b6 b5 b4 b3 b2 b1 b0 0 0 0 D D K K K KeyBoard/Display Mode Set 0 0 1 P P P P P Program Clock 0 1 0 AI X A A A Read FIFO/Sensor RAM 0 1 1 AI A A A A Read Display RAM 1 0 0 AI A A A A Write Display RAM 1 0 1 X IW IW BL BL Display Write Inhibit/Blanking 1 1 0 CD CD CD CF CA Clear 1 1 1 E X X X X End Interrupt/Error Mode Set
コマンドはb7がMSBでb0がLSBです。コマンドコードの下位5 bitの意味は余裕ができたときに説明します。
基本的にKeyBoard/Display Mode Set, Program Clock, Clear, Display Write Inhibit/Blankingの4種類のコマンドで初期設定した後、Write Display RAMで表示用バッファメモリにデータを書き込み、Read FIFO/Sensor RAM でキー入力を読み出すことになります。
ステータスレジスタは、こんなビット構成になっています。
b7 b6 b5 b4 b3 b2 b1 b0 Du SE O U F N N N
ここでDuはDisplay unavailableという意味で、Clearコマンドによって表示用バッファメモリをクリアする作業中にCPUからアクセスできないことを示すビットです。
SEはセンサーマトリックスモードでは少なくとも1接点が閉じていることを表し、スペシャルエラーモードでは複数接点の同時押しが生じたことを表すビットです。
Oはオーバーランエラーで、Uはアンダーランエラーです。共にFIFOへのアクセスに関するエラーですね。
FはFIFO Fullという意味で、8 Byte分のFIFOが一杯になっていることを示します。また下位3 bitのNNNは、3 bit合わせてFIFOに入っているキーコードの数を表します。結局、ステータスレジスタの下位4 bitが0ならFIFOは空で、1から8になっていればCPUがFIFOを読み出してキーコードを取り出さなくてはならないことになります。