1. PIC とは

1. PIC とは
PIC とはその挙動をプログラムできる IC のことである。Peripheral Interface Controller の略でコン
ピュータの周辺機器の接続部分をコントロールするために開発されたマイクロコントローラである。
開発元は Microchip Tecnology Inc. 社で、PIC とは同社の PICmicro(R)マイクロコントローラを指す。
PIC は内部的には小規模なコンピュータで、IC のパッケージ内に演算装置やデータメモリ・プログ
ラムメモリ等が内蔵されている。
本実験では PIC16F84A という PIC を用いる。
PIC16F84A 外観
1
2. アーキテクチャ概要
PIC16F8x ファミリは命令語長 14bit の RISC[1]で命令は35種類である。1命令は4クロックで実行
されるが、実際にはパイプライン処理[2]されている。
ノイマン型コンピュータ[3]と違いプログラムとデータは別々の記憶装置に格納される。(これをハー
バードアーキテクチャという。)
PIC16F84A のプログラムメモリはフラッシュメモリで 1K ワード、データメモリは SRAM で 0x0C 番地
からの 68 バイトを汎用レジスタとして使用することが出来る。データメモリの 0~0x0B 番地まで、
0x80~0x9B 番地までの 24 個のレジスタは特殊機能レジスタと呼ばれプログラムカウンタやフラグ
レジスタなどとして予約されている。
アドレッシングは基本的に即値であるが、間接アドレッシングも可能である。
ALU は加算、減算、ビットごとの包括的・排他的論理和、論理積、左右ローテート等が可能である。
演算はワーキングレジスタ(アキュムレータ)と汎用レジスタとの間で行われ、結果の格納はそのど
ちらかを指定する。ワーキングレジスタはアドレッシング出来ない。
スタックとして 13bit 8段のハードウェアスタックが搭載されているが、サブルーチンコールや割り込
み時の戻り番地を格納することのみに使用される。スタックはアドレッシング出来ない。
I/O ポートは 5bit の PORTA と 8bit の PORTB の二つがあり、ビット(ピン)ごとに入力・出力モード
を設定可能である。両ポートはレジスタであり、特殊機能レジスタに配置されている。
割り込み機能があり、割り込み要因として外部、ポート B 変化、タイマーオーバーフロー、
EEPROM 書き込み終了の4種類がある。割り込みベクタ[4]はどの割り込みでも 0x04 番地で固定
である。
2
PIC16F8x ブロック図
3
3. メモリ構成
3.1 データメモリ構成
以下に PIC16F84A のデータメモリ構成を示す。
PIC16F84A のデータメモリ構成
PIC16F84A のデータメモリは 128 バイトのバンク0とバンク1に分割されている。これは PIC16F84A
のデータメモリアドレスバスが 8 ビットであるためである。バンクを切り替えるとことで、0x7F 番地より
大きなメモリにアクセスすることが出来る。バンクの切り替えは特殊機能レジスタによって行う。
1つのバンクは 128 バイトだが図 1.3.1 を見て解る通り各バンクの 0x50 番地以降は実装されてい
ない。また、バンク1の 0x0C 番地以降はバンク0の 0x0C 番地にマッピングされており、バンク0と
同じ値がリードされる。
4
3.2 特殊機能レジスタ
データメモリの各バンクの最初の12個のレジスタは特殊機能レジスタである。このうち重要なレジ
スタを次に解説する。
3.2.1 STATUS レジスタ
bank0 0x03 番地。演算のフラグレジスタとバンク選択。
bit7
bit0
IRP
RP1
RP0
TO
PD
名称
Z
DC
C
説明
bit7
IRP
bit6
RP1
bit5
RP0
バンク選択ビット 0 = バンク0
1 = バンク1
bit4
TO
タイムアウトビッ
ト
bit3
PD
パワーダウンビッ 1 = 電源 ON 後または CLRWDT 命令による
ト
0 = SLEEP 命令の実行による
bit2
Z
ゼロビット
bit1
DC
デジットキャリー 1 = 結果により下位 4 ビット目からキャリーが発生した
ビット
0 = 結果により下位 4 ビット目からキャリーが発生しなかった
bit0
C
キャリービット
バンク選択ビット 不使用
クリアされているものとする
バンク選択ビット
1 = 電源 ON 後、CLRWT 命令または SLEEP 命令の実行後
0 = WDT タイムアウト発生
1 = 計算またはロジック演算の結果がゼロ
0 = 計算またはロジック演算の結果がゼロでない
1 = 結果により最上位ビットからキャリーが発生した
0 = 結果により最上位ビットからキャリーが発生しなかった
5
3.2.2 OPTION_REG レジスタ
bank1 0x8C 番地。周辺機能の使用不使用、およびユーティリティ。
bit7
bit0
RBPU
INTEDG
T0CS
T0SE
PSA
名称
bit7
bit6
RBPU
PORT B プル
アップイネーブ
ルビット
INTEDG 割り込みエッジ
選択ビット
PB2
PS1
PS0
説明
1 = PORTB プルアップを使用しない
0 = PORTB プルアップを使用する
1 = RB0/INT ピンの立ち上がりエッジにより割り込み
0 = RB0/INT ピンの立ち下がりエッジにより割り込み
bit5
T0CS
TMR0 クロック 1 = RA4/T0CKI ピンの入力
ソース選択ビッ 0 = 内部命令サイクルクロック (CLKOUT)
ト
bit4
T0SE
TMR0 ソースエッ1 = RA4/T0CKI ピンの入力が High から Low でインクリメント
ジ選択ビット
0 = RA4/T0CKI ピンの入力が Low から High でインクリメント
bit3
PSA
プリスケーラ割 1 = プリスケーラは WDT へ割り当て
り当てビット
0 = プリスケーラは TMR0 へ割り当て
bit2
PB2
bit1
PS1
bit0
PS0
プリスケーラレー 000 = 1:2 / 1:1
ト選択ビット
001 = 1:4 / 1:2
010 = 1:8 / 1:4
011 = 1:16 / 1:8
100 = 1:32 / 1:16
101 = 1:64 / 1:32
110 = 1:128 / 1:64
111 = 1:256 / 1:128
(TMR0 レート/WDT レート)
6
3.2.3 INTCON レジスタ
bak0 0x0B 番地および bank1 0x8B 番地。割り込み許可不許可、および割り込みフラグ。
bit7
bit0
GIE
EEIE
T0IE
INTE
RBIE
名称
bit7
GIE
bit6
EEIE
bit5
T0IE
bit4
INTE
bit3
RBIE
bit2
T0IF
bit1
INTF
bit0
RBIF
グローバル割
り込みイネー
ブルビット
EE ライト完了
割り込みイネー
ブルビット
T0IF
INTF
RBIF
説明
1 = すべてのマスクされていない割り込み発生を許可する
0 = 全ての割り込み発生を禁止する
1 = EE ライト完了割り込み発生を許可する
0 = EE ライト完了割り込み発生を禁止する
TMR0 オーバー1 = TMR0 割り込み発生を許可する
フロー割り込 0 = TMR0 割り込み発生を禁止する
みイネーブル
ビット
RB0/INT 割り 1 = RB0/INT 割り込み発生を許可する
込みイネーブ 0 = RB0/INT 割り込み発生を禁止する
ルビット
RB ポート変化 1 = RB ポート変化割り込み発生を許可する
割り込みイネー 0 = RB ポート変化割り込み発生を禁止する
ブルビット
TMR0 オーバー1 = TMR0 がオーバーフローした(ソフトウェアでクリア要)
フロー割り込 0 = TMR0 がオーバーフローしていない
みフラグビット
RB0/INT 割り
込みフラグビッ
ト
RB ポート変化
割り込みフラグ
ビット
1 = RB0/INT 割り込みが発生した(ソフトウェアでクリア要)
0 = RB0/INT 割り込みが発生していない
1 = 少なくとも 1 つ以上の RB7:RB4 ピンの状態が変化した
(ソフトウェアでクリア要)
0 = 状態が変化した RB7:RB4 ピンはない
7
3.2.4 FSR,INDF レジスタ
間接アドレッシングに使用。
INDF レジスタへのアクセスは、FSR レジスタの値の番地のレジスタへのアクセスとなる。
3.2.4.1 FSR レジスタ
bank0 0x04 番地、および bank1 0x84 番地。
3.2.4.2 INDF レジスタ
bank0 0x00 番地、および bank1 0x80 番地。尚、物理的には存在しない。
8
4. 命令セット
PIC16Cxx ファミリの命令セットの命令は 35 種類で共通である。
4.1 命令セット サマリ
ニーモニック
説明
命令サイクル 影響されるステータス
バイト対応のファイルレジスタ命令
ADDWF
f,d
Add W and f
1
C,DC,Z
ANDWF
f,d
AND W with f
1
Z
CLRF
f
Clear f
1
Z
CLRW
-
Clear W
1
Z
COMF
f,d
Complement f
1
Z
DECF
f,d
Decrement f
1
Z
DECFSZ
f,d
Decrement f, Skip if zero
1(2)
-
INCF
f,d
Increment f
1
Z
INCFSZ
f,d
Increment f, Skip if zero
1(2)
-
IORWF
f,d
Inclusive OR W with f
1
Z
MOVF
f,d
Move f
1
Z
MOVWF
f
Move W to f
1
-
NOP
-
No Operation
1
-
RLF
f,d
Rotate Left f through Carry
1
C
RRF
f,d
Rotate Right f throught Carry
1
C
SUBWF
f,d
Subtract W from f
1
C,DC,Z
SWAPF
f,d
Swap nibbles in f
1
-
XORWF
f,d
Exclusive OR W with f
1
Z
ビット対応のファイルレジスタ命令
BCF
f,b
Bit Clear f
1
-
BSF
f,b
Bit Set f
1
-
BTFSC
f,b
Bit Test f, Skip if Clear
1(2)
-
BTFSS
f,b
Bit Test f, Skip if Set
1
-
9
ニーモニック
説明
命令サイクル 影響されるステータス
リテラルおよびコントロール命令
ADDLW
k
Add literal and W
1
C,DC,Z
ANDLW
k
AND literal with W
1
Z
CALL
k
Call subroutine
2
-
CLRWDT
-
Clear Watchdog Timer
1
~TO,~PD
GOTO
k
Go to address
2
-
IORLW
k
Inclusive OR literal with W
1
Z
MOVLW
k
Move literal to W
1
-
RETFIE
-
Return from interrupt
2
-
RETLW
k
Return with literal in W
2
-
RETURN
-
Return from Subroutine
2
-
SLEEP
-
Go into srandly mode
1
~TO,~PD
SUBLW
k
Subtract W from literal
1
C,DC,Z
XORLW
k
Exclusive OR literal with W
1
Z
・記号の読み方
W
:
ワーキングレジスタ(working registor)
f
:
ファイルレジスタ(file registor)の即値アドレス
d
:
格納先(distination)、0 = W, 1 = f
b
:
桁
k
:
リテラル
10
4.2 命令セット 詳説
ADDLW
Add Literal and W
構文
:
[label]
オペランド
:
0 ≦ k ≦ 255
操作
:
(W) + k → (W)
影響フラグ
:
C, DC, Z
説明
:
W レジスタの内容を 8 ビットのリテラル "k" に加え、この結果を W レジスタに
ライトする。
命令サイクル :
1
ADDWF
Add W and f
ADDLW
構文
:
[label]
オペランド
:
0 ≦ f ≦ 127
k
ADDWF
f,d
d ∈ {0,1}
操作
:
(W) + f → (distination)
影響フラグ
:
C, DC, Z
説明
:
W レジスタの内容をレジスタ "f" に加える。この結果を d=0 であれば W
レジスタに、d=1 であればレジスタ"f" にライトする。
命令サイクル :
1
ANDLW
AND Literal with W
構文
:
[label]
ANDLW
オペランド
:
0 ≦ k ≦ 255
操作
:
(W) AND k → (W)
影響フラグ
:
Z
説明
:
W レジスタの内容と 8 ビットのリテラル "k" の AND を行う。この結果を d=0
であれば W レジスタに、d=1 であればレジスタ "f" にライトする。
命令サイクル :
1
ANDWF
AND W with f
構文
:
[label]
ANDWF
オペランド
:
0 ≦ f ≦
127
k
f,d
d ∈ [0,1]
操作
:
(W) AND f → (distination)
影響フラグ
:
Z
説明
:
W レジスタとレジスタ "f" の AND を行う。この結果を d=0 であれば W レジ
スタに、d=1 であればレジスタ"f" にライトする。
命令サイクル :
1
11
BCF
Bit Clear f
構文
:
[label]
BCF
オペランド
:
0 ≦ f ≦ 127
f,b
0 ≦ b ≦ 7
操作
:
0 → (f<b>)
影響フラグ
:
なし
説明
:
レジスタ "f" のビット "b" をクリアする。
命令サイクル :
1
BSF
Bit Set f
構文
:
[label]
BSF
オペランド
:
0 ≦ f ≦ 127
f,b
0 ≦ b ≦ 7
操作
:
1 → (f<b>)
影響フラグ
:
なし
説明
:
レジスタ "f" のビット "b" がセットする。
命令サイクル :
1
BTFSC
Bit Test, Skip if Clear
構文
:
[label]
BTFSC
オペランド
:
0 ≦ f ≦ 127
f,b
0 ≦ b ≦ 7
操作
:
skip if (f<b>) = 0
影響フラグ
:
なし
説明
:
レジスタ "f" のビット "b" が 1 の場合、次の命令を実行する。ビット "b" が
0 の場合は、次の命令を破棄して、かわりに NOP を実行する。2 サイクル
命令になる。
命令サイクル :
1(2)
BTFSS
Bit Test f, Skip if Set
構文
:
[label]
BTFSS
オペランド
:
0 ≦ f ≦ 127
f,b
0 ≦ b ≦ 7
操作
:
skip if (f<b>) = 1
影響フラグ
:
なし
説明
:
W レジスタ "f" のビット "b" が 0 の場合、次の命令を実行する。"b" が 1
の場合は、次の命令を破棄して、かわりに NOP を実行する。2 サイクル命
令になる。
命令サイクル :
1(2)
12
CALL
Call Subroutine
構文
:
[label ]
CALL
オペランド
:
0 ≦ k ≦ 2047
操作
:
(PC) + 1 → TOS,
k
k → PC<10:0>,
(PCLATH<4:3>) → PC<12:11>
影響フラグ
:
なし
説明
:
サブルーチンをコールする。まず、リターンアドレス (PC+1) をスタック
にプッシュして、11 ビットのリテラルアドレスを PC のビット <10:0> に
ロードする。PC の上位ビットは PCLATH からロードする。CALL は 2
サイクルの命令です。
命令サイクル :
2
CLRF
Clear f
構文
:
[label]
CLRF
オペランド
:
0 ≦ f ≦ 127
操作
:
00h → (f)
f
1 → Z
影響フラグ
:
Z
説明
:
レジスタ "f" の内容をクリアして、Z ビットをセットする。
命令サイクル :
1
CLRW
Clear W
構文
:
[label]
オペランド
:
なし
操作
:
00h → (W)
CLRW
1 → Z
影響フラグ
:
Z
説明
:
W レジスタをクリアして、Z ビットをセットする。
命令サイクル :
1
13
CLRWDT
Clear Watchdog Timer
構文
:
[label]
CLRWDT
オペランド
:
なし
操作
:
00h → WDT
0 → WDT prescaler,
1 → TO
1 → PD
影響フラグ
:
TO, PD
説明
:
CLRWDT 命令は WDT をリセットする。また、WDT のプリスケーラもリ
セットする。ステータス ビット TO および PD をセットする。
命令サイクル :
1
COMF
Complement f
構文
:
[label]
COMF
オペランド
:
0 ≦ f ≦ 127
f,d
d ∈ [0,1]
操作
:
(f) → (destination)
影響フラグ
:
Z
説明
:
レジスタ "f" の内容の補数をとる。この結果を d=0 であれば W レジ
スタに、d=1 であればレジスタ "f" にライトする。
命令サイクル :
1
DECF
Decrement f
構文
:
[label]
DECF
オペランド
:
0 ≦ f ≦ 127
f,d
d ∈ [0,1]
操作
:
(f) - 1 → (destination)
影響フラグ
:
Z
説明
:
レジスタ "f" をデクリメントする。この結果を d=0 であれば W レジスタ
に、d=1 であればレジスタ "f" にライトする。DC に影響しない点に注意。
命令サイクル :
1
14
DECFSZ
Decrement f, Skip if 0
構文
:
[label]
DECFSZ
オペランド
:
0 ≦ f ≦ 127
f,d
d ∈ [0,1]
操作
:
(f) - 1 → (destination);
skip if result = 0
影響フラグ
:
なし
説明
:
レジスタ "f" をデクリメントする。この結果を d=0 であれば W レジスタ
に、d=1 であればレジスタ "f" にライトする。
結果が 1 の場合は、次の命令を実行する。結果が 0 の場合は、次の命令を
破棄、かわりに NOP を実行して、2 サイクル命令になる。
命令サイクル :
1(2)
GOTO
Unconditional Branch
構文
:
[label]
GOTO
オペランド
:
0 ≦ k ≦ 2047
操作
:
k → PC<10:0>
k
PCLATH<4:3> → PC<12:11>
影響フラグ
:
なし
説明
:
GOTO は無条件の分岐命令。11 ビットのリテラルアドレスを PC のビット
<10:0> にロードする。PC の上位ビットへは PCLATH <4:3> をロードする。
GOTO は 2 サイクルの命令である。。
命令サイクル :
2
INCF
Increment f
構文
:
[label]
INCF
オペランド
:
0 ≦ f ≦ 127
f,d
d ∈ [0,1]
操作
:
(f) + 1 → (destination)
影響フラグ
:
Z
説明
:
レジスタ "f" の内容をインクリメントする。この結果を、d=0 であれば W レジス
タに、d=1 であればレジスタ"f" にライトする。C に影響しない点に注意。
命令サイクル :
1
15
INCFSZ
Increment f, Skip if 0
構文
:
[label]
INCFSZ
オペランド
:
0 ≦ f ≦ 127
f,d
d ∈ [0,1]
操作
:
(f) + 1 → (destination),
skip if result = 0
影響フラグ
:
なし
説明
:
レジスタ "f" の内容をインクリメントする。この結果を、d=0 であれば W レジス
タに、d=1 であればレジスタ"f" にライトする。結果が 1 の場合は、次の命令
を実行する。結果が 0 の場合は、次の命令を破棄、かわりに NOP を実行し
て、2 サイクル命令になる。
命令サイクル :
1(2)
IORLW
Inclusive OR Literal with W
構文
:
[label]
IORLW
オペランド
:
0 ≦ k ≦ 255
操作
:
(W) .OR. k → (W)
影響フラグ
:
Z
説明
:
W レジスタの内容と 8 ビットのリテラル 'k' の OR を行う。この結果を W レジ
スタにライトする。
命令サイクル :
1
IORWF
Inclusive OR W with f
構文
:
[label]
オペランド
:
0 ≦ f ≦ 127
k
IORWF
f,d
d ∈ [0,1]
操作
:
(W) .OR. (f) → (destination)
影響フラグ
:
Z
説明
:
W レジスタとレジスタ "f" の OR を行う。この結果を、d=0 であれば W レジス
タに、d=1 であればレジスタ"f" にライトする。
命令サイクル :
1
16
MOVF
Move f
構文
:
[label]
MOVF
オペランド
:
0 ≦ f ≦ 127
f,d
d ∈ [0,1]
操作
:
(f) → (destination)
影響フラグ
:
Z
説明
:
レジスタ "f" の内容を結果格納先"d" に移動する。d=0 であれば結果格納
先は W レジスタである。d=1 であれば結果格納先は同じファイルレジスタ"f"
である。d=1 は、ステータスフラグ Z が影響するので、ファイル レジスタのテ
ストに便利。
命令サイクル :
1
MOVLW
Move Literal to W
構文
:
[label]
オペランド
:
0 ≦ k ≦ 255
操作
:
k → (W)
影響フラグ
:
なし
説明
:
8 ビットのリテラル 'k' を W レジスタにロードする。"xx" は "00" とアセンブル
される。
命令サイクル :
1
MOVWF
Move W to f
MOVLW
k
構文
:
[label]
MOVWF
オペランド
:
0 ≦ f ≦ 127
操作
:
(W) → (f)
影響フラグ
:
なし
説明
:
W レジスタからレジスタ "f" にデータを移動する。
命令サイクル :
1
NOP
No Operation
構文
:
[label]
オペランド
:
なし
操作
:
No operation
影響フラグ
:
なし
説明
:
何も行いません。
命令サイクル :
f
NOP
1
17
RETFIE
Return from Interrupt
構文
:
[label]
オペランド
:
なし
操作
:
TOS → PC,
RETFIE
1 → GIE
影響フラグ
:
なし
説明
:
割り込みからの復帰。スタックをポップして、スタックの最上位 (TOS) を PC
にロードする。GIE ( グローバル割り込みイネーブル) ビットをセットして割り
込みをイネーブルにする(lNTCON<7>)。 2 サイクル命令。
命令サイクル :
2
RETLW
Return with Literal in W
構文
:
[label]
RETLW
オペランド
:
0 ≦ k ≦ 255
操作
:
k → (W);
k
TOS → PC
影響フラグ
:
なし
説明
:
8 ビットのリテラル 'k' を W レジスタにロードして、スタックの最上位 (リターン
アドレス) をプログラムカウンタへロードする。 2 サイクル命令。
命令サイクル :
2
RETURN
Return from Subroutine
構文
:
[label]
オペランド
:
なし
操作
:
TOS → PC
影響フラグ
:
なし
説明
:
サブルーチンからの復帰。スタックをポップして、次にスタックの最上(TOS)
をプログラムカウンタにロードする。 2 サイクルの命令。
命令サイクル :
RETURN
2
18
RLF
Rotate Left f through Carry
構文
:
[label]
RLF
オペランド
:
0 ≦ f ≦ 127
f,d
d ∈ [0,1]
操作
:
See description below
影響フラグ
:
C
説明
:
レジスタ "f" の内容をキャリーフラグを通して 1 ビット左に回転する。この結
果を、d=0 であれば W レジスタに、d=1 であればレジスタ "f" にライトする。
命令サイクル :
1
RRF
Rotate Right f through Carry
構文
:
[label]
RRF
オペランド
:
0 ≦ f ≦ 127
f,d
d ∈ [0,1]
操作
:
See description below
影響フラグ
:
C
説明
:
レジスタ "f" の内容をキャリーフラグを通して 1 ビット右に回転する。この結
果を、d=0 であれば W レジスタに、d=1 であればレジスタ "f" にライトする。
命令サイクル :
1
SLEEP
構文
:
[label]
SLEEP
オペランド
:
なし
操作
:
00h → WDT,
0 → WDT prescaler,
1 → TO,
0 → PD
影響フラグ
:
TO, PD
説明
:
パワーダウンステータスビット(PD)をクリア、タイムアウトステータスビット (TO)
をセット、ウォッチドッグタイマとそのプリスケーラをクリアする。
プロセッサは SLEEP モードに入る。オシレータは停止する。詳細は、14.8
項を参照。
命令サイクル :
1
19
SUBLW
Subtract W from Literal
構文
:
[label]
SUBLW
オペランド
:
0 ≦ k ≦ 255
操作
:
k - (W) → (W)
影響フラグ
:
C, DC, Z
説明
:
8 ビットのリテラル "k" から W レジスタの内容を引く (2 の補数法)。この結果
を W レジスタにライトする。
命令サイクル :
1
SUBWF
Subtract W from f
構文
:
[label]
オペランド
:
0 ≦ f ≦ 127
k
SUBWF
f,d
d ∈ [0,1]
操作
:
(f) - (W) → (destination)
影響フラグ
:
C, DC, Z
説明
:
レジスタ "f" から W レジスタの内容を引く (2 の補数法)。この結果を、d=0
であれば W レジスタに、d=1 であればレジスタ "f" にライトする。
命令サイクル :
1
SWAPF
Swap Nibbles in f
構文
:
[label]
SWAPF
オペランド
:
0 ≦ f ≦ 127
f,d
d ∈ [0,1]
操作
:
(f<3:0>) → (destination<7:4>),
(f<7:4>) → (destination<3:0>)
影響フラグ
:
なし
説明
:
レジスタ "f" の上位ニブルと下位ニブルを入れ替える。この結果を、d=0 で
あれば W レジスタに、d=1 であればレジスタ "f" にライトする。
命令サイクル :
1
XORLW
Exclusive OR Literal with W
構文
:
[label]
オペランド
:
0 ≦ k ≦ 255
操作
:
(W) .XOR. k → (W)
影響フラグ
:
Z
説明
:
W レジスタの内容と 8 ビットのリテラル "k" との XOR をとり、その結果を W
レジスタにライトする。
命令サイクル :
XORLW
k
1
20
XORWF
Exclusive OR W with f
構文
:
[label]
XORWF
オペランド
:
0 ≦ f ≦ 127
f,d
d ∈ [0,1]
操作
:
(W) .XOR. (f) → (destination)
影響フラグ
:
Z
説明
:
W レジスタの内容とレジスタ "f" との XOR をとる。この結果を、d=0 であれ
ば W レジスタに、d=1 であればレジスタ "f" にライトする。
命令サイクル :
1
21
5. I/O ポート
PIC16F84A には 5bit の PORTA と 8bit の PORTB の2つの入出力ポートがある。ここではそれぞ
れの特性および使い方について記述する。
5.1 PORTA
PORTA は 5bit の入出力ポートである。対応するレジスタは bank0 0x05 番地の PORTA レジスタ
である。PORTA レジスタの上位 3bit は 0 としてリードされる。
PORTA は IC の 1 番、2 番、3 番、18 番、17 番ピンにあたる。ピン名称はそれぞれ RA0、RA1、
RA2、RA3、RA4 である。
RA4 はオープンドレイン[5]なので、他の 4 つのピンのように出力に使うことは出来ない。入力は通
常通りに使用できる。
RA4 は TMR0 の外部クロックソース入力として使用できる(後述)。
PORTA を使う前に PORTA の各ピンの入出力設定をする必要がある。入出力設定は bank1 にあ
る TRISA レジスタで操作できる。
TRISA レジスタのビットが1になると対応する PORTA ピンが入力に、0 になると出力となる。
アドレス
bit7
bit6
bit5
bit4
bit3
bit2
bit1
bit0
0x05
-
-
-
RA4
RA3
RA2
RA1
RA0
0x85
-
-
-
TRISA4
TRISA3
TRISA2
TRISA1
TRISA0
リセット時の PORTA レジスタの値は不定、TRISA レジスタの値は'11111'である。故に PORTA を
出力として使う前には初期化する必要がある。
例えば以下のようにする。
bsf
STATUS,RP0
;操作バンクを bank1 に変更
movlw
B'00001'
;
movwf
TRISA
;RA0 以外を入力に
bcf
STATUS,RP0
;操作バンクを元に戻す
clrf
PORTA
;PORTA 初期化
この例では RA0 を入力に、それ以外を出力に設定した。TRISA レジスタが bank1 にあるためバン
ク選択ビット(STATUS<5>)を操作する必要がある。
後は通常のレジスタとしてリード/ライト可能である。
22
5.2 PORTB
PORTB は 8bit の入出力ポートである。対応するレジスタは bank0 0x06 番地の PORTB レジスタで
ある。
PORTA は IC の 6 番~13 番ピンにあたる。ピン名称はそれぞれ RB0、RB1、RB2、RB3、RB4、
RB5、RB6、RB7 である。
RA4~RA7 の 4 つのピンが入力で値が変化すると、PORTB 変化割り込みが発生する。
PORTA と同様に PORTB を使う前には PORTB の各ピンの入出力設定をする必要がある。入出
力設定は bank1 にある TRISB レジスタで操作できる。
TRISA レジスタのビットが1になると対応する PORTA ピンが入力に、0 になると出力となる。
アドレス
bit7
bit6
bit5
bit4
bit3
bit2
bit1
bit0
0x06
RB7
RB6
RB5
RB4
RB3
RB2
RB1
RB0
0x86
TRISB7
TRISB6
TRISB5
TRISB4
TRISB3
TRISB2
TRISB1
TRISB0
リセット時の PORTB レジスタの値は不定、TRISB レジスタの値は'11111111'である。故に PORTB
を出力として使う前には初期化する必要がある。
例えば以下のようにする。
bsf
STATUS,RP0
;操作バンクを bank1 に変更
movlw
B'11110000'
;
movwf
TRISB
;PORTB 上位4ビットを入力に
bcf
STATUS,RP0
;操作バンクを元に戻す
clrf
PORTB
;PORTB 初期化
この例では PORTB の上位 4 ビットを入力に、それ以外を出力に設定した。TRISB レジスタが
bank1 にあるためバンク選択ビット(STATUS<5>)を操作する必要がある。
後は通常のレジスタとしてリード/ライト可能である。
23
6. 割り込み
PIC16F84A には 4 つの割り込み要因がある。外部、PORTB 変化、TMR0 オーバーフロー、
EEPROM 書き込み終了の 4 つがそれである。ここではそれぞれの使い方について記述する。
6.1 割り込みとは
割り込みとは、外部のイベントが起こったときにそれに対応するルーチンを呼び出す仕組みのこと
である。
外部のイベントとは、ここでは RB0/INTE ピンが変化する、PORTB の上位 4 ビットが変化する、
TMR0(タイマー)の値がオーバーフローする、データ EEPROM を書き込み終わる事を指す。
具体的に PIC では割り込みが発生するとプログラムカウンタ[6]に 0x04 という値がロードされる。つ
まり割り込みが発生するとプログラムメモリの 0x04 番地以降の命令が実行される。
戻り番地は割り込みが起こる瞬間に自動的にスタックに積まれる。
割り込みの重要な点は、メインプログラムが割り込み発生の前後で何事も無かったかのように実行
されることである。これはメインプログラムでは割り込みの発生を意識する必要が無いということであ
る。
割り込みイベントが命令の実行中に起こっても、実際に割り込みが起こるのはその命令が終了し
た後である。上図では n 番地の命令が実行中に割り込みが発生したとしている。この場合 n 番地
の命令が実行されその次に割り込みハンドラが実行され、その後に n+1 番地の命令が実行される。
6.2 共通
何らかの割り込みが発生すると、プログラムカウンタに 0x04 がロードされる。従って、プログラムメ
モリの 0x04 番地から割り込みからのリターン命令(retfie)までの命令が割り込みハンドラとなる。
割り込みは 4 種類あるが、割り込みベクタの位置は 0x04 で固定である。割り込みハンドラには以
下の実行内容が必要である。
・割り込み発生の不許可(多重割り込み防止)
・プログラムコンテキストの退避
・(割り込み要因の特定と実行内容の振り分け)
24
・割り込みフラグのクリア
・割り込みサービス
・プログラムコンテキストの復帰
・割り込みからの復帰
割り込み発生の不許可とは、それ以上割り込みが発生しないようにすることである。この命令は割
り込みハンドラの最初、つまり 0x04 番地にある必要がある。
そのためには INTCON レジスタの GIE ビットをクリアする。GIE ビットは割り込みグローバルイネー
ブルビットと呼ばれ、これが 0 なら割り込み発生が可能になり 1 なら割り込みが発生しなくなる。
プログラムコンテキストの退避・復帰とはワーキングレジスタと STATUS レジスタの内容をどこかに
保存することである。割り込みハンドラ内でワーキングレジスタや STATUS レジスタを変化させてし
まうと、メインプログラムの動作に影響が出てしまう。そのため、割り込みハンドラの始めの方でこれ
らをどこかのレジスタへ退避し、割り込みから復帰するときにこれを復帰させることが必要である。
割り込み要因の特定と実行内容の振り分けとは、どの割り込み要因によって割り込みが引き起こさ
れたか INTCON レジスタの下位3ビット(割り込みフラグ)をテストして特定し、割り込み要因に応じ
た処理へ実行を移すことである。
括弧付きになっているのは、プログラムによって割り込み要因が1つに特定されている場合がある
為である。その場合は振り分けの必要は無い。たいていの場合、全ての割り込み要因を使用する
ようなことは無い。
割り込みフラグのクリアとは、INTCON レジスタの下位3ビットの割り込みが起こったことを示すフラ
グを 0 にしておくことである。INTCON レジスタの下位3ビットはそれぞれタイマー割り込み発生フ
ラグ T0IF(INTCON<3>)、外部割込み発生フラグ INTF(INTOCN<1>)、PORTB 変化割り込み発生
フラグ RBIF(INTCON<0>)となっている。
これをクリアしておかないと、割り込みから復帰した直後にまた割り込みハンドラへ飛んでしまう。
割り込みサービスとは、割り込み要因に応じた処理のことである。
割り込みからの復帰とは retfie 命令を実行することである。retfie 命令は割り込み発生を許可して
スタックに積まれいている戻り番地の命令に戻ることである。即ち、INTCON レジスタの GIE ビット
をセットして、プログラムカウンタにスタックの最上位の値(TOS)をロードする。
以上が割り込みハンドラの基本的な流れである。
25
例として、外部割込みが発生するたびに PORTB レジスタをインクリメントするプログラムを次に示
す。
include
“P16F84A.INC“
evac_W
equ
0x0c
;ワーキングレジスタ退避用
evac_STATUS
equ
0x0d
;STATUS レジスタ退避用
goto
start
;割り込みハンドラを飛ばす
org
0x04
;割り込みハンドラ、ここから
bcf
INTCON,GIE
;GIE クリア
movwf
evac_W
;
movf
STATUS,W
;プログラムコンテキスト退避
mvowf
evac_STATUS
;
incf
PORTB
;PORTB インクリメント
movf
evac_STATUS,W
;
movwf
STATUS
;プログラムコンテキスト復帰
movf
evac_W,W
;
retfie
start
lb0
;割り込みから復帰
bsf
STATUS,RP0
;
clrf
TRISB
;PORTB を出力設定に
bcf
STATUS,RP0
;
clrf
PORTB
;PORTB 初期化
bsf
INTCON,INTE
;INTE 割り込み許可
bsf
INTCON,GIE
;GIE セット
goto
lb0
;無限ループ
end
26
6.3 外部割込み(INTE 割り込み)
外部割込みは RB0/INTE ピン(6 番ピン)が変化したときに発生する。この割り込みを許可するには
INTCON レジスタの INTE ビット(INTCON<4>)をセットする。
立上がりエッジ(Low→High)で割り込むか立下りエッジ(Hight→Low)で割り込むかは
OPTION_REG レジスタの INTEDG ビット(OPTION_REG<6>)で設定できる。INTEDG ビットが 1
なら立上がり、0 なら立下りエッジで割り込む。
INTE 割り込みが発生すると INTCON レジスタの INTF ビット(INTCON<1>)がセットされる。INTF
ビットは割り込みハンドラ内でクリアする必要がある。
INTE 割り込みは PIC をスリープ状態から起動することが出来る。
6.4 PORTB 変化割り込み(RBIE 割り込み)
PORTB 割り込みは RB7~RB4 のいづれかのピンが変化すると発生する。名前に反して PORTB
の下位4ビットの変化では発生しない点に注意。この割り込みを許可するには INTCON レジスタ
の RBIE ビット(INTCON<3>)をセットする。
RBIE 割り込みが発生すると、INTCON レジスタの RBIF ビット(INTCON<0>)がセットされる。RBIF
ビットは割り込みハンドラ内でクリアする必要がある。
6.5 TMR0 オーバーフロー割り込み(T0IE 割り込み)
TMR0 オーバーフロー割り込みは TMR0 レジスタ(0x01 番地)がオーバーフローすると発生する。
この割り込みを許可するには INTCON レジスタの T0IE ビット(INTCON<5>)をセットする。
T0IE 割り込みが発生すると、INTCON レジスタの T0IF ビット(INTCON<2>)がセットされる。T0IF
ビットは割り込みハンドラ内でクリアする必要がある。
タイマー0については後述する。
6.6 データ EEPROM 書き込み完了割り込み(EEIE 割り込み)
データ EEPROM の書き込みが完了すると発生する。この割り込みを許可するには INTCON レジ
スタの EEIE ビット(INTCON<6>)をセットする。
この割り込みには対応する割り込みフラグは無い。データ EEPROM の使用法については本書で
は解説しない。PIC16F8x のデータシートを参照されたし。
7. TMR0 モジュール
PIC16F84A には TMR0 モジュールというタイマ/カウンタが搭載されている。ここでは TMR0 モジュー
ルの使い方について記述する。
7.1 概要
TMR0 モジュールは指定したクロックソースでカウントアップするタイマである。クロックソースは
RB4/CLKI のパルス入力か命令サイクルのどちらかを選択できる。
タイマの値は bank0 0x01 番地 TMR0 レジスタに格納されている。
TMR0 がオーバーフローすると割り込みが発生する。これによって一定時間ごとに割り込ませるこ
とが出来る。
27
7.2 TMR0 モジュール使用方法
TMR0 モジュールのクロックソースはデフォルトで RA4/CLKI パルス入力になっている。TMR0 を
命令サイクルによってカウントアップしたい場合は、OPTION_REG レジスタの T0CS ビット
(OPTION_REG<5>)を 0 にする。
プリスケーラを使用するとクロックソースの入力に対するカウントアップの比(これをプリスケーラレー
トと呼ぶ)を変更することが出来る。プリスケーラを使用しない場合、クロックソースの入力ごとにカウ
ントアップする(1:1)。
プリスケーラの割り当ては OPTION_REG の~PSA ビット(OPTION_REG<3>)で行う。~PSA ビットを
クリアすることでプリスケーラは TMR0 モジュールに割り当てられる。ちなみにデフォルトではウォッ
チドッグタイマに割り当てられている。
プリスケーラレートは OPTION_REG の PS2,PS1,PS0 ビット(OPTION_REG<2~0>)の3ビット変更で
きる。つまり、8モードある。詳しくはメモリ構成を見よ。
例えばプリスケーラレートが 1:32 である場合、32 入力ごとに TMR0 レジスタがインクリメントされる。
この場合、32 x 256 = 8192 入力ごとに TMR0 オーバーフロー割り込みが発生する。
この場合は、以下のようにする。
;操作バンクを bank1 に変更
bsf
STATUS,RP0
bcf
OPTION_REG,T0CS;クロックソースを命令サイクルに
bsf
OPTION_REG,PSA ;プリスケーラを使用しない
bsf
OPTION_REG,PS2 ;モード 100
bcf
OPTION_REG,PS1 ;プリスケーラレート 1:32
bcf
OPTION_REG,PS0 ;
bcf
STATUS,RP0
;操作バンクを元に戻す
bsf
INTCON,T0IE
;T0IE 割り込みのみ許可
bsf
INTCON,GIE
;GIE セット
clrf
TMR0
;タイマ初期化、ここからカウント
...
28
参考
[1]RISC
RISC(リスク)とは、Reduced Instruction Set Computer(縮小命令セットコンピュータ)の略で、マイク
ロプロセッサの内部構造の一つである。制御命令の数を減らし、加減算などの単純な処理の組み
合わせによって回路を単純化し演算速度の向上を図ろうとする手法である。
(フリー百科事典『ウィキペディア (Wikipedia) 』http://ja.wikipedia.org/wiki/より)
[2]パイプライン処理
ここで言うパイプラインとは命令パイプラインのこと。PIC16F84A では命令の実行と次の命令の取り
出しを同時に行っている。
[3]ノイマン型コンピュータ
大雑把に言ってプログラムとデータが同じアドレス空間に存在するコンピュータ。殆どのコンピュー
タは、ノイマン型である。
[4]割り込みベクタ
割り込みが発生したときにプログラムカウンタにロードされる値。同様にリセットベクタとは PIC がリ
セットされたときにプログラムカウンタにロードされる値のこと。
[5]オープンドレイン
この場合、FET のドレインが RA4 に直結している。
ゲートが H の時ピンはグランドと結線され、ゲートが L の時ピンは Low となる。
[6]プログラムカウンタ
PIC に限らずコンピュータはプログラムメモリ上にロードされている機械語を、取り出しながら実行し
ている。メモリには言うまでも無くアドレスがある。プログラムカウンタとは現在実行している命令(機
械語)のアドレスを格納しているレジスタである。
命令を一つ実行すると、プログラムカウンタの値を命令語長分だけ増加させて、次の命令のアドレ
スとする。
PIC の命令は固定長なので、プログラムカウンタは1づつインクリメントされる。
29