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
© Copyright 2024 Paperzz