この文書では入出力ボードにあるドットマトリクスディスプレイの制御方法について説明します.
1:概要
入出力ボードにある8個のドットマトリクスディスプレイは,7セグメントLEDと同様にダイナミック点灯方式で制御されており,垂直方向にある16個のLEDに表示するパターンをFPGAから32回送るようになっています.ただし7セグメントLEDよりやや複雑な制御を行っております.その一番の要因は32回送るとき,7セグメントLEDではそれぞれFPGAと制御されていましたが,ドットマトリクスディスプレイの場合にはFPGAの外部にあるシフトICを使っていることが挙げられます.各シフトレジスタはシリアルイン8ビットパラレルアウトになっており,それを4個使って32個の信号にしているのです.詳しくは後ほど説明します.
2:インタフェース
下にドットマトリクスディスプレイのインタフェースを示すとともに,各端子の説明を図の下にある表で示します.
端子名 | 入力/出力 | バス幅 | 説明 |
iClk | 入力 | 1 | クロック.ダイナミック点灯をするために用います. |
iLoad | 入力 | 1 | 立ち上がりエッジでiColumnからの信号をiColumnIdに表示します. |
iColumnId | 入力 | 5 | iColumnを表示する列の番号です.右端が0,左端が31とします. |
iColumn | 入力 | 8 | 描画する垂直方向(列)のパターンです.作成する回路ではこの信号をあらかじめ設定しておくと,それを記憶しておきます.1にすると点灯,0にすると消灯します. |
iClrN | 入力 | 1 | 表示(1'b1)/非表示(1'b0)します. |
iRst | 入力 | 1 | この信号が1'b1のときリセットされます. |
oClr | 出力 | 1 | ドットマトリクスディスプレイを表示する(1'b0)か非表示(1'b1)にするか出力します. |
oClk | 出力 | 1 | 4個のシフトレジスタのクロックに接続されています. |
oSeg | 出力 | 4 | 4個のシフトレジスタのシリアルインと接続されており,同じくシフトレジスタに接続されているoClkの立ち上がりエッジのタイミングで,oSsgの信号をシフトレジスタは取り込みます. |
oColumn | 出力 | 8 | このドットマトリクスはダイナミック点灯方式を利用しており,目には見えませんが高速で1列ずつ描画しています.その1列のパターンを表しているのがこの信号です. |
3:外部回路構成
下に示す回路図はDMDに関係する回路図です.上部にPNP型トランジスタがあり,これで32列のLEDをON/OFFしています.その下側に8個のドットマトリクスディスプレイがあります.右側には行を制御する3ステートバッファ(74541)とトランジスタアレイ(TD6208)があり,右下には3ステートバッファによりハイインピーダンスにすることができるスライドスイッチがあります.なお,3ステートバッファにはもうひとつハイインピーダンスにすることができる信号はFPGAと接続されています.最後に,下側には列を制御するシリアルインパラレルアウトの8ビットシフトレジスタ(74164)があります.
PDF版はこちらからダウンロードできます.
動作の流れを簡単に説明します.ここでは1列分のパターンを表示することを例とします.
表示する列を指定するには,回路図の下側にあるシフトレジスタ(SR)の中の1個だけから1個だけHigh,他をすべてLowにした信号を出します.これらの信号は回路図上側にあるソース型トランジスタアレイに接続されており,入力をHighにすると出力から3.3[V]の電気がその列に流れるため点灯します.反対に,トランジスタアレイの入力をLowにすると出力からは電気が流れないため消灯します.
1列分の信号をFPGAから3ステートバッファを介してトランジスタアレイに接続しています.このトランジスタアレイはシンク型トランジスタアレイであり,入力をHighにするとドットマトリクスディスプレイからの電気をグランドへ流すことができます.
以上のように,1列のパターンを変えつつ,かつシフトレジスタ(SR)にクロックを与えていけば,残像現象でパターンが表示されたように人間の目には見えます.
4:ピンアサイン
ピンアサインを下表で示します.この表をもとに,GOWIN EDAのPloorPlannerにてピンを割り振ってください.なお,この表にはドットマトリクスディスプレイとは別に,スイッチ類のピン番号も掲載しておきます.
端子の役割 | 回路図上の名称 | FPGAのピン番号 | 信号の種類 | ポート名 |
上から1行目 | ROW1 | 28 | LVCMOS33 | oColumn[0] |
上から2行目 | ROW2 | 27 | LVCMOS33 | oColumn[1] |
上から3行目 | ROW3 | 26 | LVCMOS33 | oColumn[2] |
上から4行目 | ROW4 | 25 | LVCMOS33 | oColumn[3] |
上から5行目 | ROW5 | 39 | LVCMOS33 | oColumn[4] |
上から5行目 | ROW6 | 36 | LVCMOS33 | oColumn[5] |
上から7行目 | ROW7 | 37 | LVCMOS33 | oColumn[6] |
上から8行目 | ROW8 | 38 | LVCMOS33 | oColumn[7] |
右から1~8列目を 制御するSRの シリアルイン |
CLM_SEG1 | 77 | LVCMOS33 | oSeg[0] |
右から9~16列目を 制御するSRの シリアルイン |
CLM_SEG2 | 79 | LVCMOS33 | oSeg[1] |
右から17~24列目を 制御するSRの シリアルイン |
CLM_SEG3 | 80 | LVCMOS33 | oSeg[2] |
右から25~32列目を 制御するSRの シリアルイン |
CLM_SEG4 | 81 | LVCMOS33 | oSeg[3] |
すべてのSRに つながっているクロック |
CLM_CLK | 76 | LVCMOS33 | oClk |
点灯/消灯 | !DMD_CLR1! | 63 | LVCMOS33 | oClrN |
トグルスイッチ1 | SW1 | 69 | LVCMOS33 | iColumn[0] |
トグルスイッチ2 | SW2 | 68 | LVCMOS33 | iColumn[1] |
トグルスイッチ3 | SW3 | 57 | LVCMOS33 | iColumn[2] |
トグルスイッチ4 | SW4 | 56 | LVCMOS33 | iColumn[3] |
トグルスイッチ5 | SW5 | 55 | LVCMOS33 | iColumn[4] |
トグルスイッチ6 | SW6 | 54 | LVCMOS33 | iColumn[5] |
トグルスイッチ7 | SW7 | 53 | LVCMOS33 | iColumn[6] |
トグルスイッチ8 | SW8 | 51 | LVCMOS33 | iColumn[7] |
トグルスイッチ9 | SW9 | 42 | LVCMOS33 | iColumn[8] |
トグルスイッチ10 | SW10 | 41 | LVCMOS33 | iColumn[9] |
トグルスイッチ11 | SW11 | 35 | LVCMOS33 | iColumn[10] |
トグルスイッチ12 | SW12 | 40 | LVCMOS33 | iColumn[11] |
トグルスイッチ13 | SW13 | 34 | LVCMOS33 | iColumn[12] |
トグルスイッチ14 | SW14 | 33 | LVCMOS33 | iColumn[13] |
トグルスイッチ15 | SW15 | 30 | LVCMOS33 | iColumn[14] |
トグルスイッチ16 | SW16 | 29 | LVCMOS33 | iColumn[15] |
トグルスイッチ17 | SW17 | 32 | LVCMOS33 | iLoad |
トグルスイッチ18 | SW18 | 31 | LVCMOS33 | iClrN |
タクトスイッチ | S1 | 3 | LVCMOS33 | iRst |
発振器 | CLK | 52 | LVCMOS33 | iClk |
5:内部信号
ドットマトリクスディスプレイを制御するには,下記の内部信号が必要となります.
名称 | reg/wire | ビット幅 | 個数 | 初期値 | 備考 |
oSeg | reg | 4 | 1 | 4'b0000 | ポート宣言の信号をregにしている. |
drawingColumnPattern | reg | 8 | 1 | 8'b0000_0000 | 描画している列のパターン |
drawingColumnId | reg | 5 | 1 | 5'b00000 | 描画している列のID. |
pattern1 | reg | 16 | 8 | 別記 | 右から1~8列目のパターン |
pattern2 | reg | 16 | 8 | 別記 | 右から9~16列目のパターン |
pattern3 | reg | 16 | 8 | 別記 | 右から17~24列目のパターン |
pattern4 | reg | 16 | 8 | 別記 | 右から25~32列目のパターン |
disSt | reg | 1 | 1 | 1'b0 | 表示の状態.0:非表示,1:表示 |
dividedClk | wire | 1 | 1 | - | 分周したクロック |
初期状態で8個のドットマトリクスディスプレイに下記のように表示することにします.
長野高専
左端1列がpattern1[0]で表現され,その列から右側に進むにつれてpattern1[1],[2]…[7],pattern2[0],…,pattern4[7]となります.1列を表すpatternx[y]は16ビットであり,最上位ビットが下,最下位ビットが上になります.従いまして,パターンとpattern1~pattern4の関係は下の図のようになります.
上の図をもとに,pattern1~pattern4を初期化すると下のようになります.
initial begin pattern4[7] = 8'b00010000; pattern4[6] = 8'b01010000; pattern4[5] = 8'b01111111; pattern4[4] = 8'b01010101; pattern4[3] = 8'b00110101; pattern4[2] = 8'b01010001; pattern4[1] = 8'b01010000; pattern4[0] = 8'b00000000; pattern3[7] = 8'b01011111; pattern3[6] = 8'b01010101; pattern3[5] = 8'b01111111; pattern3[4] = 8'b01011111; pattern3[3] = 8'b01001001; pattern3[2] = 8'b01111101; pattern3[1] = 8'b00011011; pattern3[0] = 8'b00000000; pattern2[7] = 8'b01110010; pattern2[6] = 8'b00010010; pattern2[5] = 8'b01111110; pattern2[4] = 8'b01011011; pattern2[3] = 8'b01111110; pattern2[2] = 8'b00010010; pattern2[1] = 8'b01110010; pattern2[0] = 8'b00000000; pattern1[7] = 8'b00010010; pattern1[6] = 8'b00010010; pattern1[5] = 8'b00111110; pattern1[4] = 8'b01011111; pattern1[3] = 8'b01111110; pattern1[2] = 8'b00010010; pattern1[1] = 8'b00010010; pattern1[0] = 8'b00000000; end
次に各信号を説明します.
drawingColumnPattern:ある時点で描画している1列のパターンを表しています.従って,pattern1[0]~[7],pattern2[0]~[7],pattern3[0]~[7],pattern4[0]~[7]のいずれかということです.
drawingColumnId:ダイナミック点灯方式では,1列ごとにパターンを表示していきます.このときの列を表すのがこの信号です.すべてで32列あるため,この信号は5ビット(=0~31)となっています.0が右端の列,31が左端の列です.
disSt:ドットマトリクスディスプレイを制御するときにも隣り合う列を同時に表示させないため,列の切り替え時に消灯を行うことにしています.そのための信号がdisStです.この信号が1のときには点灯し,0のときには消灯するようにしています.
dividedClk:FPGAボードにはマスタクロックとして40[MHz]の発振器が備えられていますが,ドットマトリクスディスプレイをダイナミック点灯させるには速すぎます.そこで,およそ10[kHz]に分周したクロックを使うことにします.このクロック信号がdividedClkです.dividedClkはシフトレジスタのクロック(CLM_CLK)としても使用されます.
6:FPGAに作成する回路の構成
ここでは作成する回路の概略を示します.
- iClrNもしくはiRstがHigh(=押された)のときにoClrNをHigh(=非表示)にします.
- およそ10[kHz]に分周し,その信号をdividedClkとします.
- oClkをdisStとつなげます.
- iLoadが立ち上がる,もしくはiRstボタンが押されたとき,次の動作をする回路を作成します.
- iRstボタンが押されていたら,パターンを初期状態にします.初期状態にするには,pattern1~4に初期信号(すべて0)を入れればよいです.
- iRstボタンが押されていなかったら,つまりiLoadが立ち上がったら次の動作をする回路を作成します.
- もしiColumnIdの上位2ビットが0であったら,pattern1[y]にiColumnを代入します.このときのyは,iColumnIdの下位3ビットです.
- もしiColumnIdの上位2ビットが1であったら,pattern2[y]にiColumnを代入します.このときのyは,iColumnIdの下位3ビットです.
- もしiColumnIdの上位2ビットが2であったら,pattern3[y]にiColumnを代入します.このときのyは,iColumnIdの下位3ビットです.
- もしiColumnIdの上位2ビットが3であったら,pattern4[y]にiColumnを代入します.このときのyは,iColumnIdの下位3ビットです.
- 1列のパターン(oColumn)と描画している列パターン(drawingColumnPattern)とをつなげます.
- 周波数がおよそ10[kHz]のクロックの立ち上がりエッジが現れたら,表示状態(disSt)を表示なら非表示,非表示なら表示にします.
- 周波数がおよそ10[kHz]のクロックの立ち下がりエッジが現れたら,次の動作をする回路を作成します.
- disStが表示状態(=1'b1)なら,次の動作をする回路を作成します.
- 描画する列番号(drawingColumnId)をインクリメントします.
- もし描画する列番号が0~7であったら,描画している列パターンをpattern1[y]にします.ここでyはdrawingColumnIdの下位3ビットです.
- そうではなく,もし描画する列番号が8~15であったら,描画している列パターンをpattern2[y]にする.ここでyはdrawingColumnIdの下位3ビットです.
- そうではなく,もし描画する列番号が16~23であったら,描画している列パターンをpattern3[y]にする.ここでyはdrawingColumnIdの下位3ビットです.
- そうではなく,もし描画する列番号が24~31であったら,描画している列パターンをpattern4[y]にする.ここでyはdrawingColumnIdの下位3ビットです.
- 以上ですべての列番号を網羅したのでIF文を終了します.
-
もしdrawingColumnIdが31のとき,左端から1列目から8列目までのドットマトリクスディスプレイを制御するシフトレジスタに1を入力し, それ以外のシフトレジスタには0を入力します.
- そうではなく,もしdrawingColumnIdが7のとき,左端から9列目から16列目までのドットマトリクスディスプレイを制御するシフトレジスタに1を入力し, それ以外のシフトレジスタには0を入力します.
- そうではなく,もしdrawingColumnIdが15のとき,左端から17列目から24列目までのドットマトリクスディスプレイを制御するシフトレジスタに1を入力し, それ以外のシフトレジスタには0を入力します.
- そうではなく,もしdrawingColumnIdが23のとき,左端か259列目から32列目までのドットマトリクスディスプレイを制御するシフトレジスタに1を入力し, それ以外のシフトレジスタには0を入力します.
- それ以外の場合にはすべてのシフトレジスタに0を入力します.
- そうでない(disStが非表示状態)なら,drawingColumnPatternを8'b0000_0000にします.
- disStが表示状態(=1'b1)なら,次の動作をする回路を作成します.
以上でドットマトリクスディスプレイを制御する回路の説明を終わります.