検索
連載

たかがLチカされどLチカ、バイナリコードでLEDを点滅させるオリジナルCPUでバイナリコード入門(9)(3/3 ページ)

オリジナル4ビットCPUを用いてバイナリコードを学ぶ本連載。第9回では、プログラミング演習の定番であるLチカを題材にバイナリコードを動かしてみる。

Share
Tweet
LINE
Hatena
前のページへ |       

Tang Nano基板側のLEDを点滅させてみる

 ここまでのLチカのサンプルプログラムは、CPU内部のレジスタの値を操作することで、ドットマトリクスのLEDを点滅させてきました。ここからのサンプルプログラムでは、Tang Nano基板上のLEDを点滅させてみます。DL166では、レジスタR6が外部制御用のレジスタに割り当てられています。また、今回の実装ではレジスタR6はTang Nanoの評価モジュールの6個あるオレンジ色のLEDのうち上から4つのLEDに割り当てられています。一番上のLEDが最下位ビットで、その下側の4個目のLEDが最上位ビットとなります。そこからさらに下側のLEDは、電源が入っているときは常に点灯しています。

 さてそれではblink5.asm(リスト5)のコードを見ていきましょう。基本的には先に示したblink1.asmと同じアイデアなのですが、mviという即値命令はレジスタR0にしか使えないので、1と0を交互にR0にセットしてそれをmov命令でレジスタR6に転送する方法を用いています。

 ただし、これだとmov R6,R0が追加されている分、blink1.asmに比べて1クロック分余計に時間がかかりLEDの点滅の間隔はさらに長くなってしまいます。それと点灯している時間が2クロック分なのに対しjmp命令があるため消灯時間は3クロック分になってしまいます。

ram[0] <=8'b1010_0001;  // mvi R0,1
ram[1] <=8'b00_110_000; // mov R6,R0
ram[2] <=8'b1010_0000; 	// mvi R0,0
ram[3] <=8'b00_110_000; // mov R6,R0
ram[4] <=8'b1001_0000;  // jmp 	0
リスト5 blink5.asmのコード

 図3はblink5.asmを実行した様子です。基板上のLEDが見えやすいようにLEDドットマトリクスはソケットから外しています。6個縦に並んだオレンジのLEDのうち、一番上のLEDが点灯しているのが分かります。別のタイミングではそのLEDは消灯しており、点滅を繰り返します。

図3
図3 blink5.asmによる基板上LEDのLチカ[クリックで拡大]

 LEDの点滅の間隔は速くなりませんが、点灯と消灯の間隔が同じなるプログラムを書いてみました。blink6.asm(リスト6)では、点灯と消灯の時間が不均衡になる原因であるjmp命令を外しました。

ram[0] <=8'b1010_0001;  // mvi R0,1
ram[1] <=8'b00_110_000; // mov R6,R0
ram[2] <=8'b1010_0000; 	// mvi R0,0
ram[3] <=8'b00_110_000; // mov R6,R0
ram[4] <=8'b1010_0001;  // mvi R0,1
ram[5] <=8'b00_110_000; // mov R6,R0
ram[6] <=8'b1010_0000; 	// mvi R0,0
ram[7] <=8'b00_110_000; // mov R6,R0
ram[8] <=8'b1010_0001;  // mvi R0,1
ram[9] <=8'b00_110_000; // mov R6,R0
ram[10]<=8'b1010_0000;	// mvi R0,0
ram[11]<=8'b00_110_000; // mov R6,R0
ram[12]<=8'b1010_0001;  // mvi R0,1
ram[13]<=8'b00_110_000; // mov R6,R0
ram[14]<=8'b1010_0000;  // mvi R0,0
ram[15]<=8'b00_110_000; // mov R6,R0
リスト6 blink6.asmのコード

 DL166の仕様ではプログラムカウンタが上限までカウントアップするとまた0に戻るので、それを利用してjmp命令なしにループを実現しています。blink5.asmの4行目までのコードを4回繰り返しています。

 さて次のプログラムのblink7.asm(リスト7)では、LEDの点滅の間隔を短くする工夫を取り入れました。レジスタR0に0、レジスタR1に1をあらかじめ入れておいて、それをmov命令で交互にレジスタR6に転送する方法です。ですが、LEDの消灯が1クロック分に対して点灯は2クロック分の時間がかかってしまいます。

ram[0]<=8'b1010_0001;  // mvi R0,1
ram[1]<=8'b00_001_000; // mov R1,R0
ram[2]<=8'b1010_0000;  // mvi R0,0
ram[3]<=8'b00_110_000; // mov R6,R0
ram[4]<=8'b00_110_001; // mov R6,R1
ram[5]<=8'b1001_0000;  // jmp 	3
リスト7 blink7.asmのコード

 LEDが4つとも点滅しますがblink8.asm(リスト7)のようなコードもあります。

ram[0] <=8'b01_101_110;  // not R6
ram[1] <=8'b1001_0000;   // jmp 0
リスト8 blink8.asmのコード

おわりに

 いかがでしたか。「たかがLチカされどLチカ」と題していろんなLチカを試してみました。プログラミングなのに、ゲームかパズルを解いているかのような感覚だったのではないでしょうか。これを機会にバイナリコーディングに親しんで頂ければ幸いです。それではまた次回をお楽しみに。

Copyright © ITmedia, Inc. All Rights Reserved.

前のページへ |       
ページトップに戻る