目次
前
次
定番プログラム
ワンチップマイコンで、C言語の「Hello , World !」に
相当する定番プログラムは、8個のLEDを使って、一列に
並べた左右に光が流れるようにすることでしょう。
LED表示器をテスト基板に接続して、左右に光を
流してみます。
利用した基板は、以下。
プログラムは、次のようにしてみます。
;
; TEST program for 8048 ( PROASM-II )
; Copyright (C) 2017 Kensuke Ooyu
;
INCLUDE 8048.LIB
;****************
; define symbols
;****************
ENTRY equ 0h
E_INT equ 3h
E_TIM equ 7h
;*******************
; interrupt vectors
;*******************
org ENTRY
jmp START
; external interrupt
org E_INT
retr
; timer interrupt
org E_TIM
retr
org 10h
;**************
; sub routines
;**************
INIT:
; disable external interrupt
dis i
; disable timer interrupt
dis tcnti
; initialize I/O
mov a,#0
outl p1,a
outl p2,a
;
ret
WAIT:
; set counter
mov R7,#0
WAITL:
nop
djnz R7,WAITL
;
ret
;**************
; main routine
;**************
org 100h
START:
call INIT
;
MAIN:
; set counter
mov R5,#8
mov R6,#1
MAIN1:
; impress
xch a,R6
outl P1,a
; delay
call WAIT
; rotate
rl a
xch a,R6
;
djnz R5,MAIN1
; set counter
mov R5,#8
mov R6,#128
MAIN2:
; impress
xch a,R6
outl P1,a
; delay
call WAIT
; rotate
rr a
xch a,R6
;
djnz R5,MAIN2
;
jmp MAIN
end
8048では、割込みベクタのアドレスが固定なので
以下の3エントリーアドレスを使います。
- 0h リセット
- 3h 外部割込み
- 7h タイマー割込み
10hより若いアドレスにあるコードは、Vectorに
なっているとして、3エントリーアドレスのみに
限定します。
8048では、プログラムをページ単位で処理する方が
作成効率がよいので、32バイト、64バイトの範囲に
収まるように、サブルーチンを構成しました。
10hからFFhまでの240バイトに、サブルーチンをおく
構成にし、100hから主ルーチンを配置。
今回用意したサブルーチンは、初期化と遅延の2種。
初期化サブルーチンでは、3種の処理をまとめました。
- 外部割込み禁止
- タイマー割込み禁止
- ポートの方向設定
遅延では、汎用レジスタR7に値を設定し
djnz命令で、ゼロになるまでnopを実行。
この程度のコードであれば、サブルーチン
ひとつに32バイトもいらないでしょう。
ワンチップマイコンのプログラミングでは
サブルーチンを定義して、それを呼び出す
構成が開発効率を上げることになります。
主ルーチンでは、LEDの点灯位置が左右に
移動するようにしました。
アキュムレータから表示パターンをポートに転送
すればよいので、汎用レジスタにLSB、MSBが1と
なるパターンを入れておきます。
汎用レジスタの値を、アキュムレータに転送して
回転させつつ、ポートへ出力するカラクリを構成
してみました。
左から右、右から左と別のルーチンにしています。
主ルーチンでの動作を理解しやすくするために
左から右、右から左のパターン変化を、個別に
扱うこともできます。
;
; TEST program for 8048 ( PROASM-II )
; Copyright (C) 2017 Kensuke Ooyu
;
INCLUDE 8048.LIB
;****************
; define symbols
;****************
ENTRY equ 0h
E_INT equ 3h
E_TIM equ 7h
;*******************
; interrupt vectors
;*******************
org ENTRY
jmp START
; external interrupt
org E_INT
retr
; timer interrupt
org E_TIM
retr
org 10h
;**************
; sub routines
;**************
INIT:
; disable external interrupt
dis i
; disable timer interrupt
dis tcnti
; initialize I/O
mov a,#0
outl p1,a
outl p2,a
;
ret
WAIT:
; set counter
mov R7,#0
WAITL:
nop
djnz R7,WAITL
;
ret
SFTL:
; set counter
mov R5,#8
mov R6,#1
SFTL1:
; impress
xch a,R6
outl P1,a
; delay
call WAIT
; rotate
rl a
xch a,R6
;
djnz R5,SFTL1
;
ret
SFTR:
; set counter
mov R5,#8
mov R6,#128
SFTR1:
; impress
xch a,R6
outl P1,a
; delay
call WAIT
; rotate
rr a
xch a,R6
;
djnz R5,SFTR1
;
ret
;**************
; main routine
;**************
org 100h
START:
call INIT
;
MAIN:
; left shift
call SFTL
; right shift
call SFTR
;
jmp MAIN
end
主ルーチンは、サブルーチンに対して
指示を与えるだけで対応できています。
アセンブルした結果は、以下。
0000 ;
0000 ; TEST program for 8048 ( PROASM-II )
0000 ; Copyright (C) 2017 Kensuke Ooyu
0000 ;
0000 INCLUDE 8048.LIB
0000 list
0000
0000 ;****************
0000 ; define symbols
0000 ;****************
0000 ENTRY equ 0h
0003 E_INT equ 3h
0007 E_TIM equ 7h
0000
0000 ;*******************
0000 ; interrupt vectors
0000 ;*******************
0000 org ENTRY
0000 2400 + jmp START
0002
0002 ; external interrupt
0002 org E_INT
0003 93 + retr
0004
0004 ; timer interrupt
0004 org E_TIM
0007 93 + retr
0008
0008 org 10h
0010 ;**************
0010 ; sub routines
0010 ;**************
0010 INIT:
0010 ; disable external interrupt
0010 15 + dis i
0011 ; disable timer interrupt
0011 35 + dis tcnti
0012 ; initialize I/O
0012 2300 + mov a,#0
0014 39 + outl p1,a
0015 3A + outl p2,a
0016 ;
0016 83 + ret
0017
0017 WAIT:
0017 ; set counter
0017 BF00 + mov R7,#0
0019 WAITL:
0019 00 + nop
001A EF19 + djnz R7,WAITL
001C ;
001C 83 + ret
001D
001D SFTL:
001D ; set counter
001D BD08 + mov R5,#8
001F BE01 + mov R6,#1
0021 SFTL1:
0021 ; impress
0021 2E + xch a,R6
0022 39 + outl P1,a
0023 ; delay
0023 1417 + call WAIT
0025 ; rotate
0025 E7 + rl a
0026 2E + xch a,R6
0027 ;
0027 ED21 + djnz R5,SFTL1
0029 ;
0029 83 + ret
002A
002A SFTR:
002A ; set counter
002A BD08 + mov R5,#8
002C BE80 + mov R6,#128
002E SFTR1:
002E ; impress
002E 2E + xch a,R6
002F 39 + outl P1,a
0030 ; delay
0030 1417 + call WAIT
0032 ; rotate
0032 77 + rr a
0033 2E + xch a,R6
0034 ;
0034 ED2E + djnz R5,SFTR1
0036 ;
0036 83 + ret
0037
0037 ;**************
0037 ; main routine
0037 ;**************
0037 org 100h
0100 START:
0100 1410 + call INIT
0102 ;
0102 MAIN:
0102 ; left shift
0102 141D + call SFTL
0104 ; right shift
0104 142A + call SFTR
0106 ;
0106 2402 + jmp MAIN
0108
0108 end
各サブルーチンは、16バイトにも満たないので
ページを跨ぐような奇抜な処理も取られてません。
主ルーチンは指示を与えるだけにして
実際の処理はサブルーチンに任せると
段階的詳細化ができます。
目次
前
次