成安造形大学コラボレーション・プロジェクト
アーティストのための汎用センサ自作応援講座
2001年1月 長嶋洋一
第6話
さて、秋月電子の「AKI-H8マザーボードキット(フラッシュROMライタ付)」を
第5話
に従って製作した、というビギナーのための、今度は続編で「ソフト開発」編
です。ただし、アセンブラによるAKI-H8のプログラミング、というのは
ちょっといきなりハイレベルに飛躍してしまうので、ここでは「既に完成
しているAKI-H8ソフトを自分のAKI-H8にプログラムして動かす」という
開発環境についてです。アセンブラとかC言語とかでAKI-H8を開発する、と
いうお話は、いずれもしかしたら書こうとも思いますが、可能性は不明です。
僕のここのWebには、AKI-H8モノについては、この「完成して書き込む
だけのプログラム(MOTファイル)」というのを必ず置いていますので、
ハンダ付けでハードを製作すれば、今回のやり方でソフトを仕込んで、動作
させることができるようになります。
それでは、秋月電子のマニュアルに従って環境設定から行っていきましょう。
ここでのスクリーンショットは、僕のPowerBookの画面内のVirtual PC内の
Windowsということになりますので、次の図のあとはその中だけをクリップします。
奇特にもWindowsな人(^_^;)は、そのまま中だけを見て下さい。同等のお話です。
これ
は、エクスプローラで、秋月CDROM(ないしその中身をコピーした)フォルダの
中の、WRITERというものです。他のファイルは圧縮していないのですが、
これだけはインストーラがあるので、まずこれを設定しておきます。なお、
ここでは例として「c:\MSDOS\SSS」というディレクトリを設定して、その中の
世界として環境を作ります。
この中のSETUP.EXEというのをダブルクリックして起動すると、
このような
インストーラが起動します。
「OK」以外の選択肢がないのでクリックすると、
こんな
ことを聞いてきます。この「ディレクトリ」には、AKI-H8開発を
行う場所を指定します。あらかじめ、専用のディレクトリを作っておくと、
他とまざって混乱しないでしょう。「ポート番号」というのは、
RS-232Cのシリアルポートですが、よく判らない場合には1にしておいて、
うまく行かなかったらあとで2とか3とか試します。(^_^;)
そして、「OK」クリックでインストールされた結果が、
これ
です。なんのことはない、結果としては、
指定した作業領域(ここではディレクトリ"SSS")の中に、
3048という二つのファイルとFLASH.EXEというファイルが、そのまんまコピーされる
だけです。
これでフラッシュROMライタ関係ができたので、あとは普通に入っていた
アセンブラ関係も、同じ作業ディレクトリ"SSS"にコピーするだけです。
これ
は、秋月CDROMの中のASMというディレクトリの中身です。必要なのは
EXE全てです。ちなみに、H38HMAN.TXTというのは、H8のアセンブラの
マニュアルですので、いずれプログラミングに挑戦したい人はこれも
せっかくなのでコピーしておきます。ところでH38HMAN.DOCというのは、
エディタで見てもバイナリ文字化けしているし、なんなのか不明です。(^_^;)
ドキュメントっぽいファイル名なのにテキストファイルでもない、
こういう邪悪なファイルというのは、ウイルスに感染したりしますので、
さっさと消去してしまうというのもいいですね。当然、AKI-H8の開発環境に
こういう怪しいものはコピーする必要はありません。僕はワープロというもの
をもう10年ぐらい使っていないので、"Word"なんて知りませんし。
ということで、AKI-H8開発に必要なファイルとしては、アセンブラの
マニュアルも含めて
こんな
感じで並ぶことになります。少ないしシンプルですよね。ここに、AKI-H8の
ソースプログラムを置いて、この中でアセンブル等を行って、そのままこの
中でフラッシュROMの書き込みまで行ってしまう、という閉じた世界を構成
することで、Windowsのわけわからん怪しい環境よりもスッキリと作業する
ことができます。(^_^)
さて、実際の作業では、この
DOS窓
を使います。頻繁に使うので、\WINDOWSディレクトリの中の「MS-DOSプロンプト」
のショートカットを作ってデスクトップに置いておくのもいいでしょう。
ここで、秋月CDROMの"MB"というディレクトリに置かれたサンプルプログラム
を題材にしますので、"MBTEST.MAR"というファイルを、さらに
ここにコピーしてきます。カレントディレクトリ(現在、自分が
いるディレクトリ)のファイルの一覧のコマンドは「
dir
」です。...なんてことは、最近の学校では
教えないのかなぁ。(^_^;)
"MBTEST.MAR"というのがAKI-H8のソースプログラムになりますが、
このMBTEST.MARをアセンブラにかけた、というのが
これ
です。つまり、DOSのプロンプト「>」のところに、いちいち
このように打ち込むわけです。MBTESTのところが、自分のプログラム
であればそれに代わります。
ここで、人間に読めるアセンブラプログラムが、機械語になります。
特にエラーがなければこのように出てきて、エラーがあればそのラインナンバー
が表示されるので、それを頼りにバグをつぶします。
結果として、MBTEST.OBJというのとMBTEST.LISというファイルが新しく
できました。OBJは次のステップで使います。LISは内部作業記録ファイル
ですが、テキストですので、エラーが出ても原因が判らない時に、これを
読んで解析するのに使います。
アセンブルに成功したOBJファイルを、次にリンカにかけたのが
これ
です。つまり、DOSのプロンプト「>」のところに、いちいち
このように打ち込むわけです。MBTESTのところが、自分のプログラム
であればそれに代わります。リンクとは、ここでは単なる内部変換ぐらいに
思っておきましょう。
特にエラーがなければこのように出てきます。
結果として、MBTEST.ABSというのが新しくできました。これは次のステップで使います。
リンクの結果のABSファイルは、さらにコンバータで変換します。
これは、モトローラ形式のSファイル、というものにしている作業です。
これ
です。つまり、DOSのプロンプト「>」のところに、いちいち
このように打ち込むわけです。MBTESTのところが、自分のプログラム
であればそれに代わります。
特にエラーがなければこのように出てきます。
結果として、MBTEST.MOTというのが新しくできました。
ということで、いわゆる「ソフト開発」の作業が終わりました。あとは、
AKI-H8マザーボードのフラッシュROMライタ機能を使って、このMOT
ファイル(AKI-H8の実行プログラムをROMに書き込める形にしたもの)
をダウンロードすればいいだけです。
この時点での風景は、
こんな
ものです。ここでは開発マシンはPowerBookですが、Windowsでも同様です。
スクリーンにはDOSプロンプトがあり、シリアルポート(RS-232C)からは
AKI-H8マザーボードにケーブルが伸びています。電源は、マザーボードの
電源スイッチS6がOFFであるのを確認した上でACに差し込みます。
まず、
このように
電源スイッチS6がOFFである、という事を確認して、DOS窓の中で
このように
FLASH.EXEを起動します。
すると、
このように
聞いてきますので、3048.INFが設定されていることを
確認して、「設定」をクリックします。
すると、
このように
聞いてきますので、まずはAKI-H8マザーボードのモード切り替えスイッチS7が
このように
ONになっている事を確認した上で、電源スイッチS6を
このように
ONにします。その上で、画面内の「設定」をクリックします。
すると、接続とかハード関係が全て正常であれば、
このように
0%から100%まで、ブートローダプログラムが転送されて、転送が
完了します。どこかにミスがあればまったく画面は進行しませんが、
いずれ「タイムアウトエラー」で終了できますので、慌ててリセット
しなくても大丈夫です。
ブートローダの転送が無事に終了したら、引き続きそのまま、今度は
メニューの「WRITE」コマンドの先頭で
このような
ものを出します。設定するのは「ファイル名」だけで、あとは
そのままでOKです。とりあえず「参照」のボタンをクリックして、
AKI-H8に転送したMOTファイルの場所を
このように
捜して、
このように
ファイル名の欄をセットしたら「OK」をクリックします。
すると、
このように
0%から100%まで、ユーザプログラムが転送されて、転送が
完了します。たいていの場合、こちらはほんの一瞬です。(^_^)
これで、AKI-H8のプログラミングは完了です。そこで、
このように
まず、いったん電源スイッチS6をOFFにします。S7を電源を入れた
状態で変化させてはいけません。
そして次に、
このように
モードスイッチのS7をOFF側にします。このスイッチの意味は、
プログラミングモードのON/OFFということですので、OFFという
のは、「通常の実行モード」ということになります。
そして、S7がOFF側(実行モード)にあることを確認した上で、再び
このように
電源スイッチS6をONにします。これは、通常の電子機器としての
AKI-H8システムの電源をONにした、という事に相当します。
すると
このように
AKI-H8が動作して、LCDパネルにメッセージが見事に表示されました。
下段の数字の羅列はスイッチ状態の表示で、右側の8ビットはDIPスイッチの
状態とちゃんと対応しています。また、
このように
右側の二つのプッシュスイッチについては、LCDパネルとともに
DIPの上のLEDも対応して光るようになっています。
この秋月のサンプルプログラムは、以下のようなものです。
; サンプルソフト MBTEST.MOT
; 16文字*2行LCDの接続
; データ=ポート3
; E =ポート3のビット5
; RS =ポート3のビット4
;
;■液晶表示の使い方
;1,ソフトウエアリセット
; ファンクションセット1
; ファンクションセット2
; ファンクションセット3
; ファンクションセット
;2,初期設定
; ファンクションセット
; 表示on
; エントリーモード
;3、上記終了後
;1文字のデータ表示または、コマンド
; RAM H'FEF10(@LCD_D)にデータをセット後
; データの場合はRSを1にセット、
; コマンドの場合はRSを0にセットし
; LCD_OUTをサブルーチンコールする。
;16文字2行表示
; RAM H'FEF11(@LCD162)から32文字文のデータをセット後
; LCDDSPをサブルーチンコールする。
;
; 接続
; H8マイコン LCD
; P3ー0 D4
; P3ー1 D5
; P3ー2 D6
; P3ー3 D7
; P3−5 E
; P3−4 RS
; GND R/W
;-----CPUの指定-----
.CPU 300HA
;-----シンボル-----
SW_D .EQU H'FFEF10 ;SW1-4の状態を入れるRAM
SW_D5 .EQU H'FFEF11 ;SW5の状態を入れるRAM
LCD_D .EQU H'FFEF12 ;LCDへのデータを入れるRAM
;(1バイト分)
LCD162 .EQU H'FFEF13 ;16文字2行分のデータをいれるRAM
P2DR .EQU H'FFFFC3 ;ポート2データレジスタ 8P-DIP(S5)
P3_D .EQU H'FFFFC6 ;ポート3データレジスタ
;LCDのデータ線
E_SIG .BEQU 5,P3_D ;イネーブル信号
RS .BEQU 4,P3_D ;RS信号
P4DR .EQU H'FFFFC7 ;ポート4データレジスタ
P5DR .EQU H'FFFFCA ;ポート5データレジスタ
LED1 .BEQU 0,P5DR ;LED1
LED2 .BEQU 1,P5DR ;LED2
;-----リセットベクトル-----
.SECTION RESET0,DATA,LOCATE=H'00000
.DATA.L INIT ;リセットベクトル
;-----I/Oの初期設定-----
.SECTION ROM,CODE,LOCATE=H'00100
INIT: MOV.L #H'FFF10,ER7 ;スタックポインタ設定
MOV.B #H'00,R0L ;ポート2を入力に設定(S5)
MOV.B R0L,@H'FFFFC1 ;ポート2
MOV.B #H'FF,R0L ;ポート2をプルアップに設定
MOV.B R0L,@H'FFFFD8 ;ポート2
MOV.B #H'FF,R0L ;ポート3を出力に設定
MOV.B R0L,@H'FFFFC4 ;ポート3
MOV.B #H'00,R0L ;ポート4を入力に設定
MOV.B R0L,@H'FFFFC5 ;ポート4
MOV.B #H'FF,R0L ;ポート4をプルアップに設定
MOV.B R0L,@H'FFFFDA ;ポート4
MOV.B #H'FF,R0L ;ポート5を出力に設定
MOV.B R0L,@H'FFFFC8 ;ポート5
;-----LCDの初期設定-----
;ーーーーーソフトウエアリセット-----
JSR @TIME00 ;15mSのWAIT (4mS*4)
JSR @TIME00
JSR @TIME00
JSR @TIME00
MOV.B #B'00100011,R0L ;LCDファンクションセット1
MOV.B R0L,@LCD_D
BCLR RS
JSR @LCD_OUT8
JSR @TIME00 ;4mSのWAIT
MOV.B #B'00100011,R0L ;LCDファンクションセット2
MOV.B R0L,@LCD_D
BCLR RS
JSR @LCD_OUT8
JSR @TIME00 ;4mSのWAIT
MOV.B #B'00100011,R0L ;LCDファンクションセット3
MOV.B R0L,@LCD_D
BCLR RS
JSR @LCD_OUT8
JSR @TIME00 ;4mSのWAIT
MOV.B #B'00100010,R0L ;ファンクションセット
MOV.B R0L,@LCD_D
BCLR RS
JSR @LCD_OUT8
JSR @TIME00 ;4mSのWAIT
;-----初期設定----
MOV.B #B'00101000,R0L ;ファンクションセット
MOV.B R0L,@LCD_D
BCLR RS
JSR @LCD_OUT4
JSR @TIME00 ;4mSのWAIT
MOV.B #B'00001110,R0L ;表示ON
MOV.B R0L,@LCD_D
BCLR RS
JSR @LCD_OUT4
JSR @TIME00 ;4mSのWAIT
MOV.B #B'00000110,R0L ;エントリーモード
MOV.B R0L,@LCD_D
BCLR RS
JSR @LCD_OUT4
JSR @TIME00 ;4mSのWAIT
;-----初期設定終了----
;-----液晶初期画面表示-----
MOV.B #B'00000001,R0L ;表示クリア
MOV.B R0L,@LCD_D
BCLR RS
JSR @LCD_OUT4
JSR @TIME00 ;4mSのWAIT
MOV.B #32,R0L
MOV.L #LCD162,ER1 ;液晶表示RAMのアドレスをセット
MOV.L #MOJI,ER2 ;初期文字データのアドレスをセット
SYOKI0: MOV.B @ER2+,R0H ;初期文字データをレジスタにいれる。
MOV.B R0H,@ER1 ;レジスタ値を液晶表示RAMにいれる
INC.L #1,ER1
DEC.B R0L ;文字数から1を引く
BNE SYOKI0 ;文字数が0になるまでくりかえす。
JSR @LCDDSP
;-----MAIN-----
MOV.B #0,R0L ;RAMのクリア
MOV.B R0L,@SW_D
MOV.B R0L,@SW_D5
BOTAN: MOV.B @P4DR,R0L ;SW1-4の状態の取得
MOV.B @SW_D,R0H ;RAMの内容をレジスタに読む
CMP.B R0H,R0L ;SWの状態をチェック
BEQ S5CHK ;変化が無ければS5CHKにジャンプ
JSR @S1_4 ;変化が有るので処理ルーチンへ
S5CHK: MOV.B @P2DR,R0L ;S5の状態を取得
MOV.B @SW_D5,R0H ;RAMの内容をレジスタに読む
CMP.B R0H,R0L ;SWの状態をチェック
BEQ BOTAN ;変化が無ければBOTANにジャンプ
JSR @S5 ;変化が有るので処理ルーチンへ
JMP @BOTAN
;-----MAINEND-----
;-----サブルーチン-----
;----液晶文字出力16文字*2行
LCDDSP: PUSH.L ER0
PUSH.L ER1
MOV.B #B'00000010,R0L ;カーソルホーム
MOV.B R0L,@LCD_D
BCLR RS
JSR @LCD_OUT4
JSR @TIME00 ;4mSのWAIT
;--1行目
MOV.B #16,R0L ;文字数のセット
MOV.L #LCD162,ER1 ;液晶表示RAMのアドレスをセット
LCDDSP1: MOV.B @ER1+,R0H ;文字データをレジスタにいれる。
MOV.B R0H,@LCD_D ;文字データをRAMにいれる。
BSET RS ;データなのでRSを1にする。
JSR @LCD_OUT4 ;サブルーチンコール
BCLR RS ;RSを0にもどす。
DEC.B R0L ;文字数から1を引く
BNE LCDDSP1 ;文字数が0になるまでくりかえす。
MOV.B #B'11000000,R0L ;カーソルを2行目にする。
MOV.B R0L,@LCD_D
BCLR RS
JSR @LCD_OUT4
;--2行目
MOV.B #16,R0L ;文字数のセット
MOV.L #LCD162 + 16,ER1 ;液晶表示RAMのアドレスをセット
LCDDSP2: MOV.B @ER1+,R0H ;文字データをレジスタにいれる。
MOV.B R0H,@LCD_D ;文字データをRAMにいれる。
BSET RS ;データなのでRSを1にする。
JSR @LCD_OUT4 ;サブルーチンコール
BCLR RS ;RSを0にもどす。
DEC.B R0L ;文字数から1を引く
BNE LCDDSP2 ;文字数が0になるまでくりかえす。
POP.L ER1
POP.L ER0
RTS
;-----LCDへのデータ、コマンド出力-----
LCD_OUT8: PUSH.L ER0 ;レジスタ待避
BSET E_SIG ;液晶のE信号をセットする。
MOV.B @LCD_D,R0L ;データ(コマンド)をレジスタに入れる
MOV.B R0L,@P3_D ;液晶にデータ(コマンド)を出力
JSR @TIME10 ;WAIT
BCLR E_SIG ;液晶のE信号を0にする。
JSR @TIME10 ;WAIT
POP.L ER0 ;レジスタの復帰
RTS
;-----LCDへのデータ、コマンド出力 4bit -----
LCD_OUT4: PUSH.L ER0 ;レジスタ待避
;--上位4ビット送出
BSET E_SIG ;液晶のE信号を1にする。
MOV.B @LCD_D,R0L ;データ(コマンド)をレジスタに入れる
SHLR.B R0L ;4ビットモードなので上位4ビットを
SHLR.B R0L ;下位に移動
SHLR.B R0L
SHLR.B R0L
AND.B #B'00001111,R0L ;データ線以外をマスクする。
MOV.B @P3_D,R0H ;RS信号の待避
AND.B #B'11110000,R0H ;RS信号、E信号以外をマスク
OR.B R0H,R0L ;RS信号,E信号、データ(4ビット)
;を合成する。
MOV.B R0L,@P3_D ;合成したすべての信号を液晶に出力
JSR @TIME10 ;WAIT
BCLR E_SIG ;液晶のE信号を0にする
JSR @TIME10 ;WAIT
;--上位4ビット送出
BSET E_SIG ;液晶のE信号を1にする
MOV.B @LCD_D,R0L ;データ(コマンド)をレジスタに入れる
AND.B #B'00001111,R0L ;データ線下位4ビット以外をマスクする
MOV.B @P3_D,R0H ;RS信号の待避
AND.B #B'11110000,R0H ;RS信号、E信号以外をマスク
OR.B R0H,R0L ;RS信号,E信号、データ(4ビット)
;を合成する
MOV.B R0L,@P3_D ;合成したすべての信号を液晶に出力
JSR @TIME10 ;WAIT
BCLR E_SIG ;液晶のE信号を0にする
JSR @TIME10 ;WAIT
POP.L ER0 ;レジスタの復帰
RTS
;-----液晶表示S1-4-----
S1_4: MOV.B R0L,@SW_D ;現在の状態をRAMに格納
MOV.B #4,R1L ;文字数のセット
MOV.L #LCD162 + 20,ER2 ;液晶表示アドレスをセット
MOV.B @SW_D,R0L ;スイッチの状態をレジスタに読む
BOTAN1: ROTL.B R0L
MOV.B R0L,R0H
AND.B #B'00000001,R0H ;SWの状態をアスキーコードに変換
OR.B #B'00110000,R0H
MOV.B R0H,@-ER2 ;アスキーコードを液晶表示RAMに格納
DEC.B R1L ;文字数から1を引く
BNE BOTAN1 ;文字数が0になるまでくりかえす。
JSR @LCDDSP
;---LED
SW3LED: MOV.B @SW_D,R0L ;在の状態をRAMに格納
BTST #6,R0L ;S3の状態をチェック
BEQ BOTAN2 ;押されていればBOTAN2にジャンプ
BCLR LED1 ;押されていないので消灯
JMP @SW4LED
BOTAN2: BSET LED1 ;押されているので点灯
SW4LED: BTST #7,R0L ;S4の状態をチェック
BEQ BOTAN3 ;押されていればBOTAN3にジャンプ
BCLR LED2 ;押されていないので消灯
RTS
BOTAN3: BSET LED2 ;押されているので点灯
RTS
;-----液晶表示S5-----
S5: MOV.B R0L,@SW_D5 ;現在の状態をRAMに格納
MOV.B #8,R1L ;文字数のセット
MOV.L #LCD162 + 29,ER2 ;液晶表示アドレスを読む
MOV.B @SW_D5,R0L ;RAMの内容をレジスタに読む
BOTAN4: ROTL.B R0L
MOV.B R0L,R0H
AND.B #B'00000001,R0H ;SWの状態をアスキーコードに変換
OR.B #B'00110000,R0H
MOV.B R0H,@-ER2 ;アスキーコードを液晶表示RAMに格納
DEC.B R1L ;文字数から1を引く
BNE BOTAN4 ;文字数が0になるまでくりかえす。
JSR @LCDDSP ;
RTS
;-----4mSタイマ-----
TIME00: PUSH.L ER0
MOV.L #H'2000,ER0
TIME01: SUB.L #1,ER0
BNE TIME01
POP.L ER0
RTS
TIME10: PUSH.L ER0
MOV.L #H'AA,ER0 ;450nS TIMER
TIME11: SUB.L #1,ER0
BNE TIME11
POP.L ER0
RTS
;-----サブルーチン終了-----
;-----文字データ-----
.ALIGN 2
.SECTION LCDDATA,DATA,LOCATE=H'01000
MOJI: .SDATA "AKI-H8 "
.DATA.B H'0CF,H'0BB,H'0DE,H'0B0,H'0CE
.DATA.B H'0DE,H'0B0,H'0C4,H'0DE
.SDATA "1111 11111111 "
.END
あまり見やすいという気はしませんが(^_^;)、まともに馬鹿正直に
やっている、というところでしょう。プログラミングに興味のある人は
これを解読できれば、もう自分で作れますね。
ということで、もう、AKI-H8はびしばし走ってしまいました。
この状態で、作業ディレクトリ内には、
このように
ごちゃごちゃと不要なファイルが増えています。必要な時にはまた
アセンブルすればいい、という視点に立てば、ソースだけあれば
いいのです。そこで
このように
お掃除してやると、スッキリします。また、MOTファイルは毎回、
同じファイル名にすると、いちいち捜す時に何も考えなくてよく
なります。
このような発想をまとめて、実際に僕が使っているのは、
このような
バッチプログラムです。いまどきのWindowsな人たち(DOSな人でない(^_^;))は、
MS-DOSのバッチなんて知らないかもしれませんが、いい勉強になるので
調べてみましょう。
この場合、たとえばソースプログラムが「TEST01.SRC」であれば、
「ASM TEST01」とだけ入力してやると、フルオートで
アセンブル、リンク、コンバート、が進行してMOTファイルが
出来ます。そしてキー入力を待ってFLASH.EXEも起動され、
最後には不要ファイルも消してくれます。こういう文化は
残したいものですが。(^_^;)
ということで、これにて「ソフト開発」編もおしまいです。秋月のLCD
ソフトを改造する、というのも面白そうですし、AKI-H8マザーボード
のユニバーサル部分にMIDIを増設したいところですが、これは
またいずれ。(^_^)
|