低予算での実習を行うにあたり、非常に低価格のUSB接続ROMエミュレーターを開発していただいたT&Aの佐藤様に感謝します。佐藤様の尽力が無ければ、この実習の実現は不可能でした。
1chip マイコンのプログラム手法を習得し、パソコンだけではできないリアルタイム性を持った機器の制御、データの収集等を行える機器のソフトウエア開発能力を身につける。
寺脇が常に使用しているマイコン開発環境と同じ環境を再現し、その開発手法を学ぶ。通常、500Kbyte。最大1.5Mbyte位のプログラムの開発実績がある。ほとんどのマイコンで利用できる開発環境。開発に関する制約がほとんど無し。
最近の開発動向プログラム開発
プログラム開発 | gnu の成果を利用(Linuxも同様) |
---|---|
プリント基板 | 100x79程の2層基板ならばフリーの回路図CADを使って、5000円程度で製作できる(ただし、商用利用は不可) |
デジタル回路 | CPLD/FPGA を使用し、VHDL言語で回路動作を記述する。最近では、これらの中に CPUを入れられる。 |
アナログ回路 | 今回学習するのは、プログラム開発のみ |
CPUとは、メモリーのアドレスの内容を読込み、それを命令として実行する。メモリーは、データとして読み書きできる。命令は、アドレス順に実行される。(付録:ROM)
通常、CPUが読込みしかできないメモリーである。例:パソコンのBIOS、ファミコンのカセット
読み書きができるメモリーである。このマイコンでは、特殊なRAMがあり、その内容を書き換えることで、LEDを点灯させるようなことができる。(パソコン上のプログラムは、常にここで、実行される)
演算を行う場合は、レジスタで演算する。例えば、メモリの内容を+1したい時には
・メモリの内容をレジスタに読込む
・レジスタの内容を+1する
・レジスタの内容をメモリに書込む
mov.l@0xeb80:16,er2
adds#1,er2
mov.ler2,@0xeb80:16
今回使用するCPUには、er0~er7がある。(マニュアル40P)
次に実行する命令のメモリーアドレスを示す。
CPUは、プログラムカウンタが指し示すアドレスの内容を読込み、それを命令として実行する。通常、アドレスの順番に実行する。(マニュアル40P)
メモリに書込む/読込む 演算(整数の四則演算など) 比較命令 分岐命令(ジャンプ) (マニュアル46P)
演算の結果を格納する。Zeroフラグ、OverFlowフラグ等があり、この状態によって、プログラムの流れを変更することができる。
スタックについて
2.s を作成する(meadowの使い方)。
アセンブル
meadow 上で、M-! を実行し、以下のコマンドを入力し、アセンブルを行う。
h8300-hms-gcc -mh 1.s -o 1.x
gdbでの実行
meadow 上で、M-x shell を実行し、以下のコマンドを入力し、アセンブルを行う。
h8300-hms-gdb 1.x
3.c を作成する
コンパイル/gdb その1
ソースコード先頭部分のコメントになっているコマンドを実行する。
コンパイル/gdb その2
ソースコード先頭部分のコメントになっているコマンドを実行する。
(gdb にバグがあるので、一度アセンブルリストを出力し、それをアセンブルする)
組み立て
6.で作成した 3.c を CPUボードで実行できるようにする。
今回使用するデバッグ環境は、市販のICE(In Circuit Emulator)に比較すると、デバッグ時に収集できる情報が非常に少ない。この情報の少なさを補い、デバッグを効率的に進めるためには、デバッグを補佐するプログラムが必要である。ここでは、そのプログラムを含むフレームワークを提供する。
また、通常、プログラムは、複数のファイルに分けて作成される。その場合に効率良くコンパイルを進めるために make の使用方法を学ぶ。
課題1 LED を適当な周期で点滅させてみる。
課題2 適当な周期で、LCD 上の文字をブリンクさせてみる。
課題3 LEDを、3秒ON、1秒OFFの周期で点滅、LCDを 0.5秒周期でブリンクさせる。
9.の課題3を、マルチタスクを使用して書き直す。
StartTask(タスク番号,タスク関数);
KillTask(タスク番号);
Sleep(休眠時間);
multi0.c
ad.c
課題1 A/Dの値を、リアルタイムでLCDに表示し、その値が一定以上を越えた場合には、LEDを点滅させる
課題2 2つのA/Dの値をリアルタイムで LCDに表示する
回路
割込みとは、http://homepage1.nifty.com/rikiya/software/105timer2.htm
ソフトウエアの変更
initperi.c
InitPeripheral()関数の直前に以下の行を追加
int IrqCount ;
InitPeripheral()関数の中の頭に、
IrqCount = 0 ;
を追加
initperi.c の、Irq2() を以下のように書き換える。
int IrqCount ;
#pragma interrupt
void Irq2( void )
{
IrqCount ++ ;
}
hello.c
以下のプログラムを適当なところに入れる。
LcdLocate( 1, 10 ) ;
lcdprintf( "[%d]" , IrqCount ) ;
ハードウエアの追加
CN1-5 に SW を取りつける。
課題 SWを ON/OFF させることで、IrqCount を、LCDに表示する
マイコンは、COMポートを通じてパソコンにデータを送る。
パソコンのプログラムは、そのデータを受け取って、リアルタイムにデータを表示する。
マイコン側プログラム
COMポートにデータを出力するタスクを追加する。
パソコン側プログラム
ROM Emulator 無しのスタンドアローン状態で動作するようにする。書込みプログラムhttp://www.linet.gr.jp/~mituiwa/h8/index-j.html を使用する。(VineLinux3.1+秋月USBシリアルで動作するh8write))
手順
書込み時ジャンパー設定
CPUボード MD2 short
マザーボード JP1 short
実行時ジャンパー設定
CPUボード:全てopen
マザーボード:全てopen