アセンブリ言語で、LEDチカチカをやってみた。
アセンブリ言語でプログラムを書いて、LEDチカチカをやってみた。
下が、そのプログラム、40行まで、初期設定である。
29、30行で変数のラベルを設定。
34行からがメインプログラム、35行でメモリのバンクを1に変更。
(TRISレジスタがバンク1にあるから)
36,37行でPORTAおよびBを全部出力に設定。
38でメモリのバンクを0に戻す。
39、40行で、コンパレータをOFFにし、1、2、17、18ピンをデジタル入出力に設定。
上の続き。
42行はLIGHTというラベルを設定。
43行でLED点灯用データをWレジスタに入れる。
44行でWレジスタのデータをPORTBにいれて、LEDを点灯させる。
45行は、DELAYサブルーチン(待ち時間作成サブルーチン)に飛ぶ。
46行でPORTBをクリア(0にする)して、LEDを消す。
47行は、DELAYサブルーチンに飛ぶ。
48行で、LIGHT(ラベル)に飛ぶ。
以上で、42行から、48行までを永久に繰り返すことにより、LEDが点滅し続ける。
以下、サブルーチンの説明。
50行がDELAYサブルーチンの始まり、DELAYというラベルにした。
51行で、繰り返し回数データ(0FFh、10進数で255)をWレジスタに入れる。
52行で、Wレジスタのデータを変数COUNT1に入れる。
54行が繰り返しの始まり、LOOP1というラベルにした。
55行は、DELAYSサブルーチン(待ち時間作成サブルーチン)に飛ぶ。
56行は、COUNT1から1を引き、COUNT1が0でない時次の行に行き、0の時は、次の行をNOP命令にして実行後、その次(58行)の行に行く。
57行は、LOOP1に飛ぶ。
(54行から、57行までが255回繰り返されるとCOUNT1が0になり、58行が実行され、CALL命令の次の行に戻る。)
58行は、CALL命令の次の行に飛ぶ。
60行から、68行までは、54行から、57行までとほぼ同じ内容で、65行のみNOP命令になっているだけである。
CALL命令で、DELAYサブルーチンが呼び出されると、LOOP1を255回実行する内にLOOP2が255回呼び出され実行される、この実行時間をLEDの点灯および消灯時間にしている。
その時間は、アセンブリ言語ではほぼ正確に算出できる。
まず1命令の実行時間は、クロックが4MHzだから、1μSとなる。
では、命令の数を計算してみよう、命令の数が算出できれば、命令数✖1μSで、計算できる。
まず、50行から、DELAYはラベルであり命令ではないので、数えない。
51行と52行で、2命令。
55行はCALL命令で、2サイクル命令なので、2命令。
ここで60行に飛んで、61行と62行で2命令。
65,66,67行は、3命令で、254回繰り返すので、3✖254=762命令。
65,66,67行の最後の1回は、65.66,67(NOP命令になる)の3命令とリターン命令(2サイクル命令)で5命令。
つまり、DELAYSサブルーチンの命令数は、769命令。
56行にサブルーチンから戻ってくると、56、57行で2命令。
55行から、57行までは254回繰り返されるので、(2+769+2)✖254=196,342命令。
55行から、57行までの最後は、55行の762命令と56、57行の2命令とリターン命令の2命令で、766命令。
従って、全体の命令数は、51行と52行で、2命令と55~57行の196,342命令と55行から、57行までの最後の766命令で、合計197,110命令です。
時間は、197,110命令✖1μS=197.110mS=0.19711Sと言う事で、約0.2秒と言う事になります、したがって、LEDは0.2秒点灯し0.2秒消灯するを繰り返すことになります。
上のプログラムを実行させてみました。