■ PICの命令ないか簡単だ! ■
上の表でも見ましたが命令はそんなに多くないので覚えるのも楽ですが少ないのも大変な事もあります。
実際の動きを調べてみましょう。例題は実際にプルグラムを作って実行したように見てみましょう。
1.wレジスタとメモリー、フラグが変化した場合にはピンク色の表示にしました。
2.Z,D,Cはフラグを意味しZ,DC(Dと記載),Cの順番で表示され変化は次のようにします。
「0」に変化は”0”、「1」に変化は”Z,D,C”の立つフラグ、影響しない場合は=”-”、現在状態が不明=”x”
3.RAM(ファイルメモリ)は2種類で「RAM_A」と「RAM_B」を仮に作りました。
「--」は影響されない時に使います。
4.枠内の色について「ピンク色」は変化、影響する可能性のある部分、「灰色」は命令をスキップする場合です。
5.数字の表記は通常16進で記入し01H=01H、0FFH=FFHとします「H」がない場合は10進数扱いです。
|
■ PICの基本(MOV)命令! ■
◆ MOVLW k 動作: k→(w) |
「MOVLW」は「MOV命令」です。「f」のRAMアドレスの内容を「W」へ書き込みます。
この命令はWのみでRAMは指定できません。 |
|
◆基本例題1
W= 1FH |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
W= 100(10進) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
-- |
-- |
-- |
x,x,x |
; |
|
-- |
-- |
-- |
x,x,x |
MOVLW |
1FH |
1FH |
-- |
-- |
-,-,- |
MOVLW |
100 |
64H |
-- |
-- |
-,-,- |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
フラグ |
解 説(「(RAM_A= 25H」の場合) |
; |
|
-- |
-- |
-- |
x,x,x |
初期状態 |
MOVLW |
25H |
25H |
-- |
-- |
0,-,- |
Wの内容と25Hを論理和しWに格納 |
MOVWF |
RAM_A |
25H |
25H |
-- |
0,-,- |
Wの内容をRAM_Aに格納 |
|
◆ MOVF f,d 動作: (f)→(destination) |
「MOVLW」は「MOV命令」です。「K」で指定された値を「W」へ書き込みます。
「d」は格納場所を指定しますが「0(w)」でWに格納し「1(f)」であればRAMに格納します。 |
|
◆基本例題1
W = RAM_A |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
RAM_A = RAM_A |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
-- |
1FH |
-- |
x,x,x |
; |
|
-- |
00 |
-- |
x,x,x |
MOVF |
RAM_A,W |
1FH |
1FH |
-- |
0,-,- |
MOVF |
RAM_A,F |
-- |
00 |
-- |
Z,-,- |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
フラグ |
解 説(「(RAM_A= RAM_B」の場合) |
; |
|
-- |
5AH |
-- |
x,x,x |
初期状態 |
MOVF |
RAM_A,W |
5AH |
5AH |
-- |
0,-,- |
RAM_Aの内容をWに格納 |
MOVWF |
RAM_B |
5AH |
5AH |
5AH |
0,-,- |
Wの内容をRAM_Bに格納 |
|
◆ MOVWF f 動作: (w)→(f) |
「MOVWF」は「MOV命令」です。「W」の内容をfで指定されたアドレス「f」へ書き込みます。
WからRAMへの移動専用です。 |
|
◆基本例題1
RAM_A = W |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
RAM_B = W |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
2AH |
1FH |
-- |
x,x,x |
; |
|
2AH |
-- |
56H |
x,x,x |
MOVWF |
RAM_A,W |
2AH |
2AH |
-- |
-,-,- |
MOVWF |
RAM_B,F |
2AH |
-- |
2AH |
-,-,- |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
フラグ |
解 説(「(RAM_A= RAM_B」の場合) |
; |
|
-- |
5AH |
-- |
x,x,x |
初期状態 |
MOVF |
RAM_A,W |
5AH |
5AH |
-- |
0,-,- |
RAM_Aの内容をWに格納 |
MOVWF |
RAM_B |
5AH |
5AH |
5AH |
0,-,- |
Wの内容をRAM_Bに格納 |
|
◆ CLRF f 動作:00H → (f) |
「CLRF」は「クリア命令」です。「f」のRAMアドレスの内容へ「0」を書き込みます。
この命令はRAMへの指定です、Wは別の命令があります。 |
|
◆基本例題1
RAM_A =00H |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
RAM_B =00H |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
-- |
15H |
-- |
x,x,x |
; |
|
-- |
-- |
15H |
x,x,x |
CLRF |
RAM_A |
-- |
00H |
-- |
Z,-,- |
CLRF |
RAM_B |
-- |
-- |
00H |
Z,-,- |
|
◆ CLRW 動作:00H → W |
「CLRW」は「クリア命令」です。「W」の内容へ「0」を書き込みます。
この命令はWレジスタ専用ですRAMへのは出来ません、RAM用は別の命令があります。 |
|
◆基本例題1
W =00H |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
|
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
15H |
-- |
-- |
x,x,x |
; |
|
-- |
-- |
-- |
x,x,x |
CLRW |
|
00H |
-- |
-- |
Z,-,- |
; |
|
-- |
-- |
-- |
-,-,- |
|
◆ SWAPF f、d 動作:f<0:3> → d<4:7> & f<4:7> → d<0:3> |
「SWAPF」は「スワップ命令」です。fの下4ビットとdの上4ビットとfの上4ビットとdの下4ビットを交換します。
簡単に言うと上位4ビットと下位4ビットを入れ替えするのです。但し「f」と「d」の間で行われます。
フラグが影響しない唯一のMOV命令なのでよく使うとした場合は割り込み処理の時にレジスタ保存と復帰のとき使われます。
「d」は格納場所を指定しますが「0(w)」でWに格納し「1(f)」であればRAMに格納します。 |
|
◆基本例題1
W =SAWPF RAM_A |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
RAM_A =SAWPF RAM_A |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
15H |
68H |
-- |
x,x,x |
; |
|
15H |
68H |
-- |
x,x,x |
SWAPF |
RAM_A、W |
86H |
68H |
-- |
-,-,- |
SWAPF |
RAM_A、F |
15H |
86H |
-- |
-,-,- |
|
■ PICの加減算命令! ■
◆ ADDLW k 動作:(w)+k→(w) |
「ADDLW」は「加算命令」です。Wレジスタの内容と「K」で指定された値を加え「W」へ書き込みます。
この命令はWのみでRAMは指定できません。 |
|
◆基本例題1
35H =10H + 25H |
W |
RAM_A |
RAM_B |
フラグ |
|
◆基本例題2
00H =FFH + 01H |
W |
RAM_A |
RAM_B |
フラグ |
; |
|
10H |
-- |
-- |
x,x,x |
; |
|
01H |
-- |
-- |
x,x,x |
ADDLW |
25H |
35H |
-- |
-- |
0,0,0 |
ADDLW |
0FFH |
00H |
-- |
-- |
Z,D,C |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
フラグ |
解 説(「(RAM_A=RAM_A+25H」の場合) |
; |
|
-- |
3AH |
-- |
|
初期状態 |
MOVF |
RAM_A,W |
3AH |
3AH |
-- |
0,x,x |
RAM_Aの内容をWに格納 |
ADDLW |
25H |
5FH |
3AH |
-- |
0,0,0 |
Wの内容と25Hを加算しWに格納 |
MOVWF |
RAM_A |
5FH |
5FH |
-- |
x,x,x |
Wの内容をRAM_Aに格納 |
|
◆ ADDWF f、d 動作:(w)+(f)→(destination) |
「ADDWF」は「加算命令」です。Wレジスタの内容と「f」のRAMアドレスの内容を加え「d」へ書き込みます。
「d」は格納場所を指定しますが「0(w)」でWに格納し「1(f)」であればRAMに格納します。 |
|
◆基本例題1
35H =10H + 25H(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
35H =10H + 25H(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
10H |
25H |
-- |
x,x,x |
; |
|
10H |
25H |
-- |
x,x,x |
ADDWF |
RAM_A,W |
35H |
25H |
-- |
0,0,0 |
ADDWF |
RAM_A,F |
10H |
35H |
-- |
0,0,0 |
◆基本例題3
10H=08H+08H(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題4
0FH =08H + 07H(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
08H |
08H |
-- |
x,x,x |
; |
|
07H |
08H |
-- |
x,x,x |
ADDWF |
RAM_A,W |
10H |
08H |
-- |
0,D,0 |
ADDWF |
RAM_A,W |
0FH |
08H |
-- |
0,0,0 |
◆基本例題5
8EH =0A5H + 0E9H(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題6
00H =01H + 0FFH(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
A5H |
E9H |
-- |
x,x,x |
; |
|
01H |
FFH |
-- |
x,x,x |
ADDWF |
RAM_A,W |
8EH |
E9H |
-- |
0,0,C |
ADDWF |
RAM_A,W |
00H |
FFH |
-- |
Z,D,C |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(「(RAM_A=RAM_A+RAM_B」の場合) |
; |
|
-- |
25H |
65H |
x,x,x |
初期状態 |
MOVF |
RAM_A,W |
25H |
25H |
65H |
0,-,- |
RAM_Aの内容をwに格納 |
ADDWF |
RAM_B,W |
8AH |
25H |
65H |
0,0,0 |
Wの内容とRAM_Bの内容を加算しWに格納 |
MOVWF |
RAM_A |
8AH |
8AH |
65H |
0,0,0 |
Wの内容をRAM_Aに格納 |
◆応用例題2 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(上記を一工夫、1命令減少) |
; |
|
-- |
25H |
65H |
x,x,x |
初期状態 |
MOVF |
RAM_B,W |
65H |
25H |
65H |
0,-,- |
RAM_Bの内容をWに格納 |
ADDWF |
RAM_A,F |
65H |
8AH |
65H |
0,0,0 |
W(RAM_B)の内容とRAM_Aの内容を加算しRAM_Bに格納 |
|
◆ SUBLW k 動作:k−(w)→(w) ※ADDと違い引く方向がが逆だよ! |
「SUBLW」は「減算命令」です。「K」で指定された値からWレジスタの内容を引いて「W」へ書き込みます。
この命令はWのみでRAMは指定できません。 |
|
◆基本例題1
35H =25H - 10H |
W |
RAM_A |
RAM_B |
フラグ |
|
◆基本例題2
00H =01H - 01H |
W |
RAM_A |
RAM_B |
フラグ |
; |
|
10H |
-- |
-- |
x,x,x |
; |
|
01H |
-- |
-- |
x,x,x |
SUBLW |
25H |
15H |
-- |
-- |
0,D,C |
SUBLW |
01H |
00H |
-- |
-- |
0,0,0 |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
フラグ |
解 説(「(RAM_A = 25H - RAM_A」の場合) |
; |
|
-- |
10H |
-- |
|
初期状態 |
MOVF |
RAM_A,W |
10H |
10H |
-- |
0,x,x |
RAM_Aの内容をWに格納 |
SUBLW |
25H |
15H |
10H |
-- |
0,D,C |
25HとWの内容と引き算しWに格納 |
MOVWF |
RAM_A |
15H |
15H |
-- |
0,D,C |
Wの内容をRAM_Aに格納 |
◆応用例題2 |
W |
RAM_A |
RAM_B |
フラグ |
解 説(「(RAM_A = RAM_A - 25H」の場合)
※引き算のみ引く方向があるためSUBLWが使えない |
; |
|
-- |
3AH |
-- |
|
初期状態 |
MOVLW |
25H |
25H |
3AH |
-- |
0,x,x |
定数の25HをWに格納 |
SUBWF |
RAM_A,F |
25H |
15H |
-- |
0,D,C |
RAM_Aの内容と25H(W)の内容とを引き算しRAM_Aに格納 |
|
◆ SUBWF f、d 動作:(f)−(w)→(destination) ※ADDと違い引く方向がが逆だよ! |
「SUBWF」は「加算命令」です。「f」のRAMアドレスの内容からWレジスタの内容を引いて「d」へ書き込みます。
「d」は格納場所を指定しますが「0(w)」でWに格納し「1(f)」であればRAMに格納します。 |
|
◆基本例題1
15H =25H - 10H(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
15H =25H - 10H(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
10H |
25H |
-- |
x,x,x |
; |
|
10H |
25H |
-- |
x,x,x |
SUBWF |
RAM_A,W |
15H |
25H |
-- |
0,D,C |
SUBWF |
RAM_A,F |
10H |
15H |
-- |
0,D,C |
◆基本例題3
00H=08H - 08H(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題4
0FH =10H - 01H(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
08H |
08H |
-- |
x,x,x |
; |
|
01H |
10H |
-- |
x,x,x |
SUBWF |
RAM_A,W |
00H |
08H |
-- |
Z,D,C |
SUBWF |
RAM_A,W |
0FH |
10H |
-- |
0,D,0 |
◆基本例題5
FFH =00H - 01H(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題6
00H =01H - 01H(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
00H |
01H |
-- |
x,x,x |
; |
|
01H |
01H |
-- |
x,x,x |
SUBWF |
RAM_A,W |
FFH |
01H |
-- |
0,0,0 |
SUBWF |
RAM_A,W |
00H |
01H |
-- |
Z,D,C |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(「(RAM_A=RAM_B - RAM_A」の場合) |
; |
|
-- |
1AH |
65H |
x,x,x |
初期状態 |
MOVF |
RAM_A,W |
25H |
10H |
65H |
0,-,- |
RAM_Aの内容をwに格納 |
SUBWF |
RAM_B,W |
4BH |
10H |
65H |
0,D,C |
RAM_Bの内容とWの内容とを引き算しWに格納 |
MOVWF |
RAM_A |
4BH |
4BH |
65H |
0,D,C |
Wの内容をRAM_Aに格納 |
◆応用例題2 |
W |
RAM_A |
RAM_B |
フラグ |
解 説(「(RAM_A = RAM_A - 25H」の場合)
※引き算のみ引く方向があるためSUBLWが使えない |
; |
|
-- |
3AH |
-- |
|
初期状態 |
MOVLW |
25H |
25H |
3AH |
-- |
0,x,x |
定数の25HをWに格納 |
SUBWF |
RAM_A,F |
25H |
15H |
-- |
0,D,C |
RAM_Aの内容と25H(W)の内容とを引き算しRAM_Aに格納 |
|
◆ INCF f、d 動作:(f) +1 →(destination) |
「INCF」は「1つ加算(Increment)命令」です。「f」のRAMアドレスの内容を1つ加算して「d」へ書き込みます。
「d」は格納場所を指定しますが「0(w)」でWに格納し「1(f)」であればRAMに格納します。
この命令の兄弟で条件機能が付いた「INCFSZ」があります。 |
|
◆基本例題1
16H =15H +01H(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
10H= 0FH +01H(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
0FH |
15H |
-- |
x,x,x |
; |
|
15H |
0FH |
-- |
x,x,x |
INCF |
RAM_A,W |
16H |
15H |
-- |
0,-,- |
INCF |
RAM_A,F |
15H |
10H |
-- |
0,-,- |
◆基本例題3
00H=FFH +01H(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題4
5AH =59H +01H(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
5AH |
FFH |
-- |
x,x,x |
; |
|
01H |
59H |
-- |
x,x,x |
INCF |
RAM_A,f |
5AH |
00H |
-- |
Z,-,- |
INCF |
RAM_A,f |
01H |
5AH |
-- |
0,-,- |
|
◆ DECF f、d 動作:(f) −1 →(destination) |
「DECF」は「1つ減算(Decrement)命令」です。「f」のRAMアドレスの内容を1つ減算して「d」へ書き込みます。
「d」は格納場所を指定しますが「0(w)」でWに格納し「1(f)」であればRAMに格納します。
この命令の兄弟で条件機能が付いた「DECFSZ」があります。 |
|
◆基本例題1
14H =15H -01H(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
0EH= 0FH -01H(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
0FH |
15H |
-- |
x,x,x |
; |
|
15H |
0FH |
-- |
x,x,x |
DECF |
RAM_A,W |
14H |
15H |
-- |
0,-,- |
DECF |
RAM_A,F |
15H |
0EH |
-- |
0,-,- |
◆基本例題3
00H=01H -01H(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題4
5FH =60H -01H(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
5AH |
01H |
-- |
x,x,x |
; |
|
01H |
60H |
-- |
x,x,x |
DECF |
RAM_A,f |
5AH |
00H |
-- |
Z,-,- |
DECF |
RAM_A,f |
01H |
5FH |
-- |
0,-,- |
|
例題:DECFを使った10回ループプログラムです。ループ数は2行目の「10」を変えることでループ数を変えることが出来、ループ数字の後に「H」を付けていないので10進数として扱われます。「10」の場合は16進では0AHで10進で最大255までです。
また「NOP」の行とそれ以降に新たにプルグラムを組むことが出来ます。(現在はタイマープログラムですかね)
例題1:1回目のループの時の動きで実際にはRAM_Aの内容を1つ減算して0になるまで「LOOP」から「GOTO LOOP」まで繰り返す
例題2:最終10回目の時のプログラムの流れです。結果的にゼロ・フラグが立つのでGOTO LOOP文がスキップされます。 |
◆応用例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(10回ループを作る、最初の1回目) |
; |
|
|
xx |
xx |
-- |
x,x,x |
初期状態 |
|
MOVLW |
10 |
0AH |
xx |
-- |
-,-,- |
Wに10(10進数)を設定する |
|
MOVWF |
RAM_A |
0AH |
0AH |
-- |
-,-,- |
Wの内容をRAM_Aに格納 |
LOOP: |
NOP |
|
-- |
0AH |
-- |
-,-,- |
ラベルを「LOOP」とする。NOPは何もせず1サイクル消費 |
|
DECF |
RAM_A,F |
0AH |
09H |
-- |
0,-,- |
RAM_Aの値を−1してRAM_Aへ(1回目は9で0まで繰り返す) |
|
BTFSS |
STATUS,Z |
0AH |
-- |
-- |
-,-,- |
STATUSのZフラグが立っているかチェック(今回はは0) |
|
GOTO |
LOOP |
0AH |
-- |
-- |
-,-,- |
RAM_Aが「0」になるまでLOOPにジャンプ |
◆応用例題2 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(10回ループを作る、最後の1回) |
LOOP: |
NOP |
|
-- |
01H |
-- |
-,-,- |
ラベルを「LOOP」とする。NOPは何もせず1サイクル消費 |
|
DECF |
RAM_A,F |
0AH |
00H |
-- |
Z,-,- |
RAM_Aの値を−1してRAM_Aへ(10回目は0で終了) |
|
BTFSS |
STATUS,Z |
0AH |
-- |
-- |
-,-,- |
STATUSのZフラグが立っているかチェック(今回は1) |
|
GOTO |
LOOP |
-- |
-- |
-- |
-,-,- |
RAM_Aが「0」になったのでこの命令はスキップで次の行へ |
|
■ PICの論理演算命令! ■
◆ ANDLW k 動作:(w) and k→(w) |
「ANDLW」は「AND命令」です。Wレジスタの内容と「K」で指定された値を論理積(AND)して「W」へ書き込みます。
この命令はWのみでRAMは指定できません。 |
|
◆基本例題1
05H =15H and 0FH |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
00H =52H and 01H |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
15H |
-- |
-- |
x,x,x |
; |
|
52H |
-- |
-- |
x,x,x |
ADDLW |
0FH |
05H |
-- |
-- |
0,0,0 |
ADDLW |
01H |
00H |
-- |
-- |
Z,0,0 |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
フラグ |
解 説(「(RAM_A=RAM_A and 25H」の場合) |
; |
|
-- |
3AH |
-- |
x,x,x |
初期状態 |
MOVF |
RAM_A,W |
3AH |
3AH |
-- |
0,-,- |
RAM_Aの内容をWに格納 |
ADDLW |
25H |
20H |
3AH |
-- |
0,0,0 |
Wの内容と25Hを論理積しWに格納 |
MOVWF |
RAM_A |
20H |
20H |
-- |
-,-,- |
Wの内容をRAM_Aに格納 |
|
◆ ANDWF f、d 動作:(w) and (f)→(destination) |
「ANDWF」は「論理積(AND)命令」です。wレジスタの内容と「f」のRAMアドレスの内容を論理積(AND)して「d」へ書き込みます。
「d」は格納場所を指定しますが「0(w)」でWに格納し「1(f)」であればRAMに格納します。 |
|
◆基本例題1
35H=15H and 0FH(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
35H=15H and 0FH(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
15H |
0FH |
-- |
x,x,x |
; |
|
15H |
0FH |
-- |
x,x,x |
ANDWF |
RAM_A,W |
05H |
0FH |
-- |
0,-,- |
ANDWF |
RAM_A,F |
15H |
05H |
-- |
0,-,- |
◆基本例題3
00H=5AH and 01H(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題4
01H=5BH and 01H(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
5AH |
01H |
-- |
x,x,x |
; |
|
5BH |
01H |
-- |
x,x,x |
ANDWF |
RAM_A,W |
00H |
00H |
-- |
Z,0,0 |
ANDWF |
RAM_A,W |
01H |
01H |
-- |
0,-,- |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(「(RAM_A=RAM_A and RAM_B」の場合) |
; |
|
-- |
25H |
0FH |
x,x,x |
初期状態 |
MOVF |
RAM_A,W |
25H |
25H |
0FH |
0,-,- |
RAM_Aの内容をwに格納 |
ANDWF |
RAM_B,W |
05H |
25H |
0FH |
0,-,- |
Wの内容とRAM_Bの内容を論理積しWに格納 |
MOVWF |
RAM_A |
05H |
05H |
0FH |
0,-,- |
Wの内容をRAM_Aに格納 |
◆応用例題2 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(上記「RAM_A=RAM_A and RAM_B」を一工夫、1命令減少) |
; |
|
-- |
25H |
0FH |
x,x,x |
初期状態 |
MOVF |
RAM_B,W |
0FH |
25H |
0FH |
0,-,- |
RAM_Bの内容をWに格納 |
ANDWF |
RAM_A,F |
0FH |
05H |
0FH |
0,-,- |
W(RAM_B)の内容とRAM_Aの内容を論理積しRAM_Bに格納 |
◆応用例題3 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(上記のRAM_Aの値を変えて) |
; |
|
-- |
20H |
0FH |
x,x,x |
初期状態(I/Oポートのマスクに使います) |
MOVF |
RAM_B,W |
0FH |
20H |
0FH |
0,-,- |
RAM_Bの内容をWに格納 |
ANDWF |
RAM_A,F |
0FH |
00H |
0FH |
Z,-,- |
W(RAM_B)とRAM_Aを論理積しRAM_Bへ、結果0の為ゼロフラグ1 |
|
◆ IORLW k 動作:(w) or k→(w) |
「IORLW」は「OR命令」です。Wレジスタの内容と「K」で指定された値を論理和(OR)して「W」へ書き込みます。
この命令はWのみでRAMは指定できません。 |
|
◆基本例題1
1FH=15H or 0FH |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
53H=52H or 01H |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
15H |
-- |
-- |
x,x,x |
; |
|
52H |
-- |
-- |
x,x,x |
IORLW |
0FH |
1FH |
-- |
-- |
0,-,- |
IORLW |
01H |
53H |
-- |
-- |
0,-,- |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
フラグ |
解 説(「(RAM_A=RAM_A+25H」の場合) |
; |
|
-- |
3AH |
-- |
x,x,x |
初期状態 |
MOVF |
RAM_A,W |
3AH |
3AH |
-- |
0,-,- |
RAM_Aの内容をWに格納 |
IORLW |
25H |
3FH |
3AH |
-- |
0,-,- |
Wの内容と25Hを論理和しWに格納 |
MOVWF |
RAM_A |
3FH |
3FH |
-- |
0,-,- |
Wの内容をRAM_Aに格納 |
|
◆ IORWF f、d 動作:(w) or (f)→(destination) |
「IORWF」は「論理w和(OR)命令」です。wレジスタの内容と「f」のRAMアドレスの内容を論理和(OR)して「d」へ書き込みます。
「d」は格納場所を指定しますが「0(w)」でWに格納し「1(f)」であればRAMに格納します。 |
|
◆基本例題1
1FH=15H or 0FH(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
1FH=15H or 0FH(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
15H |
0FH |
-- |
x,x,x |
; |
|
15H |
0FH |
-- |
x,x,x |
IORWF |
RAM_A,W |
1FH |
0FH |
-- |
0,-,- |
IORWF |
RAM_A,F |
15H |
1FH |
-- |
0,-,- |
◆基本例題3
5BH=5AH or 01H(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題4
5FH=5BH or 04H(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
5AH |
01H |
-- |
x,x,x |
; |
|
5BH |
04H |
-- |
x,x,x |
IORWF |
RAM_A,W |
5BH |
00H |
-- |
0,-,- |
IORWF |
RAM_A,W |
5FH |
04H |
-- |
0,-,- |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(「(RAM_A=RAM_A and RAM_B」の場合) |
; |
|
-- |
25H |
0FH |
x,x,x |
初期状態 |
MOVF |
RAM_A,W |
25H |
25H |
0FH |
0,-,- |
RAM_Aの内容をwに格納 |
IORWF |
RAM_B,W |
2FH |
25H |
0FH |
0,-,- |
Wの内容とRAM_Bの内容を加算しWに格納 |
MOVWF |
RAM_A |
2FH |
2FH |
0FH |
-,-,- |
Wの内容をRAM_Aに格納 |
◆応用例題2 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(上記「RAM_A=RAM_A and RAM_B」を一工夫、1命令減少) |
; |
|
-- |
25H |
0FH |
x,x,x |
初期状態 |
MOVF |
RAM_B,W |
0FH |
25H |
0FH |
0,-,- |
RAM_Bの内容をWに格納 |
IORWF |
RAM_A,F |
0FH |
2FH |
0FH |
0,-,- |
W(RAM_B)の内容とRAM_Aの内容を加算しRAM_Bに格納 |
|
◆ XORLW k 動作:(w) xor k→(w) |
「XORLW」は「XOR命令」です。Wレジスタの内容と「K」で指定された値を排他的論理和(XOR)して「W」へ書き込みます。
排他的論理和って!:これはお互いのビットが違う時だけ「1」となり同じ時は「0」となります。
この命令はWのみでRAMは指定できません。 |
|
◆基本例題1
1FH=15H xor 0FH |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
53H=52H xor 01H |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
15H |
-- |
-- |
x,x,x |
; |
|
52H |
-- |
-- |
x,x,x |
XORLW |
0FH |
1AH |
-- |
-- |
0,-,- |
XORLW |
0FFH |
ADH |
-- |
-- |
0,-,- |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
フラグ |
解 説(「(RAM_A=RAM_A xor 25H」の場合) |
; |
|
-- |
3AH |
-- |
x,x,x |
初期状態 |
MOVF |
RAM_A,W |
25H |
3AH |
-- |
0,-,- |
RAM_Aの内容をWに格納 |
XORLW |
25H |
3FH |
3AH |
-- |
0,-,- |
Wの内容と25Hを排他的論理和しWに格納 |
MOVWF |
RAM_A |
3FH |
3FH |
-- |
0,-,- |
Wの内容をRAM_Aに格納 |
|
◆ XORWF f、d 動作:(w) xor (f)→(destination) |
「XORWF」は「排他的論理和(XOR)命令」です。wレジスタの内容と「f」のRAMアドレスの内容を排他的論理和(XOR)して「d」へ書き込みます。
「d」は格納場所を指定しますが「0(w)」でWに格納し「1(f)」であればRAMに格納します。 |
|
◆基本例題1
1AH=15H xor 0FH(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
1AH=15H xor 0FH(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
15H |
0FH |
-- |
x,x,x |
; |
|
15H |
0FH |
-- |
x,x,x |
XORWF |
RAM_A,W |
1AH |
0FH |
-- |
0,-,- |
XORWF |
RAM_A,F |
15H |
1AH |
-- |
0,-,- |
◆基本例題3
00H=FFH xor 0FFH(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題4
5FH=5BH xor 04H(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
FFH |
FFH |
-- |
x,x,x |
; |
|
5BH |
04H |
-- |
x,x,x |
XORWF |
RAM_A,W |
00H |
00H |
-- |
Z,-,- |
XORWF |
RAM_A,W |
5FH |
04H |
-- |
0,-,- |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(「(RAM_A=RAM_A xor RAM_B」の場合) |
; |
|
-- |
25H |
0FH |
x,x,x |
初期状態 |
MOVF |
RAM_A,W |
25H |
25H |
0FH |
0,-,- |
RAM_Aの内容をwに格納 |
XORWF |
RAM_B,W |
2AH |
25H |
0FH |
0,-,- |
Wの内容とRAM_Bの内容を加算しWに格納 |
MOVWF |
RAM_A |
2AH |
2AH |
0FH |
-,-,- |
Wの内容をRAM_Aに格納 |
◆応用例題2 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(上記を一工夫、1命令減少) |
; |
|
-- |
25H |
0FH |
x,x,x |
初期状態 |
MOVF |
RAM_B,W |
0FH |
25H |
0FH |
0,-,- |
RAM_Bの内容をWに格納 |
XORWF |
RAM_A,F |
0FH |
2AH |
0FH |
0,-,- |
W(RAM_B)の内容とRAM_Aの内容を加算しRAM_Bに格納 |
|
◆ COMF f、d 動作: invert (f)→(destination) |
「COMF」は「反転(invert)命令」です。「f」のRAMアドレスの内容を反転(invert)して「d」へ書き込みます。
「d」は格納場所を指定しますが「0(w)」でWに格納し「1(f)」であればRAMに格納します。
反転とはビットが1の時は0になりビットが0の時は1となる。(詳細は下記例題参照) |
|
◆基本例題1
invert 15H→EAH(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
invert 15H→EAH(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
15H |
15H |
-- |
x,x,x |
; |
|
15H |
15H |
-- |
x,x,x |
COMF |
RAM_A,W |
EAH |
15H |
-- |
0,-,- |
COMF |
RAM_A,F |
15H |
EAH |
-- |
0,-,- |
◆基本例題3
invert FFH→EAH(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題4
invert 0FH→F0H(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
5AH |
FFH |
-- |
x,x,x |
; |
|
5BH |
0FH |
-- |
x,x,x |
COMF |
RAM_A,F |
5AH |
00H |
-- |
Z,-,- |
COMF |
RAM_A,F |
5BH |
F0H |
-- |
0,-,- |
|
■ PICのシフト命令! ■
◆ RLF f、b 動作:f<n> → d<n+1>、f<7> → C、C → d<0> |
「RLF」は「左シフト命令」です。キャリを含めて「f」の内容を1ビット上位側にずらし「d」に格納する。ちょうど「RRF」の反対動作
「d」は格納場所を指定しますが「0(w)」でWに格納し「1(f)」であればRAMに格納します。 |
|
◆基本例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2 |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
-- |
01H |
-- |
x,x,0 |
; |
|
-- |
01H |
-- |
x,x,0 |
RLF |
RAM_A,W |
02H |
01H |
-- |
-,-,0 |
RLF |
RAM_A,F |
-- |
02H |
-- |
-,-,0 |
◆基本例題3 |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題4 |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
-- |
01H |
-- |
x,x,C |
; |
|
-- |
81H |
-- |
x,x,C |
RLF |
RAM_A,F |
-- |
03H |
-- |
-,-,0 |
RLF |
RAM_A,F |
-- |
03H |
-- |
-,-,C |
◆基本例題5 |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題6 |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
-- |
80H |
-- |
x,x,0 |
; |
|
-- |
55H |
-- |
x,x,0 |
RLF |
RAM_A,F |
-- |
00H |
-- |
-,-,C |
RLF |
RAM_A,F |
-- |
AAH |
-- |
-,-,0 |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(RAM_Aをキャリ含めずにグッルと2回シフト) |
; |
|
-- |
C5H |
-- |
x,x,0 |
初期状態 |
RLF |
RAM_A,W |
8AH |
C5H |
-- |
-,-,C |
まずはキャリフラグを設定(7ビット→C) |
RLF |
RAM_A,F |
8AH |
8BH |
-- |
-,-,C |
そしてキャリを含めてシフト(7ビット→1ビット目へ) |
RLF |
RAM_A,W |
17H |
8BH |
-- |
-,-,C |
まずはキャリフラグを設定(7ビット→C) |
RLF |
RAM_A,F |
17H |
17H |
-- |
-,-,C |
そのままシフト(C5Hを2回左シフトで17Hです) |
◆応用例題2 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(RAM_Aを8倍) |
; |
|
-- |
03H |
-- |
x,x,C |
初期状態(03H) |
BCF |
STATUS,C |
-- |
03H |
-- |
-,-,0 |
まずはキャリフラグをクリア(上4ビットは立っていないと想定) |
RLF |
RAM_A,F |
-- |
06H |
-- |
-,-,0 |
そしてキャリを含めてシフト(X2倍) |
RLF |
RAM_A,F |
-- |
0CH |
-- |
-,-,C |
そしてキャリを含めてシフト(X4倍) |
RLF |
RAM_A,F |
-- |
18H |
-- |
-,-,C |
そしてキャリを含めてシフト(X8倍)3x8=24(18H) |
|
◆ RRF f、b 動作:f<n> → d<n-1>、f<0> → C、C → d<7> |
「RRF」は「右シフト命令」です。キャリを含めて「f」の内容を1ビット下位側にずらし「d」に格納する。ちょうど「RLF」の反対動作
「d」は格納場所を指定しますが「0(w)」でWに格納し「1(f)」であればRAMに格納します。 |
|
◆基本例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2 |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
-- |
80H |
-- |
x,x,0 |
; |
|
-- |
80H |
-- |
x,x,0 |
RRF |
RAM_A,W |
40H |
80H |
-- |
-,-,0 |
RRF |
RAM_A,F |
-- |
40H |
-- |
-,-,0 |
◆基本例題3 |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題4 |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
-- |
80H |
-- |
x,x,C |
; |
|
-- |
81H |
-- |
x,x,C |
RRF |
RAM_A,F |
-- |
C0H |
-- |
-,-,0 |
RRF |
RAM_A,F |
-- |
C0H |
-- |
-,-,C |
◆基本例題5 |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題6 |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
-- |
01H |
-- |
x,x,0 |
; |
|
-- |
AAH |
-- |
x,x,0 |
RRF |
RAM_A,F |
-- |
00H |
-- |
-,-,C |
RRF |
RAM_A,F |
-- |
55H |
-- |
-,-,0 |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(RAM_Aをキャリ含めずにグッルと2回シフト) |
; |
|
-- |
C5H |
-- |
x,x,0 |
初期状態 |
RRF |
RAM_A,W |
62H |
C5H |
-- |
-,-,C |
まずはキャリフラグを設定(0ビット→C) |
RRF |
RAM_A,F |
62H |
E2H |
-- |
-,-,C |
そしてキャリを含めてシフト(0ビット→7ビット目へ) |
RRF |
RAM_A,W |
F1H |
E2H |
-- |
-,-,0 |
まずはキャリフラグを設定(0ビット→C) |
RRF |
RAM_A,F |
F1H |
71H |
-- |
-,-,0 |
そのままシフト(C5Hを2回右シフトで71Hです) |
|
■ PICのビット命令! ■
◆ BCF f、b 動作:0 →(f <b>) |
「BCF」は「ビットクリア命令」です。fで指定されたRAMアドレスのbビット目をクリアする。BSFの反対動作です。
この命令はPICのRAM内であればどこでも対応できる便利な命令だよ! |
|
◆基本例題1
RAM_A ビット4 クリア |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
RAM_B ビット0 クリア |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
-- |
FF |
-- |
x,x,x |
; |
|
-- |
-- |
05 |
x,x,x |
BCF |
RAM_A,4 |
-- |
EF |
-- |
-,-,- |
BCF |
RAM_B,0 |
-- |
-- |
04 |
-,-,- |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(STATUSのキャリーをクリアしてみましょう) |
; |
|
-- |
3AH |
-- |
x,x,x |
初期状態 |
BCF |
STATUS,C |
25H |
3AH |
-- |
-,-,0 |
キャリーフラグをクリア |
|
◆ BSF f、b 動作:0 →(f <b>) |
「BSF」は「ビットセット命令」です。fで指定されたRAMアドレスのbビット目をセットする。BCFの反対動作です。
この命令はPICのRAM内であればどこでも対応できる便利な命令だよ! |
|
◆基本例題1
RAM_A ビット4 クリア |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
RAM_B ビット0 クリア |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
-- |
EF |
-- |
x,x,x |
; |
|
-- |
-- |
04 |
x,x,x |
BSF |
RAM_A,4 |
-- |
FF |
-- |
-,-,- |
BSF |
RAM_B,0 |
-- |
-- |
05 |
-,-,- |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(STATUSのキャリーをセットしてみましょう) |
; |
|
-- |
3AH |
-- |
x,x,x |
初期状態 |
BCF |
STATUS,C |
25H |
3AH |
-- |
-,-,C |
キャリーフラグをセット |
|
■ PICの条件・無条件分岐命令! ■
◆ BTFSC f、b 動作:skip if(f <b>)=0 |
「BTFSC」は「条件ジャンプ命令」です。fで指定されたRAMアドレスのbビット目が「1」であれば次の命令を実行する。
また「0」の時は次の次の命令を実行する。(つまり「0」の時は次の命令をスキップするという事です)
この命令はPICのRAM内であればどこでも対応でき、しかも唯一の条件命令だよ! |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(実際のキャリフラグで分岐を見てみましょう) |
; |
|
-- |
01H |
-- |
x,x,C |
初期状態(キャリーフラグが「1」となっていると想定) |
BTFSC |
STATUS,C |
-- |
01H |
-- |
-,-,- |
キャリーフラグを調べて「1」なので次の命令を実行 |
GOTO |
LOOP |
-- |
01H |
-- |
-,-,- |
「LOOP」へジャンプする。 |
CLRF |
RAM_A |
-- |
-- |
-- |
-,-,- |
RAM_Aを0クリアする。(今回は上でジャンプ下ので動作せず) |
|
◆応用例題2 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(実際のキャリフラグで分岐を見てみましょう) |
; |
|
-- |
01H |
-- |
x,x,0 |
初期状態(キャリーフラグが「0」となっていると想定) |
BTFSC |
STATUS,C |
-- |
01H |
-- |
-,-,- |
キャリーフラグを調べて「0」なので次の命令をスキップ |
GOTO |
LOOP |
-- |
01H |
-- |
-,-,- |
「LOOP」へジャンプする。(今回はこの命令はスキップする) |
CLRF |
RAM_A |
-- |
00H |
-- |
-,-,- |
RAM_Aを0クリアする。 |
|
◆ BTFSS f、b 動作:skip if(f <b>)=1 |
「BTFSS」は「条件ジャンプ命令」です。fで指定されたRAMアドレスのbビット目が「0」であれば次の命令を実行する。
また「1」の時は次の次の命令を実行する。(つまり「1」の時は次の命令をスキップするという事です)
この命令はPICのRAM内であればどこでも対応でき、しかも唯一の条件命令だよ! |
|
◆応用例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(実際のゼロフラグで分岐を見てみましょう) |
; |
|
-- |
01H |
-- |
Z,x,x |
初期状態(ゼロフラグが「1」となっていると想定) |
BTFSS |
STATUS,Z |
-- |
01H |
-- |
Z,-,- |
ゼロフラグを調べて「1」なので次の命令をスキップ |
GOTO |
LOOP |
-- |
-- |
-- |
-,-,- |
「LOOP」へジャンプする。(今回はこの命令はスキップする) |
CLRF |
RAM_A |
-- |
00H |
-- |
Z,-,- |
RAM_Aを0クリアする。 |
|
◆応用例題2 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(実際のゼロフラグで分岐を見てみましょう) |
; |
|
-- |
01H |
-- |
0,x,x |
初期状態(ゼロフラグが「0」となっていると想定) |
BTFSS |
STATUS,Z |
-- |
01H |
-- |
0,-,- |
ゼロフラグを調べて「0」なので次の命令を実行 |
GOTO |
LOOP |
-- |
01H |
-- |
0,-,- |
「LOOP」へジャンプする。 |
CLRF |
RAM_A |
-- |
-- |
-- |
-,-,- |
RAM_Aを0クリアする。(今回は上でジャンプ下ので動作せず) |
|
◆ INCFSZ f、d 動作:(f) +1 →(destination) + skip if (f)=0 |
「DECF」は「1つ減算(Decrement)命令」です。「f」のRAMアドレスの内容を1つ減算して「d」へ書き込みます。
その結果減算した値が「0」になった時のみ次の命令をスキップする。それ以外はスキップしない。そのため値が「0」になるまで繰り返すようなプログラムにはちょうど良い命令です。(上記「DECF」に「BTFSC STATUS、Z」がドッキングした命令だよ
「d」は格納場所を指定しますが「0(w)」でWに格納し「1(f)」であればRAMに格納します。 |
|
◆基本例題1
16H=15H +1(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
10H=0FH +1(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
0FH |
15H |
-- |
x,x,x |
; |
|
15H |
0FH |
-- |
x,x,x |
INCFSZ |
RAM_A,W |
16H |
15H |
-- |
-,-,- |
INCFSZ |
RAM_A,F |
15H |
10H |
-- |
-,-,- |
GOTO |
LOOP |
16H |
15H |
-- |
-,-,- |
GOTO |
LOOP |
15H |
10H |
-- |
-,-,- |
◆基本例題3
00H=FFH +01H(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題4
60H =5FH +01H(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
5AH |
FFH |
-- |
x,x,x |
; |
|
01H |
5FH |
-- |
x,x,x |
INCFSZ |
RAM_A,F |
5AH |
00H |
-- |
-,-,- |
INCFSZ |
RAM_A,F |
01H |
60H |
-- |
-,-,- |
GOTO |
LOOP |
-- |
-- |
-- |
-,-,- |
GOTO |
LOOP |
01H |
60H |
-- |
-,-,- |
|
◆ DECFSZ f、d 動作:(f) −1 →(destination) + skip if (f)=0 |
「DECF」は「1つ減算(Decrement)命令」です。「f」のRAMアドレスの内容を1つ減算して「d」へ書き込みます。
その結果減算した値が「0」になった時のみ次の命令をスキップする。それ以外はスキップしない。そのため値が「0」になるまで繰り返すようなプログラムにはちょうど良い命令です。(上記「DECF」に「BTFSC STATUS、Z」がドッキングした命令だよ
「d」は格納場所を指定しますが「0(w)」でWに格納し「1(f)」であればRAMに格納します。 |
|
◆基本例題1
15H -1=14H(Wの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題2
0FH -1=0EH(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
0FH |
15H |
-- |
x,x,x |
; |
|
15H |
0FH |
-- |
x,x,x |
DECFSZ |
RAM_A,W |
14H |
15H |
-- |
-,-,- |
DECFSZ |
RAM_A,F |
15H |
0EH |
-- |
-,-,- |
GOTO |
LOOP |
14H |
15H |
-- |
-,-,- |
GOTO |
LOOP |
15H |
0EH |
-- |
-,-,- |
◆基本例題3
00H=01H -01H(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
|
◆基本例題4
5FH =60H -01H(Fの時) |
W |
RAM_A |
RAM_B |
Z,D,C |
; |
|
5AH |
01H |
-- |
x,x,x |
; |
|
01H |
60H |
-- |
x,x,x |
DECFSZ |
RAM_A,F |
5AH |
00H |
-- |
-,-,- |
DECFSZ |
RAM_A,F |
01H |
5FH |
-- |
-,-,- |
GOTO |
LOOP |
-- |
-- |
-- |
-,-,- |
GOTO |
LOOP |
01H |
5FH |
-- |
-,-,- |
|
例題:上のDECFの10回ループに比べて1行少なくなるのでループ・プログラムに最適です。ループ数は2行目の「10」を変えることでループ数を変えることが出来、ループ数字の後に「H」を付けていないので10進数として扱われます。「10」の場合は16進では0AH
また「NOP」の行とそれ以降に新たにプルグラムを組むことが出来ます。(現在はタイマープログラムですかね) |
◆応用例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(10回ループを作る、1回目) |
; |
|
|
xx |
xx |
-- |
x,x,x |
初期状態 |
|
MOVLW |
10 |
0AH |
xx |
-- |
-,-,- |
Wに10(10進数)を設定する |
|
MOVWF |
RAM_A |
0AH |
0AH |
-- |
-,-,- |
Wの内容をRAM_Aに格納 |
LOOP: |
NOP |
|
-- |
0AH |
-- |
-,-,- |
ラベルを「LOOP」とする。NOPは何もせず1サイクル消費 |
|
DECFSZ |
RAM_A,F |
0AH |
09H |
-- |
0,-,- |
RAM_Aの値を−1してRAM_Aへ(1回目は9で0になるまで繰り返す) |
|
GOTO |
LOOP |
0AH |
-- |
-- |
-,-,- |
RAM_Aが「0」になるまでLOOPにジャンプ |
◆応用例題2 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(10回ループを作る、最後の1回) |
LOOP: |
NOP |
|
-- |
01H |
-- |
-,-,- |
ラベルを「LOOP」とする。NOPは何もせず1サイクル消費 |
|
DECFSZ |
RAM_A,F |
0AH |
00H |
-- |
Z,-,- |
RAM_Aの値を−1してRAM_Aへ(10回目は0で終了) |
|
GOTO |
LOOP |
0AH |
-- |
-- |
-,-,- |
RAM_Aが「0」になったのでこの命令はスキップで次の行へ |
|
◆ GOTO k 動作:GOTO k (K=000H〜7FFH) |
「GOTO」は「ジャンプ命令」です。条件がない無条件ジャンプです、プログラムの終了時や「BTFSC、BTFSS、DECFSZ」命令の後にこのGOTO文を使うことで条件ジャンプにも変化します。。
GOTO命令はCALL命令と違いRETURN命令を使って戻ることは出来ないのでジャンプしたら自力で戻るようにプログラムを組んで下さい。GOTO文の多用はプログラムを解りにくくするので最低限に留めましょう。
飛び先番地ですが「K」には範囲があります。000H〜7FFHの範囲であればそのままジャンプ出来ますがそれ以上に飛ばす場合はバンク切り替えをしてからCALL命令を実行しることになるでしょう。ホビーの範囲ではそこまで大きいプログラムはあまり無いと思いますが超えた場合は対策が必要ですので要注意! |
|
◆基本例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(CALLについて) |
; |
|
|
xx |
02H |
-- |
x,x,x |
初期状態 |
|
MOVWF |
RAM_A |
02H |
02H |
-- |
-,-,- |
Wの内容をRAM_Aに格納 |
|
SUBLW |
01H |
01H |
02H |
-- |
-,-,- |
ラベルを「LOOP」とする。NOPは何もせず1サイクル消費 |
|
DECFSZ |
RAM_A,F |
0AH |
02H |
-- |
0,-,- |
RAM_Aの値を−1してRAM_Aへ(1回目は9で0になるまで繰り返す) |
|
CALL |
LEDOUT |
-- |
-- |
-- |
-,-,- |
LEDOUTと言うサブルーチンをコールする |
|
GOTO |
LOOP |
0AH |
-- |
-- |
-,-,- |
RAM_Aが「0」になるまでLOOPにジャンプ |
; |
|
|
-- |
-- |
-- |
-,-,- |
メインプログラムがここに入る。(省略) |
LEDOUT: |
|
|
-- |
-- |
-- |
-,-,- |
呼び出されるサブルーチンのスタート |
; |
|
|
-- |
-- |
-- |
-,-,- |
ここからサブルーチンのプログラムが入る。 |
|
RETURN |
|
-- |
-- |
-- |
-,-,- |
サブルーチンが終了したら元に戻る。(この例では2行目NOPへ) |
|
■ PICのサブルーチン命令! ■
◆ CALL k 動作:CALL k (K=000H〜7FFH) |
「CALL」は「サブルーチン・コール命令」です。同じプログラムを何回も使う時やプログラムを見やすくするためプルグラムを小分けして必要な時に呼び出すための使われます。
GOTO命令と違いCALL命令はサブルーチンを呼び出しスタックポインタに戻り番地を記憶してサブルーチンへジャンプします。その後サブルーチン側の最後で「RETURN」命令を使い先ほどスタックポインタに記憶した戻り番地を読み込み今コールした次の行に戻ると言う特徴があります。但し、CALL命令実行時にスタックポインタに戻り番地を1段使用し「RETURN」で1段戻ると言うしくみになっていますし、その段数は8段(PICにより違う)まで可能です。
PIC16F84ではスタックポインタが8段まで使用可能ですので注意して下さい。これはサブルーチンの中にサブルーチンを呼ぶのに8回まで使えます。ちなみに割り込みを使用せずに9回サブルーチンを重ねて呼び込むと戻り値は解らず動作が保証されませんのであまり段数を増やさないように作りましょう。但し割り込みもこのスタックポインタに戻り番地を収納しますのでここも注意しましょう。
飛び先番地ですが「K」には範囲があります。000H〜7FFHの範囲であればそのままジャンプ出来ますがそれ以上に飛ばす場合はバンク切り替えをしてからCALL命令を実行しることになるでしょう。ホビーの範囲ではそこまで大きいプログラムはあまり無いと思いますが超えた場合は対策が必要ですので要注意!
実際に実行する順番は次のようになるよ!
CALL LEDOUT(1行目) → LEDOUT(4行目) ・・・(5行目)→ RETURN(6行目) → NOP(2行目) と進みます。 |
|
◆基本例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(CALLについて) |
|
CALL |
LEDOUT |
-- |
-- |
-- |
-,-,- |
LEDOUTと言うサブルーチンをコールする(LEDOUTへ) |
|
NOP |
|
-- |
-- |
-- |
-,-,- |
キャリーフラグを調べて「1」なので次の命令をスキップ |
; |
|
|
-- |
-- |
-- |
-,-,- |
メインプログラムがここに入る。(省略) |
LEDOUT: |
|
|
-- |
-- |
-- |
-,-,- |
呼び出されるサブルーチンのスタート |
; |
|
|
-- |
-- |
-- |
-,-,- |
ここからサブルーチンのプログラムが入る。 |
|
RETURN |
|
-- |
-- |
-- |
-,-,- |
サブルーチンが終了したら元に戻る。(この例では2行目NOPへ) |
|
◆ RETURN 動作:RETURN |
「RETURN」は「リターン命令」です。サブルーチンを呼び出されて元の場所へ戻る命令です。「CALL」命令でサブルーチンを呼び出した場合は、サブルーチンの最後は「RETURN」命令で戻るようにして下さい。「GOTO」文で元の場所へ飛ばさないでね!
サブルーチンは戻り番地をスタックポイントに保管し1段減り「RETURN」命令でその記憶を呼び出しスタックポインタが1段戻る仕掛けになっています。16F84では8段のスタックレベルがあります。(PICにより違いがありますので注意してね) |
|
◆ RETFIE 動作:RETFIE |
「RETFIE」は「割り込み用リターン命令」です。CALL命令ではなく割り込みが発生すると現在動作しているアドレスをスタックへ記憶して0004H番地にジャンプします。そのためプログラムの最初に割り込み処理プログラムを入れると良いでしょう。
その割り込み処理が終了して元の場所へ戻る時に「RETFIE」命令を使うとスタックに記憶していたアドレスへ戻ります。その時にINTCONのGIE(グローバル割り込みイネーブル)が割り込み時に自動的に「0」の禁止になっていたのを「1」の許可にします。 |
|
|
|
◆基本例題1 |
W |
STATUS |
W_STAK |
ST_STAK |
解 説(CALLについて) |
|
ORG |
0000H |
-- |
-- |
-- |
-- |
0番地からスタート |
|
GOTO |
MAIN |
-- |
-- |
-- |
-- |
リセット時はメインへジャンプ |
|
ORG |
0004H |
-- |
-- |
-- |
-- |
割り込み用のアドレスをセット(ここより割り込み処理) |
; |
|
仮の値→ |
8FH |
07H |
-- |
-- |
割り込み用のアドレスをセット(ここより割り込み処理) |
|
MOVWF |
W_STAK |
8FH |
07H |
8FH |
-- |
WレジスタをW_STAKに一時待避 |
|
SWAPF |
STATUS,W |
70H |
8FH |
8FH |
-- |
STATUSとWレジスタを交換する(Zフラグを変化させないため) |
|
CLRF |
STATUS |
70H |
00H |
8FH |
-- |
バンク0にする |
|
MOVWF |
ST_STAK |
70H |
00H |
8FH |
70H |
STATUSをST_STAKに一時待避 |
|
MOVFW |
PCLATH,W |
-- |
00H |
8FH |
70H |
PCLATHをST_PCLATHに一時待避 |
|
MOVWF |
ST_PCLATH |
-- |
00H |
8FH |
70H |
同上 |
; |
|
|
-- |
XX |
8FH |
70H |
割り込み処理をここに入れます。 |
|
MOVFW |
ST_PCLATH,W |
-- |
-- |
8FH |
70H |
PCLATHを元に戻す |
|
MOVWF |
PCLATH |
-- |
-- |
8FH |
70H |
同上 |
|
SWAPF |
ST_STATUS,W |
07H |
-- |
8FH |
70H |
t待避時に「SWAPF」を使用したためここも同じ事する |
|
MOVWF |
STATUS |
07H |
07H |
8FH |
70H |
STATUSを元に戻す。(この段階でバンクも戻る) |
|
SWAPF |
W_STAK,F |
07H |
07H |
F8H |
70H |
W(STATUS)とW_STAKを交換する |
|
SWAPF |
W_STAK,W |
8FH |
07H |
F8H |
70H |
もう一度、W(STATUS)とW_STAKを交換する |
|
RETFIE |
|
-- |
-- |
-- |
-- |
最後はこの命令で割り込みから復帰 |
MAIN: |
|
|
-- |
-- |
-- |
-- |
|
; |
|
|
-- |
-- |
-- |
-- |
割り込み設定、初期化、メインプログラムなど |
|
GOTO |
MAIN |
-- |
-- |
-- |
-- |
|
|
◆ RETLW k 動作:RETLW k |
「RETLW」は「リターン定数命令」です。サブルーチンを呼び出されて元の場所へ戻る命令では「RETURN」と同じですがチョット違った使い方が出来ます。実際には例題を見て下さい。簡単に説明するとリターンする時にWレジスタに応じた値を戻り値として返すのでテーブル参照に便利な命令です。 |
|
◆基本例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(CALLについて) |
|
MOVLW |
02H |
02H |
-- |
-- |
-,-,- |
Wに02Hを格納 |
|
CALL |
TABLE |
43H |
-- |
-- |
-,-,- |
TABLEサブルーチンをコール。'C'のアスキーコード43HがWに格納 |
|
NOP |
|
43H |
-- |
-- |
-,-,- |
|
; |
|
|
-- |
-- |
-- |
-,-,- |
メインプログラムがここに入る。(省略) |
|
GOTO |
LOOP |
-- |
-- |
-- |
-,-,- |
|
TABLE: |
ADDWF |
PC |
-- |
-- |
-- |
-,-,- |
サブルーチン開始、goto PC+W |
|
RETLW |
'A' |
-- |
-- |
-- |
-,-,- |
W=0の時に来る。リターンする前にWに'A'を入れてリターンする |
|
RETLW |
'B' |
-- |
-- |
-- |
-,-,- |
W=1の時に来る。リターンする前にWに'B'を入れてリターンする |
|
RETLW |
'C' |
-- |
-- |
-- |
-,-,- |
W=2の時に来る。リターンする前にWに'C'を入れてリターンする |
|
RETLW |
'D' |
-- |
-- |
-- |
-,-,- |
W=3の時に来る。リターンする前にWに'D'を入れてリターンする |
|
RETLW |
'E' |
-- |
-- |
-- |
-,-,- |
W=4の時に来る。リターンする前にWに'E'を入れてリターンする |
|
■ PICのその他の命令! ■
◆ NOP 動作:No operation |
「NOP」は「ノップ命令」です。これは何もしない命令ですが、それならこんな命令はいらないのではと思います。でもこの命令にも便利な機能があり1命令で1サイクルの時間を消費するのでタイマーのプログラムなどに含まれる場合が有ります。 |
|
◆基本例題1 |
W |
RAM_A |
RAM_B |
Z,D,C |
解 説(NOPについて) |
; |
|
25H |
35H |
68H |
0,0,C |
初期値がそれぞれ左の値であるとき |
NOP |
|
25H |
35H |
68H |
0,0,C |
NOPは何もしないのでどれも変化無し、1サイクルのみ消費 |
NOP |
|
25H |
35H |
68H |
0,0,C |
NOPは何もしないのでどれも変化無し、1サイクルのみ消費 |
|
◆ SLEEP 動作:Sleep |
「SLEEP」は「スリープ命令」です。スリープ命令と言うぐらいですからPICがお休みする命令です。この命令を実行するとPIC自体はスリープモードに入り省電力モードとなります。
●スリープモードでは下記の状態になります。
・ウォッチドックタイマがクリアされる
・STATUSレジスタ内のPD=0にTO=1に設定されます。
・オシレータが停止します。(オシレータが動作すると電気が流れ省電力にならないようです)
●スリープからの復帰方法
・MCLRピンからのリセット
・ウォッチドッグタイマが作動
・割り込みがかかった場合(INTピン、ポートBの変化、TMR1割り込み、CCP、SSP、USART、A/D、EEPROMなどの要素がある)
|
|
◆基本例題1 |
W |
TO |
PD |
Z,D,C |
解 説(SLEEPについて) |
; |
|
25H |
-- |
-- |
0,0,C |
初期値がそれぞれ左の値であるとき |
SLEEP |
|
25H |
1 |
0 |
0,0,C |
SLEEPでここでスリープモードにはいる(お休み中) |
NOP |
|
25H |
1 |
0 |
0,0,C |
割り込みなどの原因で復帰する(この行から始まる) |
|
◆ CLRWDT 動作:00H → WDT |
「CLRWDT」は「クリア命令」です。但しウォッチドッグタイマーをクリアする命令です。
PICにはウォッチドックタイマーを内蔵している物があり、その機能を作動させた時ある一定時間以内に、このクリア命令を発効しなければリセットするしくみです。暴走などでの保護用です。
この命令でSTATUSレジスタ内のPDとTOの2種類がセットされます。それぞれの意味は次のようになっています。
・PD →パワーダウン・ビット 1=電源ON後、CLRWDT命令実行後/0=SLEEP命令実行時
・TO →タイムアウト・ビット 1=電源ON後、CLRWDT命令かSLEEP命令実行後/0=WDT タイムアウト発生した場合 |
|
◆基本例題1 |
W |
TO |
PD |
Z,D,C |
解 説(CLRWDTについて) |
; |
|
25H |
-- |
-- |
0,0,C |
初期値がそれぞれ左の値であるとき |
CLRWDT |
|
25H |
1 |
1 |
0,0,C |
ウォッチドッグタイマをクリアする。 |
NOP |
|
25H |
1 |
0 |
0,0,C |
通常の値は何も変化がない |
|
|