ミュウアセンブラを使うと変数演算やタイマー・ポート命令など細かい制御が出来ます。ミュウアセンブラ一覧表を見ながらサンプルプログラムをご覧ください。
■ミュウアセンブラの処理速度
ミュウアセンブラの1ステップの実行時間をタイマーを使って計測します。
■タイマーとポート命令を使う
ミュウロボ命令の時間単位は、0.1秒です。これより短い時間でLEDを点滅してみます。
■ミュウロボ命令codeの実行
ミュウロボ命令codeを1(左前)から11(左回り)まで1.5秒間、順次実行するプログラム。
■ミュウアセンブラを使って再帰プログラム
IXレジスタやIXMレジスタを使うと再帰プログラムが可能になります。
●ミュウアセンブラの処理速度
ミュウロボ制御基板はPIC16F630の内部クロック4MHzで動作しています。PICの場合、4サイクルで1命令を実行するので1Sec(秒)/4MHz x 4=1nSecがPIC1命令を実行する時間となります。ミュウアセンブラの場合はPICが命令をEEPROMから読み、どの命令か判断し、実行するというプロセスを経るので1命令、数十nSecかかります。これをタイマー1を使って計測してみましょう。
//ミュウアセンブラの処理速度 (ドリトル)
ロボ太=シリアルポート!作る。
ロボ太:転送命令=「!はじめロボット
CLT1L //タイマー1下位8ビットをクリア
T1LA //タイマー1下位8ビットをAレジスタにセット
10 アンカー //アンカー番号10を宣言
1 ブザー //0.1秒ブザーを鳴らす
5 時間 //0.5秒のウエイト
DECA //Aレジスタを-1
10 JNZ //ゼロでなければアンカー番号10にジャンプ
おわりロボット」。
ロボ太! ”com1"ひらけごま。
ロボ太!転送命令。
ロボ太!とじろごま。
//ミュウアセンブラの処理速度 (myurobo.exe)
CLT1L //タイマー1下位8ビットをクリア
T1LA //タイマー1下位8ビットをAレジスタにセット
アンカー,10 //アンカー番号10を宣言
ブザー,1 //0.1秒ブザーを鳴らす
時間,5 //0.5秒のウエイト
DECA //Aレジスタを-1
JNZ,10 //ゼロでなければアンカー番号10にジャンプ
このプログラムではタイマー1をクリアしてAレジスタにセットする間にタイマー1が幾つカウントしているかを見るものです。Aレジスタの値をブザーの鳴る回数で判るようにしました。タイマー1のサイクルは8nSecですから8x4=32nSecがT1LAの実行時間となります。
※命令によって実行時間は違います。
●タイマーとポート命令を使う
0.05秒間隔でLEDを点滅するプログラムを作ってみました。タイマー1上位8ビットは0.008x256=2.048mSecサイクルです。タイマー1と24を比較することで0.05秒を判別します。LEDはポートAの5ビット目(32)をON/OFFすることで点滅します。入出力プログラム参照
//タイマーとポート命令を使う (ドリトル)
ロボ太=シリアルポート!作る。
ロボ太:転送命令=「!はじめロボット
30 アンカー //アンカー番号30を宣言
CLT1H //タイマー1上位8ビットをクリア
32 PA //32をポートAに出力(LEDを消灯)
20 アンカー //アンカー番号20を宣言
T1HA //タイマー1上位8ビットをAレジスタにセット
24 CMP //Aレジスタと24を比較(0.05秒)
20 JC //24より少なければアンカー番号20へジャンプ
CLPA //ポートAをクリア(LEDを点灯)
10 アンカー //アンカー番号10を宣言
T1HA //タイマー1上位8ビットをAレジスタにセット
48 CMP //Aレジスタと48を比較(0.1秒)
10 JC //48より少なければアンカー番号10へジャンプ
30 ジャンプ //アンカー番号30へジャンプ
おわりロボット」。
ロボ太! ”com1"ひらけごま。
ロボ太!転送命令。
ロボ太!とじろごま。
//タイマーとポート命令を使う (myurobo.exe)
アンカー,30 //アンカー番号30を宣言
CLT1H //タイマー1上位8ビットをクリア
PA,32 //32をポートAに出力(LEDを消灯)
アンカー,20 //アンカー番号20を宣言
T1HA //タイマー1上位8ビットをAレジスタにセット
CMP,24 //Aレジスタと24を比較(0.05秒)
JC,20 //24より少なければアンカー番号20へジャンプ
CLPA //ポートAをクリア(LEDを点灯)
アンカー,10 //アンカー番号10を宣言
T1HA //タイマー1上位8ビットをAレジスタにセット
CMP,48 //Aレジスタと48を比較(0.1秒)
JC,10 //48より少なければアンカー番号10へジャンプ
ジャンプ,30 //アンカー番号30へジャンプ
※LEDと圧電ブザーは、同じポートを使っています。LEDを点滅させると圧電ブザーからも音が出ます。
●ミュウロボ命令codeの実行
CMD命令は引数にミュウロボ命令codeをセットすることでその命令を実行できます。引数に85(CMD命令)をセットすると第1引数用レジスタARG1の値の命令を実行します。ARG1に1をセットすると左前を実行しますが実行時間も1(0.1秒)となってしまいます。このプログラムではミュウロボ命令codeを1(左前)から11(左回り)まで順次実行しますが一定時間(1.5秒)動かす為にARG1と15との差をウエイトとして実行するようにしてあります。
ミュウロボ命令codeはミュウロボ命令一覧やミュウアセンブラ一覧をご覧ください。
//ミュウロボ命令codeの実行 (ドリトル)
ロボ太=シリアルポート!作る。
ロボ太:転送命令=「!はじめロボット
CLIX //IXレジスタをクリア
10 アンカー //アンカー番号10を宣言
INCIX //IXレジスタを+1
IXA //IXレジスタをAレジスタにセット
AARG1 //AレジスタをARG1にセット
85 CMD //ミュウロボ命令85(CMD命令)を実行
15 A //Aレジスタに15をセット
SUBARG1 //Aレジスタ = Aレジスタ - ARG1 15とARG1の差をAレジスタにセット
AARG1 //AレジスタをARG1にセット
5 CMD //ミュウロボ命令5(時間命令)を実行
IXA //IXレジスタをAレジスタにセット
11 CMP //Aレジスタと11を比較
10 JNZ //Aレジスタが11でない場合、アンカー番号10にジャンプ
おわりロボット」。
ロボ太! ”com1"ひらけごま。
ロボ太!転送命令。
ロボ太!とじろごま。
//ミュウロボ命令codeの実行 (myurobo.exe)
CLIX //IXレジスタをクリア
アンカー,10 //アンカー番号10を宣言
INCIX //IXレジスタを+1
IXA //IXレジスタをAレジスタにセット
AARG1 //AレジスタをARG1にセット
CMD,85 //ミュウロボ命令85(CMD命令)を実行
A,15 //Aレジスタに15をセット
SUBARG1 //Aレジスタ = Aレジスタ - ARG1 15とARG1の差をAレジスタにセット
AARG1 //AレジスタをARG1にセット
CMD,5 //ミュウロボ命令5(時間命令)を実行
IXA //IXレジスタをAレジスタにセット
CMP,11 //Aレジスタと11を比較
JNZ,10 //Aレジスタが11でない場合、アンカー番号10にジャンプ
●ミュウアセンブラを使って再帰プログラム
ドリトルのサンプルの中に二分木という再帰プログラムがあります。
// 二分木
木=「|x|「x>1」!なら
「!(x)歩く 45 左回り (x/2)木 90 右回り (x/2)木 45 左回り(x)戻る」実行。
自分」。
タートル!作る 200 木。
再帰プログラムとはブロック内から自分自身を呼出すプログラムのことです。再帰プログラムを利用するとプログラムがシンプルになります。通常、自分自身を呼出すと無限に呼出すことになりエラーとなりますから自分自身から抜け出す工夫が必要です。上の例では (x/2)木 の所でxを半分にして自分自身を呼出し、「|x|「x>1」!なら の部分でxの値をチェックして戻るようになっています。
下は二本木をミュウアセンブラを使って実現したものです。ドリトルの変数はローカル変数として機能しますがミュウアセンブラではそれが出来ません。呼出された深さをIXレジスタにセットしIXMが深さごとに数値を独立して保存することで再帰プログラムを実現しました。
//ミュウアセンブラを使って再帰プログラム( 二分木) (myurobo.exe)
ロボ太=シリアルポート!作る。
ロボ太:転送命令=「!はじめロボット
CLIX //IXレジスタをクリヤ(IX=0)
32 IXM //IXM=32 最初の前進時間をセット
10 ブロック実行 //ブロック番号10を呼び出す
2 ブザー //ブザーを鳴らして終了
10 ブロックはじめ //ブロック番号10を宣言
IXMA //Aレジスタ=IXM
AARG1 //ARG1=Aレジスタ 実行時間をセット
2 CMD //前進命令を実行 2は前進命令
10 停止 //1秒間の停止
4 CMP //Aレジスタと4を比較。
10 JZ //結果がゼロ(Aレジスタ=4)ならアンカー番号10へジャンプ。
5 左回り //45度左旋回
10 停止 //1秒間の停止
INCIX //IXレジスタを+1する
CLC //C(キャリー)フラグクリア
RRA //Aレジスタを右シフト(Aレジスタを1/2にする)
AIXM //IXM=Aレジスタ 半分にした実行時間をセット
10 ブロック実行 //自分自身の呼出し
10 右回り //90度右旋回
10 停止 //1秒間の停止
10 ブロック実行 //自分自身の呼出し
5 左回り //45度左旋回
10 停止 //1秒間の停止
DECIX //IXレジスタを−1する
10 アンカー //アンカー番号10を宣言 アンカー番号とブロック番号の重複は可
IXMA //Aレジスタ=IXM
AARG1 //ARG1=Aレジスタ 実行時間をセット
8 CMD //後退命令を実行 8は後退命令
10 停止 //1秒間の停止
ブロックおわり
おわりロボット」。
ロボ太! ”com1"ひらけごま。
ロボ太!転送命令。
ロボ太!とじろごま。
//ミュウアセンブラを使って再帰プログラム( 二分木) (myurobo.exe)
CLIX //IXレジスタをクリヤ(IX=0)
IXM,32 //IXM=32 最初の前進時間をセット
ブロック実行,10 //ブロック番号10を呼び出す
ブザー,2 //ブザーを鳴らして終了
ブロックはじめ,10 //ブロック番号10を宣言
IXMA //Aレジスタ=IXM
AARG1 //ARG1=Aレジスタ 実行時間をセット
CMD,2 //前進命令を実行 2は前進命令
停止,10 //1秒間の停止
CMP,4 //Aレジスタと4を比較。
JZ,10 //結果がゼロ(Aレジスタ=4)ならアンカー番号10へジャンプ。
左回り,5 //45度左旋回
停止,10 //1秒間の停止
INCIX //IXレジスタを+1する
CLC //C(キャリー)フラグクリア
RRA //Aレジスタを右シフト(Aレジスタを1/2にする)
AIXM //IXM=Aレジスタ 半分にした実行時間をセット
ブロック実行,10 //自分自身の呼出し
右回り,10 //90度右旋回
停止,10 //1秒間の停止
ブロック実行,10 //自分自身の呼出し
左回り,5 //45度左旋回
停止,10 //1秒間の停止
DECIX //IXレジスタを−1する
アンカー,10 //アンカー番号10を宣言 アンカー番号とブロック番号の重複は可
IXMA //Aレジスタ=IXM
AARG1 //ARG1=Aレジスタ 実行時間をセット
CMD,8 //後退命令を実行 8は後退命令
停止,10 //1秒間の停止
ブロックおわり
※ロボットの動きは電池の有無や部品のバラつきなどによって変わってきます。動きを二分木に近づけるにはロボットごとに調整が必要です。