32x16LEDマトリクスドライバソフト for H8/3048F
LEDマトリクスを使っておもしろいことしよう!っていうページです。
アイデアあるけど何したらいいのかわからん!って人のためにつくってみました。
事前に必要な環境
Windows
みんなもってると思うので。
unixライクにmakeしたかったので。バッチファイルとか作ってコンパイル自分でできるなら要らないです。
秋月電子で買った部品
一番入手しやすいんではないかと。32x16で、赤1色です。
見た感じちょっと大きくて、ドットが丸い。
回路図がpdfでおちてるので、これ見て似たような回路を構成すれば違うLEDマトリクスでも駆動できそうです。
製作は説明書みながら抵抗を2個ほどつけて、端子をCPUボードの必要な汎用ポートにつけるだけ。
H8本体です。H8/3664Fの方が小さくていいかも。コンパイラ違うけど。
H8にプログラムをダウンロードするときに要ります。
秋月製のCコンパイラはWeb上で見る限りへぼそう…。cygwin上でgccやbinutilを使う方がいろんなことできそう。
でもWeb上のマニュアルが多かったので秋月製でやりました。CコンパイラはVer 1.0。トラ技の付属でVer 2.0というものがあって
そっちはC→アセンブリソースとか見れたり高機能みたい。
その他
USB2RS232Cケーブルとかはんだごてとかコンセントとか酸素とか要るんだけど
書きすぎてもあれなんで割愛。あ、h8WriterTurboっていうライタがあるとすげー便利です。
LEDマトリクスドライバファイル
以下の8つのファイルをまとめたもの。
- ledmatrix_ex.c
- ledmatrix.h
- inttable.mar
- startup.mar
- common.h
- linkscript.sub
- Makefile
- CNs.txt
使用例。×を2つ表示します。ドライバ本体はledmatrix.hです。
これをベースにledmatrix.hを説明すると、まず頭のほうにこれを入れる。
#define LEDMTX_YIN ポート名.DR.BIT.ビット名(LED説明書の端子 SIN1 に対応)
#define LEDMTX_XIN0 ポート名.DR.BIT.ビット名(LED説明書の端子 SIN2 に対応)
#define LEDMTX_XIN1 ポート名.DR.BIT.ビット名(LED説明書の端子 SIN3 に対応)
#define LEDMTX_CLK ポート名.DR.BIT.ビット名(LED説明書の端子 CLOCK に対応)
#define LEDMTX_LTC_N ポート名.DR.BIT.ビット名(LED説明書の端子 LATCH に対応)
#define LEDMTX_STR_N ポート名.DR.BIT.ビット名(LED説明書の端子 STROBE に対応)
#define SET_LEDMTX_OUTPUT() (ポート名.DDR = 0xff) /* 汎用ポートを出力に設定する */
#define LEDMTX_INT_MS 更新時間間隔(単位はms、1-32767まで)
#include "ledmatrix.h"
1-32767「μ」secで更新したいならLEDMTX_INT_MSの代わりにLEDMTX_INT_USをdefineしてください。
で、main関数のはじめに initLEDMatrix() を呼び出してLEDを初期化。
で、ledmtx_vram[] という配列に表示したいパターンを書けば
それが何もしなくてもタイマ割り込みによって LEDMTX_INT_MS 間隔で表示されるという仕組み。
main(){
...
initLEDMatrix();
...
ledmtx_vram[2]=0x10とか;
...
}
ここで、ledmtx_vram[i=0-31]は16ビットの配列で、iが行、ビットが列をあらわします。
i<16は左側のLEDマトリクス、i>=16は右側のLEDマトリクスとなっています。
マトリクスドライバソフト本体。
これをincludeすればOK。
タイマ割り込みIMIA1、Timer1 (msecオーダーで駆動するときはTimer0も) はこの中で使うので空けといてね。
原理を説明すると、LEDマトリクスは一度に1行しか表示できないので、
人間にばれないように高速に1行づつ表示する行を変えていく。
まず1行目の16ビット表示データledmtx_vram[0]/ledmtx_vram[0+16]をLEDMTX_XIN0/1にてLEDMTX_CLKの立ち上がりにラッチする。16ビットなので全部で16回のラッチ。
このときに表示行を表す 0x01 もLEDMTX_YINにて同時にラッチする。
で、全部ラッチしたらLEDMTX_LTC_N=LにしてLEDの点灯を更新。1行だけ表示されます。
つぎに、2行目のデータ。LEDMTX_YINから0x02、XIN0/1からledmtx_vram[1]/ledmtx_vram[1+16]をラッチ。
こんな感じで、「16回のラッチと表示」をさらに16回繰り返すことで人間には32x16に見えるわけです。
あ、電光掲示板みたいに流れる表示、みたいなベタことをしたいという人は
もっとそれに最適なコードに改造する必要があるでしょう。
割り込みベクトル。つまり割り込みIMIA1を使うためのC言語で書けない設定を書いたファイル。
割り込みIMIA1が発生したときに呼び出す関数をshowLEDMatrix()に設定しています。
便利ファイル。ledmatrix_ex.cからincludeしてます。内容は以下。対したことないけど。
ややこしい!とか言う人は自分流で。
typedef unsigned int uint16; /* 符号なし16bit型の定義 */
typedef signed int int16; /* 符号つき16bit型の定義 */
typedef char uint8; /* 符号なし 8bit型の定義 */
typedef signed char int8; /* 符号つき 8bit型の定義 */
static const char hexchar[]="0123456789ABCDEFF"; /* int->hex文字列の変換テーブル */
static void initTimer1Int(uint16 period_usec){...} /* μsec単位のタイマー初期化 */
void initTimer01Int(uint16 period_msec){...} /* msec単位のタイマー初期化 */
#define startTimer01() /* msec単位のタイマー駆動開始の関数 */
#define startTimer1() /* μsec単位のタイマー駆動開始の関数 */
#define stopTimer01() /* msec単位のタイマー停止の関数 */
#define stopTimer1() /* μsec単位のタイマー停止の関数 */
アセンブリソース。C言語で書けない設定のためのファイル。
リンカスクリプト。つまり*.objのメモリ配置を決めるファイル。
一行目のc38hab.libを自分の環境のパスに書き換えてください。
内容はプログラム領域 P, 定数領域 C, static変数の初期値領域 D を この順でROM の 0x100番地に、
static変数領域X, 局所変数領域BをRAMの 0x0FEF10番地に配置する設定です。
cygwin用Makefile。
LIBとWRITERのパスを書き換えてください。
makeでコンパイル、make cleanでクリーン、make installでダウンロード、make writerでh8writerturboの設定ができます。
H8/3048F CPUボードの端子配置図。等倍フォントのテキストエディタでみると便利かな。
注意とか
書き込み時にLEDマトリクスが繋がってるとLEDマトリクスがランダムに点灯してCPUへの電力供給が落ち、
書き込み失敗になるケースが多かったです。LEDがたくさんついてる(10個以上)とうまくいかない。
なので、書き込み時はLEDマトリクスをはずすか、LEDマトリクスのPOWERにスイッチをつけて、書き込み時にOFFにすると楽に書き込みできます。
update: Jan 21, 2006