このドキュメントは http://edu.net.c.dendai.ac.jp/ 上で公開されています。
あらかじめ与えられた特定のパターン(例えば 2 進数で与える)の値を PORTB に出力し、 LED を光らせたままにするプログラムを作りなさい。 (ヒント: 実行しているプログラムの番地はアセンブリ言語では $ で表します。 プログラムを止めるには sleep ではなく、単なる無限ループを作ります。)
;************
;* 例4-1 *
;************
list p=16f628a
#include p16f628a.inc
variable env
env = _BOREN_OFF
env &= _CP_OFF
env &= DATA_CP_OFF
env &= _PWRTE_OFF
env &= _WDT_OFF
env &= _LVP_OFF
env &= _MCLRE_OFF
env &= _INTOSC_OSC_NOCLKOUT
__config env
org 0x0000
goto start
org 0x0008
start
banksel TRISB
clrf TRISB
banksel PORTB
movlw b'01010101' ; 点灯させるビットパターン
movwf PORTB
goto $
end
あらかじめ与えられたふたつの特定のパターン(例えば 2 進数で与える)の値 のうちのどちらかが on になっている部分の LED を光らせるプログラムを作 りなさい。 (ヒント: ior 命令)
どちらのビットが on の時、on にするには両方のビットパターンに対して (inclusibe) OR を行います。 x or 0 = x, x or 1 = 1 より、ビットパターンが 0 の部分はそのままの値に なり、ビットパターンが 1 の部分は 1 になります。
;************
;* 例4-2 *
;************
list p=16f628a
#include p16f628a.inc
variable env
env = _BOREN_OFF
env &= _CP_OFF
env &= DATA_CP_OFF
env &= _PWRTE_OFF
env &= _WDT_OFF
env &= _LVP_OFF
env &= _MCLRE_OFF
env &= _INTOSC_OSC_NOCLKOUT
__config env
org 0x0000
goto start
org 0x0008
start
banksel TRISB
clrf TRISB
banksel PORTB
movlw b'01010101'
movwf PORTB
movlw b'00001111'
iorwf PORTB,1
goto $
end
あらかじめ与えられたふたつの特定のパターン(例えば 2 進数で与える)の値 のうちの両方が on になっている部分の LED を光らせるプログラムを作 りなさい。 (ヒント: and 命令)
あらかじめ与えられた特定のパターン(例えば 2 進数で与える)の値に対して、 2 進数で指定される特定の部分だけ反転させて LED を光らせるプログラムを作 りなさい。 (ヒント: xor 命令)
PORTB に接続した LED になにかパターンを表示し、 RA5 に接続した sw を押 した時に On , Off が反転するプログラムを作りなさい。
PORTB に接続した LED が RA5 に接続した sw を押す度に On , Off が反転す るプログラムを作りなさい。
LED のつながっている PORT B に対して、 PB0 のみ、 PB0 と PB1、 PB0 から PB2 まで、と順番に一つずつビットを 1 にしていき、全て 1 になったら全て消灯するプログラムを作りなさい。
第 2 回の flash プログラムを流用 します。
各パターンを書き込んで、wait を呼び出します。
;************
;* 例4-3 *
;************
list p=16f628a
#include p16f628a.inc
variable env
env = _BOREN_OFF
env &= _CP_OFF
env &= DATA_CP_OFF
env &= _PWRTE_OFF
env &= _WDT_OFF
env &= _LVP_OFF
env &= _MCLRE_OFF
env &= _INTOSC_OSC_NOCLKOUT
__config env
#define time D'3'
cblock 0x20
wa0,wa1,wa2
endc
org 0x0000
goto start
org 0x0008
start
banksel TRISB
clrf TRISB
banksel PORTB
main
movlw b'00000000'
movwf PORTB
call wait
movlw b'00000001'
movwf PORTB
call wait
movlw b'00000011'
movwf PORTB
call wait
movlw b'00000111'
movwf PORTB
call wait
movlw b'00001111'
movwf PORTB
call wait
movlw b'00011111'
movwf PORTB
call wait
movlw b'00111111'
movwf PORTB
call wait
movlw b'01111111'
movwf PORTB
call wait
movlw b'11111111'
movwf PORTB
call wait
goto main
wait
movlw time
movwf wa0
wait0
clrf wa1
wait1
clrf wa2
wait2
nop
decfsz wa2,1
goto wait2
decfsz wa1,1
goto wait1
decfsz wa0,1
goto wait0
return
end
これで美しくないと思った場合の別解を示します。 まず、考えられるのは似たようなパターンが出てきますので、これを一つのマ クロ命令で置き換えることです。
;**************
;* 例4-3 2 *
;**************
list p=16f628a
#include p16f628a.inc
variable env
env = _BOREN_OFF
env &= _CP_OFF
env &= DATA_CP_OFF
env &= _PWRTE_OFF
env &= _WDT_OFF
env &= _LVP_OFF
env &= _MCLRE_OFF
env &= _INTOSC_OSC_NOCLKOUT
__config env
#define time D'3'
cblock 0x20
wa0,wa1,wa2
endc
display macro pattern
movlw pattern
movwf PORTB
call wait
endm
org 0x0000
goto start
org 0x0008
start
banksel TRISB
clrf TRISB
banksel PORTB
main
display b'00000000'
display b'00000001'
display b'00000011'
display b'00000111'
display b'00001111'
display b'00011111'
display b'00111111'
display b'01111111'
display b'11111111'
goto main
wait
movlw time
movwf wa0
wait0
clrf wa1
wait1
clrf wa2
wait2
nop
decfsz wa2,1
goto wait2
decfsz wa1,1
goto wait1
decfsz wa0,1
goto wait0
return
end
プログラミングのコツとして、入出力部分を一箇所にまとめて、最小限にする ことが考えられます。 ループ変数を用意して、出力パターンを計算して出力することを考えます。 C 言語で書くと次のようになります。
for(;;){
pattern=0;
for(counter=1; counter<256; counter*=2){
pattern = counter | i;
pattern の出力;
}
}
counter *= 2 を実現するには rotateあるいは shift
と呼ばれる命令を使います。
これはレジスタの内容をビット毎に右又は左に移動する命令です。
単なる移動は shift で、溢れた bit を反対側の bit に回すのが rotate です。
PIC では STATUS の C bit を含めた rotate 命令のみがあります。
bit 毎に移動するということは、二進数で桁をずらすことになるので、 2 倍、
あるいは 1/2 にするということになります。
つまり、値を 2 倍するには左に rotate すれば良いことになります。
また、rotate した値が256 を越えると STATUS レジスタの C が 1 になりま
す。
なお、C 言語にも shift 演算 << と >> があります。
例えば、 count*=2
(2倍する) は
count<<=1
(左に 1 bit シフトする) と書けます。
但し、 counter に 1 が入ってから、 rotate で C=1 となる まで 8 回の繰り返しになるので、このプログラムのままでは全消灯を含めた 9 パターンは表示できません。
;**************
;* 例4-3 3 *
;**************
list p=16f628a
#include p16f628a.inc
variable env
env = _BOREN_OFF
env &= _CP_OFF
env &= DATA_CP_OFF
env &= _PWRTE_OFF
env &= _WDT_OFF
env &= _LVP_OFF
env &= _MCLRE_OFF
env &= _INTOSC_OSC_NOCLKOUT
__config env
#define time D'3'
cblock 0x20
counter
pattern
wa0,wa1,wa2
endc
org 0x0000
goto start
org 0x0008
start
banksel TRISB
clrf TRISB
banksel PORTB
main
clrf pattern
movlw 1
movwf counter
loop
movf counter,0
iorwf pattern,1
movf pattern,0
movwf PORTB ; 出力は一箇所
call wait
bcf STATUS,C
rlf counter,1
btfss STATUS,C
goto loop
goto main
wait
movlw time
movwf wa0
wait0
clrf wa1
wait1
clrf wa2
wait2
nop
decfsz wa2,1
goto wait2
decfsz wa1,1
goto wait1
decfsz wa0,1
goto wait0
return
end
前の解法はエレガントですが、パターンを計算して出力する点で応用が効きま せん。 そこで、パターンはデータとして列挙し、パラメータで呼び出すことにします。 そして、出力はやはり一箇所で行うようにします。
そのために使うのが算術ジャンプです。 パターンを RETLW で列挙して、W レジスタの値に応じてパターンを受けとり ます。
パターンの最大数はパターンの終了アドレスからパターンの開始アドレスを引 いて求めると、あとでパターンの変更をしてもパターンを出力するプログラム を変更する必要が無くなります。
;**************
;* 例4-3 4 *
;**************
list p=16f628a
#include p16f628a.inc
variable env
env = _BOREN_OFF
env &= _CP_OFF
env &= DATA_CP_OFF
env &= _PWRTE_OFF
env &= _WDT_OFF
env &= _LVP_OFF
env &= _MCLRE_OFF
env &= _INTOSC_OSC_NOCLKOUT
__config env
#define time D'3'
cblock 0x20
counter
wa0,wa1,wa2
endc
org 0x0000
goto start
org 0x0008
start
banksel TRISB
clrf TRISB
banksel PORTB
main
clrf counter
loop
movf counter,0
call getpat
movwf PORTB ; 出力は一箇所
call wait
incf counter,1
movlw enddata-startdata
subwf counter,0
btfss STATUS,Z
goto loop
goto main
getpat
addwf PCL,1
startdata
retlw b'00000000'
retlw b'00000001'
retlw b'00000011'
retlw b'00000111'
retlw b'00001111'
retlw b'00011111'
retlw b'00111111'
retlw b'01111111'
retlw b'11111111'
enddata
wait
movlw time
movwf wa0
wait0
clrf wa1
wait1
clrf wa2
wait2
nop
decfsz wa2,1
goto wait2
decfsz wa1,1
goto wait1
decfsz wa0,1
goto wait0
return
end
PORTB につながっている LED が 0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F を順番に表示するプログラムを作りなさい。
PORTB に接続した LED が RA5 に接続した sw を押す度に PORT B に つながっている LED が 0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F を順番に表示するプログラムを作りなさい。
ビットを off にするには off にしたいビットパターンを作り、AND を行います。 x and 0 = 0, x and 1 = x より、ビットパターンが 0 の部分は 0 になり、 ビットパターンが 1 の部分はそのままの値になります。
;************
;* 演習4-1 *
;************
list p=16f628a
#include p16f628a.inc
variable env
env = _BOREN_OFF
env &= _CP_OFF
env &= DATA_CP_OFF
env &= _PWRTE_OFF
env &= _WDT_OFF
env &= _LVP_OFF
env &= _MCLRE_OFF
env &= _INTOSC_OSC_NOCLKOUT
__config env
org 0x0000
goto start
org 0x0008
start
banksel TRISB
clrf TRISB
banksel PORTB
main
movlw b'01010101'
movwf PORTB
movlw b'00001111'
andwf PORTB,1
goto $
end
ビットを反転させるには反転させたいビットを指定するビットパターンを作り、 XOR を行います。 x xor 0 = x, x xor 1 = x より、ビットパ ターンが 0 の部分はそのままになり、 ビットパターンが 1 の部分は値が反転します。
;************
;* 演習4-2 *
;************
list p=16f628a
#include p16f628a.inc
variable env
env = _BOREN_OFF
env &= _CP_OFF
env &= DATA_CP_OFF
env &= _PWRTE_OFF
env &= _WDT_OFF
env &= _LVP_OFF
env &= _MCLRE_OFF
env &= _INTOSC_OSC_NOCLKOUT
__config env
org 0x0000
goto start
org 0x0008
start
banksel TRISB
clrf TRISB
banksel PORTB
main
movlw b'01010101'
movwf PORTB
movlw b'00001111'
xorwf PORTB,1
goto $
end
押してない時と押した時で PORTB の値を変化させます。 あらかじめ ON の時のパターンを W レジスタに入れておきます。 その後、btsfc PORTA,5 で RA5 のビットを検査します。 もし、OFF だったら押してないパターンを W レジスタに入れます。 そして、W レジスタの内容を PORTB に入れます。
そのため、 ON の時のパターン、 OFF の時のパターンをあらかじめ作ってお きます。 #define ディレクティヴで bitpattern ラベルにパターンを割り当てておきます。 ON の時のパターンはそのまま、OFF の時のパターンは b'11111111' と XOR を取って反転させておきます。
また、あらかじめ PORTA のコンパレータを無効にした後、 TRISA に b'00100000' を入れて、RA5 を入力ポートに割り当てておきます。
;************
;* 演習4-3 *
;************
list p=16f628a
#include p16f628a.inc
cblock 0x20
onpattern
offpattern
endc
#define bitpattern b'00011111'
variable env
env = _BOREN_OFF
env &= _CP_OFF
env &= DATA_CP_OFF
env &= _PWRTE_OFF
env &= _WDT_OFF
env &= _LVP_OFF
env &= _MCLRE_OFF
env &= _INTOSC_OSC_NOCLKOUT
__config env
org 0x0000
goto start
org 0x0008
start
movlw 0x07
movwf CMCON
banksel TRISA
movlw b'0010000'
movwf TRISA
clrf TRISB
banksel onpattern
clrf PORTA
movlw bitpattern
movwf onpattern
xorlw b'11111111'
movwf offpattern
main
movf offpattern,0
btfsc PORTA,5
movf onpattern,0
movwf PORTB
goto main
end
演習4-3 と同様の準備が必要です。
sw が押される度というのはどうやって考えれば良いでしょうか? sw は押している間 1 で、離すと 0 になります。 「1 なら反転」とすると、押している間反転を繰り返してしまうことになりま す。
押す度に切替えるには、押した瞬間に切替え、その後、幾ら押し続けても反転 しないようにする必要があります。 つまり、sw が押されてない状態から押された状態への変化を捉え、そこで反 転させます。 そのためには、直前の動作をファイルレジスタに取っておき、直前が 0 でス イッチが 1 の時だけ反転するようにします。
;************
;* 演習4-4 *
;************
list p=16f628a
#include p16f628a.inc
cblock 0x20
prev
endc
#define bitpattern b'00011111'
variable env
env = _BOREN_OFF
env &= _CP_OFF
env &= DATA_CP_OFF
env &= _PWRTE_OFF
env &= _WDT_OFF
env &= _LVP_OFF
env &= _MCLRE_OFF
env &= _INTOSC_OSC_NOCLKOUT
__config env
org 0x0000
goto start
org 0x0008
start
movlw 0x07
movwf CMCON
banksel TRISA
movlw b'0010000'
movwf TRISA
clrf TRISB
banksel PORTB
movlw bitpattern
movwf PORTB
clrf prev
main
btfsc PORTA,5
goto swon
swoff
clrf prev
goto main
swon
movf prev,1
btfss STATUS,Z
goto main
movlw d'1'
movwf prev
movlw b'11111111'
xorwf PORTB,1
goto main
end
なお、このように入力に対して動作が変化するようなプログラムをデバッグす る時は、 Stimulus を使用します(MPLAB IDE User's Guide 14 章 p.147)。 今回は手入力で RA5 を On, Off させますので、 CPU クロックではなく手の 入力に同期してシミュレーション中に RA5 を On, Off させる必要があります。
例4-3 4 のプログラムにおいて出力パターンを変更したものを作ります。 出力パターンは例4-3 のプログラムを動かして、どの LED がどのビットに 対応しているのかを調べると簡単です。
;************
;* 演習4-5 *
;************
list p=16f628a
#include p16f628a.inc
variable env
env = _BOREN_OFF
env &= _CP_OFF
env &= DATA_CP_OFF
env &= _PWRTE_OFF
env &= _WDT_OFF
env &= _LVP_OFF
env &= _MCLRE_OFF
env &= _INTOSC_OSC_NOCLKOUT
__config env
#define time D'3'
cblock 0x20
counter
wa0,wa1,wa2
endc
org 0x0000
goto start
org 0x0008
start
banksel TRISB
clrf TRISB
banksel PORTB
main
clrf counter
loop
movf counter,0
call getpat
movwf PORTB ; 出力は一箇所
call wait
incf counter,1
movlw enddata-startdata
subwf counter,0
btfss STATUS,Z
goto loop
goto main
getpat
addwf PCL,1
startdata
retlw b'11111011' ; 0. このパターンは配線によって変わります
retlw b'10000010' ; 1
retlw b'11011101' ; 2.
retlw b'11001110' ; 3
retlw b'10100111' ; 4.
retlw b'01101110' ; 5
retlw b'01111111' ; 6.
retlw b'11100010' ; 7
retlw b'11111111' ; 8.
retlw b'11101110' ; 9
retlw b'11110111' ; A.
retlw b'00111110' ; b
retlw b'01111001' ; C.
retlw b'10011110' ; d
retlw b'01111101' ; E.
retlw b'01110100' ; F
enddata
wait
movlw time
movwf wa0
wait0
clrf wa1
wait1
clrf wa2
wait2
nop
decfsz wa2,1
goto wait2
decfsz wa1,1
goto wait1
decfsz wa0,1
goto wait0
return
end
演習4-5 のプログラムと 演習4-4 のプログラムを組み合わせます。 counter という変数を用意し、次のサブルーチンを用意します。
このような準備をした後、次のプログラムを作ります。
プログラムは次のようになります
;************
;* 演習4-6 *
;************
list p=16f628a
#include p16f628a.inc
variable env
env = _BOREN_OFF
env &= _CP_OFF
env &= DATA_CP_OFF
env &= _PWRTE_OFF
env &= _WDT_OFF
env &= _LVP_OFF
env &= _MCLRE_OFF
env &= _INTOSC_OSC_NOCLKOUT
__config env
cblock 0x20
prev
counter
endc
org 0x0000
goto start
org 0x0008
start
movlw 0x07
movwf CMCON
banksel TRISA
movlw b'0010000'
movwf TRISA
clrf TRISB
banksel PORTA
clrf PORTA
clrf prev
clrf counter
call dispcount
main
btfsc PORTA,5
goto swon
swoff
clrf prev
goto main
swon
movf prev,1
btfss STATUS,Z
goto main
movlw d'1'
movwf prev
call inccount
goto main
inccount
incf counter,1
movlw enddata-startdata
subwf counter,0
btfsc STATUS,Z
clrf counter
dispcount
movf counter,0
call getpat
movwf PORTB
return
getpat
addwf PCL,1
startdata
retlw b'11111011' ; 0. このパターンは配線によって変わります
retlw b'10000010' ; 1
retlw b'11011101' ; 2.
retlw b'11001110' ; 3
retlw b'10100111' ; 4.
retlw b'01101110' ; 5
retlw b'01111111' ; 6.
retlw b'11100010' ; 7
retlw b'11111111' ; 8.
retlw b'11101110' ; 9
retlw b'11110111' ; A.
retlw b'00111110' ; b
retlw b'01111001' ; C.
retlw b'10011110' ; d
retlw b'01111101' ; E.
retlw b'01110100' ; F
enddata
end
プログラムの初期化の部分は全て同じなので、 ファイルに書き込んでおくと、プログラムから #include ディレクティヴで呼び 出すことで初期化が出来るようになります。 書き込む部分は、具体的には毎回同じである下記の部分です。
list p=16f628a
#include p16f628a.inc
variable env
env = _BOREN_OFF
env &= _CP_OFF
env &= DATA_CP_OFF
env &= _PWRTE_OFF
env &= _WDT_OFF
env &= _LVP_OFF
env &= _MCLRE_OFF
env &= _INTOSC_OSC_NOCLKOUT
__config env
cblock 0x20
endc
なお、前回はコンパレータも OFF にするように初期化しましたが、 RA0-3 までを出力に使う分にはその初期化は不要なので、このマクロには入れ ていません。
幾つかプログラムを作って来ましたが、各プログラムを書く際に、毎回、共通 部分があることに気付くと思います。 そこで、 macro 機能を使って各共通部分を意味のある部分毎にまとめて行き たいと思います。
課題を解決するため、 プログラムに機能を付け足すことを考えます。 基本的にはその機能は、実際の機能部分と、それの機能を呼び出す前にしてお く準備部分が存在します。 つまり、付け足すプログラムは、初期化部分と実際のプログラム部分の二ヶ所 となるパターンが一般的です。 そこで、プログラムに付け足す機能を xxx とする時、マクロとして初期化の 部分を xxx_init とし、実際の機能部分を xxx_prg という二つを用意するこ とにします。
まとめたマクロの定義は初期化のファイルに入れることにします。
但し、 nolist と list ディレクティヴではさみ、アセンブル時にリストに定
義部分が出ないようにします。
(マクロを使用すると、使用した部分が展開されてリストに現れますので問題
ありません)
初期化のファイルの名前を gs2.inc とし、#include "gs2.inc"
と呼び出すことで初期化とマクロ定義をすることにします。
初期化部分で、必要なファイルレジスタの確保には cblock ディレクティブを
使用します。
ファイルレジスタのアドレスは固定したくないので、 cblock を使う際、引
数にファイルレジスタ上の開始番地を指定しないことにします。
開始番地を省略すると、前回の割当の次の番地から割り当てられます。
したがって、最初の初期化の部分でに空のcblock 0x20
を宣言
すれば、各 xxx_init マクロで引数無しの cblock が使え、 0x20 番地以降に
順番に割り当てられます。
PORTB のみ、または PORTA と PORTB をできるだけ出力ポートとして使 う初期化を enable_PB と enable_PAPB として定義します。 PORTA を使う際、コンパレータを無効にする必要があります。
enable_PB macro
banksel TRISB
clrf TRISB
banksel PORTB
clrf PORTB
endm
enable_PAPB macro
movlw 0x07
movwf CMCON
banksel TRISA
movlw b'0010000'
movwf TRISA
clrf TRISB
banksel PORTA
clrf PORTA
clrf PORTB
endm
演習4-4 にある sw を押す度になにかをするマクロを作ります。 呼び出し名を sw とし、呼び出し先を func とすると、次のようになります。
sw_init macro
cblock
sw_prev
endc
clrf sw_prev
endm
sw_prg macro func
sw_main
btfsc PORTA,5
goto sw_on
sw_off
clrf sw_prev
goto sw_main
sw_on
movf sw_prev,1
btfss STATUS,Z
goto sw_main
movlw d'1'
movwf sw_prev
call func
goto sw_main
endm
プログラム中で単純なループにより時間待ちをさせることを ビジーウェイトと呼びます。 これは機械語プログラムでは基本的なテクニックですが、他のプログラムとの 協調が絡むと使えなかったりますので利用には注意が必要です。 呼び出し名を bwait とし、繰り返しのパ ラメータ bwait_time を初期値で与えられるようにします。
bwait_init macro _time
#define bwait_time _time
cblock
bwait_v0,bwait_v1,bwait_v2
endc
endm
bwait_prg macro
bwait
movlw bwait_time
movwf bwait_v0
bwait0
clrf bwait_v1
bwait1
clrf bwait_v2
bwait2
nop
decfsz bwait_v2,1
goto bwait2
decfsz bwait_v1,1
goto bwait1
decfsz bwait_v0,1
goto bwait0
return
endm
カウンタの値の上限値はマクロのパラメータで与えること にします。 なお、表示パターンを与える getpat サブルーチンが必要です。
counter_init macro
cblock
counter
endc
clrf counter
call dispcounter
endm
counter_prg macro limit
inccounter
incf counter,1
movlw limit
subwf counter,0
btfsc STATUS,Z
clrf counter
dispcounter
movf counter,0
call getpat
movwf PORTB
return
endm
パターンは連続したビットパターンと 16 進の値を作りましたので、二つ になります。 なお、後々の利用のため、数字のパターンでの小数点のビットは 0 にしておきます。
getpat_bit_prg macro
getpat
addwf PCL,1
pat_start
retlw b'00000000'
retlw b'00000001'
retlw b'00000011'
retlw b'00000111'
retlw b'00001111'
retlw b'00011111'
retlw b'00111111'
retlw b'01111111'
retlw b'11111111'
pat_end
endm
getpat_num_prg macro
getpat
addwf PCL,1
pat_start
retlw b'11111010' ; 0 このパターンは配線によって変わります
retlw b'10000010' ; 1
retlw b'11011100' ; 2
retlw b'11001110' ; 3
retlw b'10100110' ; 4
retlw b'01101110' ; 5
retlw b'01111110' ; 6
retlw b'11100010' ; 7
retlw b'11111110' ; 8
retlw b'11101110' ; 9
retlw b'11110110' ; A
retlw b'00111110' ; b
retlw b'01111000' ; C
retlw b'10011110' ; d
retlw b'01111100' ; E
retlw b'01110100' ; F
pat_end
endm
ここまでで定義したマクロをgs2.incという名前で
保存します。
そして、プログラムから #include "gs2.inc"
で呼び出すことにし
ます。
今回提示したプログラムのマクロ使用版を示します。
;************
;* 例4-1 *
;************
#include "gs2.inc"
org 0x0000
goto start
org 0x0008
start
enable_PB
main
movlw b'01010101' ; 点灯させるビットパターン
movwf PORTB
goto $
end
;************
;* 例4-2 *
;************
#include "gs2.inc"
org 0x0000
goto start
org 0x0008
start
enable_PB
main
movlw b'01010101'
movwf PORTB
movlw b'00001111'
iorwf PORTB,1
goto $
end
;************
;* 演習4-1 *
;************
#include "gs2.inc"
org 0x0000
goto start
org 0x0008
start
enable_PB
main
movlw b'01010101'
movwf PORTB
movlw b'00001111'
andwf PORTB,1
goto $
end
;************
;* 演習4-2 *
;************
#include "gs2.inc"
org 0x0000
goto start
org 0x0008
start
enable_PB
main
movlw b'01010101'
movwf PORTB
movlw b'00001111'
xorwf PORTB,1
goto $
end
;************
;* 演習4-3 *
;************
#include "gs2.inc"
cblock 0x20
onpattern
offpattern
endc
bitpattern equ b'00011111'
org 0x0000
goto start
org 0x0008
start
enable_PAPB
movlw bitpattern
movwf onpattern
xorlw b'11111111'
movwf offpattern
main
movf offpattern,0
btfsc PORTA,5
movf onpattern,0
movwf PORTB
goto main
end
;************
;* 演習4-4 *
;************
#include "gs2.inc"
bitpattern equ b'00011111'
org 0x0000
goto start
org 0x0008
start
enable_PAPB
movlw bitpattern
movwf PORTB
sw_init
sw_prg reverse
reverse
movlw b'11111111'
xorwf PORTB,1
return
end
;************
;* 例4-3 *
;************
#include "gs2.inc"
org 0x0000
goto start
org 0x0008
start
enable_PB
bwait_init d'3'
main
movlw b'00000000'
movwf PORTB
call bwait
movlw b'00000001'
movwf PORTB
call bwait
movlw b'00000011'
movwf PORTB
call bwait
movlw b'00000111'
movwf PORTB
call bwait
movlw b'00001111'
movwf PORTB
call bwait
movlw b'00011111'
movwf PORTB
call bwait
movlw b'00111111'
movwf PORTB
call bwait
movlw b'01111111'
movwf PORTB
call bwait
movlw b'11111111'
movwf PORTB
call bwait
goto main
bwait_prg
end
;**************
;* 例4-3 2 *
;**************
#include "gs2.inc"
display macro pattern
movlw pattern
movwf PORTB
call bwait
endm
org 0x0000
goto start
org 0x0008
start
enable_PB
bwait_init d'3'
main
display b'00000000'
display b'00000001'
display b'00000011'
display b'00000111'
display b'00001111'
display b'00011111'
display b'00111111'
display b'01111111'
display b'11111111'
goto main
bwait_prg
end
;**************
;* 例4-3 3 *
;**************
#include "gs2.inc"
cblock 0x20
counter
pattern
endc
org 0x0000
goto start
org 0x0008
start
enable_PB
bwait_init d'3'
main
clrf pattern
movlw 1
movwf counter
loop
movf counter,0
iorwf pattern,1
movf pattern,0
movwf PORTB ; 出力は一箇所
call bwait
bcf STATUS,C
rlf counter,1
btfss STATUS,C
goto loop
goto main
bwait_prg
end
;**************
;* 例4-3 4 *
;**************
#include "gs2.inc"
org 0x0000
goto start
org 0x0008
start
enable_PB
bwait_init d'3'
counter_init
main
call bwait
call inccounter
goto main
counter_prg pat_end-pat_start
getpat_bit_prg
bwait_prg
end
;************
;* 演習4-5 *
;************
#include "gs2.inc"
org 0x0000
goto start
org 0x0008
start
enable_PB
bwait_init d'3'
counter_init
main
call bwait
call inccounter
goto main
counter_prg pat_end-pat_start
getpat_num_prg
bwait_prg
end
;************
;* 演習4-6 *
;************
#include "gs2.inc"
org 0x0000
goto start
org 0x0008
start
enable_PAPB
counter_init
sw_init
sw_prg inccounter
counter_prg pat_end-pat_start
getpat_num_prg
end