PIC(Peripheral Interface Controller)は、マイクロチップ社によって開発されたマイクロコントローラー(マイコン)です。
PICマイコンのアーキテクチャはハーバード・アーキテクチャに基づいており、高速実行、プログラミングの容易さ、幅広い入手可能性、他の周辺機器とのインターフェースの容易さ、低コスト、フラッシュ・メモリによる再プログラミングなどにより、非常に人気がありるマイコンです。
PIC16F88は8ビットPICマイクロコントローラ(マイコン)で、主にオートメーションや組み込みアプリケーションで使用されています。
タイマー、AD変換、UART等の周辺モジュールのを搭載しているので、1つの小さなチップで多くの機能を実行できます。
PIC16F88の主な構成
PIC16F88は、高性能RISC CPUを搭載した8ビットPICマイクロコントローラで、PDIP、SSOP、QFNの3種類のパッケージはありますが、実験では18ピンのPDIPを使います。
- 供給電圧は最低4.0V~最高5.5Vです。
- データ・バスのサイズは8ビットの8ビットマイコンです。
- 35個のアセンブリ言語命令しかないため、PICマイコンのプログラミング学習に適しています。
- 命令は14ビット(1ワード)で構成され、分岐命令を除き、すべての命令は1サイクルで完了します。
- 命令を格納するプログラム・メモリの容量は4096ワード(1ワードは14ビット)です。
- 256バイト(256 x 8)のデータを格納するためのEEPROMメモリ(以下データメモリ)を内蔵しています。
- プログラムで使う変数は、368バイト(368 x 8)のRAM(以下ファイルレジスタ)に格納します。
- 内部クロック(最大8MHz)の他に、外部に発振器を接続することにより、最大は20MHzで動作させることができます。
- 汎用入出力(GPIO)ポート、タイマー、A/Dコンバータ、調歩同期シリアル通信(AURT)、キャプチャ/コンペア/PWM(CCPI)、同期シリアルポート等のモジュールを搭載しています。
- 各ピンに流れ込む(シンク)電流と、流れ出る(ソース)電流の最大値は25mAです。
詳細はマイクロチップ社が提供しているPIC16F88Data Sheetを参照してください。
ピン配置
16本あるGPIOピンはPORTA(RA0-RA7の8ピン)とPORTB(RB0-RB7の8ピン)に分けられており、各ピンはデジタル入出力機能の他、外部クロック入力、アナログ入力、UART、SPI、I2C等の通信と共有されています。

ピンNo | 名 称 | 説 明 |
1 | RA2 AN2 CVREF VREFー | RA2:双方向 I/O ポート(ポートAのビット2) AN2:アナログ入力 チャンネル2 CVREF:コンパレータの基準電圧出力 VREFー:A/D変換 基準電圧入力(-) |
2 | RA3 AN3 VREF+ C1OUT | RA3:双方向 I/O ポート(ポートAのビット3) AN3:アナログ入力 チャンネル3 VREF+:A/D変換 基準電圧入力(+) C1OUT:コンパレータ1出力 |
3 | RA4 AN4 T0CKI C2OUT | RA4:双方向 I/O ポート(ポートAのビット4) AN4:アナログ入力 チャンネル4 T0CKI:カウンタクロック入力 C2OUT:コンパレータ2出力 |
4 | RA5 MCLR VPP | RA5:入力 ポート(ポートAのビット5) MCR:マスター・クリア ( リセット ) 入力、通常はHightレベルに接続 VPP:PICライターでプログラムを書込む時の電圧入力 |
5 | VSS | 電源(GNDに接続) |
6 | RB0 INT CCP1 | RB0:双方向 I/O ポート(ポートBのビット0) INT:外部割込み CCP1:キャプチャ入力、コンペア出力、PWM出力 |
7 | RB1 SDI SDA | RB1:双方向 I/O ポート(ポートBのビット1) SDI:SPIデータ入力 SDA:I2Cデータ |
8 | RB2 SDO RX DT | RB2:双方向 I/O ポート(ポートBのビット2) SDO:SPIデータ出力 RX:AUSART 非同期受信 DT:AUSART 同期検出 |
9 | RB3 PGM CCP1 | RB3:双方向 I/O ポート(ポートBのビット3) PGM:PICライターでプログラムを書込む時の低電圧 ICSP™ プログラミングイネーブル CCP1:キャプチャ入力、コンペア出力、PWM出力 |
10 | RB4 SCK SCL | RB4:双方向 I/O ポート(ポートBのビット4) SCK:SPI用同期式シリアル・クロック入出力 SCL:2C 用同期シリアルクロック入力 |
11 | RB5 SS TX CK | RB5:双方向 I/O ポート(ポートBのビット5) SS:スレーブ・モードの SPI のスレーブ選択 TX:AUSART 非同期送信 CK:AUSART同期クロック |
12 | RB6 AN5(4) PGC T1OSO T1CKI | RB6:双方向 I/O ポート(ポートBのビット6) AN5:アナログ入力 チャンネル5 PGC:ICライターでプログラムを書込む時のインサーキットデバッガとプログラミング用クロックピン T1OSO:タイマー1の発振器出力 T1CKI:タイマー1の外部クロック入力 |
13 | RB7 AN6(4) PGD T1OSI | RB7:双方向 I/O ポート(ポートBのビット7) AN6:アナログ入力 チャンネル6 PGD:ICライターでプログラムを書込む時のインサーキットデバッガとICSPプログラミングデータピン T1OS:タイマー1の発振器入力 |
14 | VDD | 電源(+5Vに接続) |
15 | RA6 OSC2 CLKO | RA6:双方向 I/O ポート(ポートAのビット6) OSC2:発振器の水晶出力。水晶発振器モードで水晶振動子または共振子に接続 CLKO:RCモードでは、このピンはOSC1の1/4の周波数を持つCLKO信号を出力し、命令サイクルレートを示す |
16 | RA7 OSC1 CLKI | RA7:双方向 I/O ポート(ポートAのビット7) OSC1:発振器の水晶入力 CLKI:外部クロック入力 |
17 | RA0 AN0 | RA0:双方向 I/O ポート(ポートAのビット0) AN0:アナログ入力 チャンネル0 |
18 | RA1 AN1 | RA1:双方向 I/O ポート(ポートAのビット1) AN1:アナログ入力 チャンネル1 |
PORTBは、すべての入力に対して内部の弱いプルアップをソフトウェアで設定可能です。
構成図
PIC16F88は下図の構成になっており、「CPU」部と「周辺モジュール」部に分けることができます。

CPU部
CPU(Central Processing Unit)部は、プログラムメモリから実行するべき手順を呼び出し、読み出した手順を解釈して実行します。
実行した結果は、ファイルレジスタ(RAM)に保存されます。
プログラムメモリ/プログラムカウンタ/スタック
プログラムメモリ(FLASH ROM)はプログラムを格納するメモリで、命令は14ビット(1ワード)で表現され、PIC16F88では4096(4K)個の命令を保存することができます。
プログラムメモリ(FLASH ROM)への書き込みは、ROMライタを使って行います。

- 先頭のアドレスは0000h番地で最終アドレス0FFFh番地です。(末尾ににhを付けて16進数を表記します。)
- プログラムメモリのアドレスはプログラムカウンタ(PC)で指定され、内容を読み込み(フェッチ)命令が実行されます。
- 電源投入時やMCLRピンによるリセットが発生した場合、プログラムはプログラムメモリの0000h番地に入っている命令を実行します。
- 割込みが発生した場合は、プログラムメモリの0004h番地に入っている命令を実行します。
- プログラムカウンタ(PC)は13ビット長(1FFFh)であるため、最大8192(8K)ワードのプログラムメモリのアドレス指定ができ、PIC16F88より多くのプログラムメモリを持っているPICにも適用できます。
但し、GOTOやCALLなどのジャンプ命令の場合は、命令で指定できるアドレスは最大11ビット(2048=2K)であるため、それ以上のアドレスを指定するため、8Kワードの領域を4ページに分割し、ページを切り替えることで、最大8Kワードのプログラムメモリを利用することができます。
PIC16F88は4Kワードのプログラムメモリを指定しますで、他のレジスタの2ビットを使ってページ0、ページ1の2ページを切り替えます。 - GOTOやCALLなどのジャンプ命令を除き、命令実行後はプログラムカウンタ(PC)が+1され、次のアドレスの命令がフェチされ実行されます。
GOTOやCALLなどのジャンプ命令の場合は、命令で指定されたアドレスがプログラムカウンタ(PC)に設定され、該当するアドレスのプログラムメモリの内容がフェッチされ実行されます。 - スタックは CALL命令を実行してサブルーチンを呼び出し、サブルーチンの処理が終了した後に復帰するアドレスを保持するために使用されます。
8領域が用意されていることから、サブルーチンにネストは8回までとなります。
ALU/Wレジスタ
ALU(Arithmetic Logic Unit) は 8 ビット幅で、加算、減算、シフトと論理演算を行うことができます。
Wレジスタ(Working Register)は ALU の実行に使用される 8 ビットのレジスタで、演算や転送命令を実行するときに、データを一時的に保管しておきます。
ファイルレジスタ
ファイルレジスタは、8ビットのデータを格納する高速なメモリで、「アドレス選択」から出力される9ビットのアドレスバスでアドレスが指定されます。
RAMが使われているため、電源を切ると記憶した内容は消失します。

9ビットのアドレス(00h番地~1FFh番地)で指定されるファイルレジスタは、4つのバンク(Bank0~4)を切り替えることで、最大128X4=512領域を扱うことができます。
バンクの切り替えは「STATUSレジスタ」(03h番地)のRP0とRP1の2ビットで切り替えます。
Bank0の00h番地~1Fh番地,、Bank1の80h番地~9Fh番地、Bank3の100h番地~10Fh番、Bank4の180h番地~18Fh番までの96領域は、SFR(Special Function Registers)と呼ばれる特殊な機能を持ったレジスタに割り当てられています。
残りの領域がGPR(General Purpose Registers)と呼ばれるユーザが使用する汎用レジスタで、PIC16F88はBank0の20h番地~7Fh番地,、Bank1のA0h番地~EFh番地、Bank3の120h番地~16Fh番、Bank4の1A0h番地~1EFh番までの368領域になります。
Bank0~Bank4で同じ名前のSFRについては、若いバンク番号を参照することになり、GPRについてはBank1 ~Bank4の GPR アドレスは、Bank0のアドレスにマップされます。例えば、番地 FFh、17Fh、1FFhは、Bank0番地7Fh にアクセスします。
SFR(特殊機能レジスタ)
SFRは、ファイルレジスタ内には存在せず、周辺モージュールの制御用レジスタの領域になっているため、特殊機能レジスタと呼ばれています。
図中のレジスタの名前は、PICマイコンのデータシートに書かれている名前と同じになっているので、データシートを見ながら設定すれば、すべてのモジュールを制御することができます。
例えば、RA1(ポートAのビット1:18番ピン)の出力をHighに設定する手順(概要)は次のようになります。
- RA1は双方向 I/O ポートですので、出力方向として設定します。
・SFRの85h番地のTRSAレジスタ(ポートAのデータ方向設定レジスタ)のRA1に対応するビットを、出力方向(1)に設定します。 - RA1の出力をHighに設定します。
・SFRの05h番地のポートAレジスタのRA1に対応するビットをHigh(1)に設定します。

SFRの詳細はデータシートを参照してください。
汎用レジスタのアドレス指定方式
アドレスを指定して直接的に汎用レジスタにアクセスする方法(直接アドレッシング)と、間接的にアクセスする方法(間接アドレッシング)があります。
▶️直接アドレッシング
直接アドレッシングは、STATUSレジスタのRP1とRP0の組み合わせでバンクを選択します。
- 選択されたバンクの内容を取り出す場合は、命令のオペランド(7ビット)で汎用レジスタのアドレスを指定し、命令により選択された場所にデータを転送します。
- 選択されたバンクにデータを書き込む場合は、命令のオペランド(7ビット)で指定した汎用レジスタのアドレスに、命令により選択されたデータを書込みます。

▶️間接アドレッシング
間接アドレッシングはSTATUSレジスタのIRPと、FSRレジスタの最上位ビット(ビット7)の組み合わせでバンクを選択します。
- 選択されたバンクの内容を取り出す場合は、FSRレジスタの下位7ビット(0~6)に汎用レジスタのアドレス書込んだ後、00h番地のINDFレジスタを読み取ります。
- 選択されたバンクにデータを書き込む場合は、FSRレジスタの下位7ビット(0~6)に汎用レジスタのアドレス書込んだ後、書き込むデータを00h番地のINDFレジスタに書き込むと汎用レジスタに反映されます。

タイミング発生
タイミング発生では、PIC16F88の動作を進める基準信号と使われる「クロック」と呼ばれる一定の周波数のパルスを生成します。
クロックの生成方法には、水晶発振子やセラミック発振子を外付けする方法と、内臓の発振器を使う方法があります。
パワーアップタイマー
パワーアップタイマーは電源投入時に、電源電圧が安定するまで、通常72msの間PIC16F88をリセットします。
発振起動タイマー
発振起動タイマーは、パワーアップタイマー の遅延時間が終了後、1024 オシレータサイクル(OSC1 入力)の遅延時間を発生します。これにより、水晶発振やセラミック発振が安定するまでリセット状態にしておくために役立ちます。
パワーオンリセット
パワーオンリセットは、電源の入り切り時にリセット信号を制御して、PIC16F88の起動、停止を問題なく行うようにします。
リセットにより、内部の状態が初期化され、プログラムカウンタを0hに設定し、プログラムメモリの最初の命令が実行されます。
ウオッチドッグタイマ(WDT)
ウオッチドッグタイマ(WDT)は、プログラムに暴走を監視し、暴走していた場合はシステムをリセットします。
リセットは設定したタイマのカウントが終了した場合に発生しますので、WDTを起動し、カウントが終了する前にWDTをクリアすることを通常の処理の中で繰返し行います。
WDTはWDTCONレジスタ(105h)のSWDTENビットを使用してWDTの有効化と無効化が可能で、ビットを設定すると有効になり、クリアすると無効になります。
31.25 kHz(32μs)の内部クロックから時間基準を取得し、16ビットの分周期で32から65536で分割(WDTCONレジスタのWDTPS<3:0>)することで、時間基準の範囲を1msから2.097秒に設定できます。
ウオッチドッグタイマをクリアにする場合は、プログラムの中でCLRWDT命令を実行します。
ブラウンアウトリセット
コンピュータが動作中に、突然電源が切れたり低下した時に、リセットします。
周辺モジュール
周辺モジュールは、データバスを介して、PIC16F88に接続されているセンサー等の外部機器をプログラムにより制御するためのモジュールです。
入出力A、B
入出力A、BモジュールはPORTA、PORTBの2つの入出力ピンに接続されているHigh、Low信号を入力、逆にHigh、Low信号を出力できます。
同一のピンに対する、入力、出力の方向や入出力信号をプログラムで制御します。ピンの電圧変化(High、Low)を割り込み機能を使って、プログラムに通知することができます。
タイマ0モジュール
タイマ0モジュールは8ビットのアップカウンタで、FFh から 00h にオーバーフロー(256を超えた)したとき、TMR0 割り込みが発生し、INTCONレジスタ(0Bh)のT0IF(ビット2)が1になります。
割り込みが発生するとプログラムカウンターはハードにより強制的に0004hになり、そこからプログラムが走り始めます。割り込みを発生させるためにはINTCONレジスタ(0Bh)のGIE(ビット7)およびT0IE(ビット5)を1に設定します。
8ビット(256)ではカウントが足りない場合は、入力を8段階(2、4、8、16、32、64、128、256)に分周する分周器が備わっているため、最大256x256=65536を超えたとき、TMR0 割り込みを発生させることができます。
分周器の設定はSFRの81h番地のOPTION_REGレジスタの(ビット0~ビット2)で設定します。
SFRの81h番地のOPTION_REGレジスタのT0CS(ビット5)を0に設定すると、システムクロックでカウントされ、1に設定するとT0CKI(3番ピン)から入力される信号でカウントされます。
内部クロックを使う場合は、クロック周波数の1/4が入力信号になるようになっています。8MHzの内部クロックを使う場合は、カウンタには80MHz/4=2MHzが入力されます。
分周器を使わない場合(256)、タイマ0がオーバーフローする時間は1/2MHz X 256 =128μsecになり、分周器を256に設定した場合、タイマ0がオーバーフローする時間は1/2MHz X 256 X 256 =32768μsec(32.768ms)になります。
タイマ1モジュール
タイマー1モジュールは、2つの8ビットレジスタ(TMR1H(0Fh)とTMR1L(0Eh))で構成される、読み書き可能な16ビットタイマー/カウンターです。
カウンター0000hからFFFFhまでインクリメントし、ロールオーバーが発生した場合、TMR1割り込みは、有効に設定されている場合、オーバーフローが発生した際に生成され、割り込みフラグビットTMR1IFが1になり、TMR1 割り込みが発生します。
この割り込みは、 TMR1 割り込みイネーブルビット TMR1IEをセット/クリアすることにより、有効/無効にできます。
入力信号はT1CONレジスタ(10h)のTMR1CSビット、T1OCENビットで、内部/外部を切り替えることができます。
内部クロックを選択すると、クロック周波数の1/4の周波数の信号が入力され、外部クロックを選択すると、T1CKI(12番ピン)に入力された信号で動作します。
タイマ2モジュール
タイマ2モジュールは8ビットのカウンタレジスタ(TMR2)で、入力信号でカウントアップしますが、8ビットの比較器(PR2)と接続され、常時比較されています。
TMR2が内部クロックの周期で0からカウントをはじめ、PR2に設定された値と等しくなると、割り込み信号が出力され、同時にTMR2が0にクリアされますので、TMR2は0とPR2の間を一定間隔で繰り返されます。
割り込みが有効になっていれば、割り込みが発生しプログラムに通知されますが、他のタイマーと異なり、ハードウェアで繰り返される周期となっているので、設定された後は、プログラムに関係なく常に一定の周期となります。
入力信号は内部クロックに限定されますが、分周器により1/4、1/16に分周することができます。
A/D コンバータ
A/Dコンバータは、アナログ信号をデジタル信号に変換する電子回路です。
連続して変化するアナログ信号を、一定の時間で分割し、分割した個別のアナログ量をビット(0と1)で表現されるディジタル信号に変換します。
個別のアナログ量をディジタル信号に変換することを「量子化」と呼び、ビットの数の組み合わせでアナログ量を近似的に表します。
ビットの数が多いほど、組み合わせの結果を個別のアナログ量に近づけることができます。
例えば、ビットの数が3(3ビット)で表される組み合わせは、「000(0)、001(1)、010(2)、011(3)、100(4)、101(5)、110(6)、111(7)」の8通りです。((x)は10進数で表した場合の値です。)
仮に、0~8Vの電圧を、3ビットで表現した場合、0V、1V、2V、3V、4V、5V、6V、7Vの8個の値しか表すことができませんので、より多くの値を表わすためには、ビットの数を増やす必要があります。
PIC16F88は10ビットのA/Dコンバータを内蔵しており、温度や湿度センサーにアナログ出力をデジタル値として扱う場合に利用します。
アドレス指定同期/非同期通信(AUSART):UART
AUSARTは、英語のAddressable Universal Synchronous Asynchronous Receiver Transmitterの頭文字をとったものです。同期式/非同期式両方の通信が可能な通信機能です。
通信データを同期用のクロックに同期させて送受信する方法が同期式で、クロックを使わずに通信開始のタイミングを合わせて通信する方式が非同期式です。
非同期(UART))は、スタートビットとストップビットで足並みをそろえて通信するため、「調歩同期式」とも呼ばれます。
▶️非同期式通信(UART)
本稿では、通信に非同期式(UART)を使って実験を進めていきます。
UARTは非同期(調歩同期)によるシリアル通信方式で、1バイト単位でデータを送受信します。
信号線は送信用のTXと受信用のRXで、ラズパイPicoWとセンサーなどのデバイスとは1対1で接続します。
UARTの送受信は、送信の開始/終了やアドレスと言った概念がないため、送信側と受信側で開始と終了の合図を決めておき、データを送受信します。
開始と終了の合図を含め、主に次のような通信に必要な規約があります。
規 約 | 説 明 |
スタートビット | データを開始する合図で、通常は1ビットです。 |
データビット | 通常は8ビット(1バイト)でデータを表現します。 |
パリティビット | 受信したデータにエラーが無いかをチェックするビットです。データビットとパリティビットに含まれる『1』の数の合計が偶数の場合は偶数パリティ、奇数の場合は奇数パリティと言います。パリティビットの省略可能です。 |
ストップビット | データを終了する合図で、通常は1ビットです。 |
ボーレート | 1秒間に送信されるデータのビット数を表す単位で、一般的には9600bps、115200bps(bit per second)です。 |

キャプチャ/コンペア/PWM(CCP1)
キャプチャ/コンペア/ PWM(CCP1)モジュールには16 ビットのキャプチャ・レジスタ、16 ビットのコンペア・レジスタまたは PWM マスター/スレーブ・デューティ・サイクル・レジスタとして動作する16 ビットのレジスタがあります
▶️キャプチャ
キャプチャーはパルスの立ち上り/立ち下りエッジを検出して、次の立ち上り/立ち下りエッジまでの間隔(周波数)を測定する機能で、周期的なパルス波形の周波数を測定に利用できます。
▶️コンペア
このコンペアは、タイマ1のカウント値が、あらかじめレジスタに設定した値と同じになったとき、割込みを発生させると同時に、指定されたピンに出力をする機能で、指定した時間幅を持つワンショットのパルスを出力するような場合に使われます。
▶️PWM
一定の周期に中にあるパルス幅を変えることで、負荷に供給する電流を制御します。
一定の周期に中にあるパルスのHigh状態の時間により、電流値は制御され、High状態の時間が長いほど多くの電流が流れることになります。
一定の周期とパルスのHigh状態の時間の比を「デューティ比」と言います。

例えば、パルスではなく、常時Highの時の電流が「5mA」とします。
- 図Aの場合は「5mA X 0.5 = 2.5mA 」の電流が供給されることになります。
- 図Bの場合は「5mA X 0.7 = 3.5mA 」の電流が供給されることになります。
PWM機能は、サーボモーターの制御に使われています。
データメモリ(EEPROM)
データメモリ(EEPROM)は、書込みに10msほどかかるため、通常のプログラムで処理するデータ格納には書込み時間が早い汎用レジスタを使います。
データメモリ(EEPROM)はプログラムメモリ(FLASH ROM)と同様に、電源を切ってもデータが消えないため、重要なデータを格納する目的で使われます。
プログラムメモリ(FLASH ROM)への書き込みは、ROMライタを使って行いますが、データメモリ(EEPROM)への書込みはROMライタは必要ありません。
通常プログラムで使うMOV命令等では、書込みを直接行うことができませんので、SFRにあるEEADRレジスタ(10Dh番地)、EEDATAレジスタ(10Ch番地)、EECON1レジスタ(18Ch番地)、EECON2レジスタ(18Dh番地)を使って行います。
読出しはEEADRレジスタ(10Dh番地)、EEDATAレジスタ(10Ch番地)、EECON1レジスタ(18Ch番地)を使って行います。
アナログコンパレータ(Comparators)
アナログコンパレータには2つアナログ比較器があり、比較する電圧はRA0からRA3に入力される電圧の内の2つを比較する機能と、基準電圧と比較する機能があります。
比較した結果はピンRA3とRA4にHigh、Lowで出力されます。
同期式シリアルポート(SSP):I2C通信
SSP モジュールは、I2C(Inter-Integrated Circuit)または、SPI(Serial Peripheral Interface)のどちらかで動作することができます。
I2C通信は1980年フィリップス社で開発されたシリアル通信方式で、SDAとSCLの2本の信号線により、PIC16F88などのマイコン(マスター)から、複数のデバイス(スレーブ)を制御することができます。
通信の速度は標準モード、ファーストモード、高速モードの3種類のモードがあり、それぞれ、100kbps、400kbs、3.4Mbpsの通信を行うことができます。
通信距離は比較的高いインピーダンスと低い雑音耐性のため、数メートルに制限されています。
▶️接続方法
SDA(シリアルデータ)とSCL(シリアルクロック)は、マスターといわれるデバイスと複数のスレーブといわれるデバイスに接続され、データをSDA信号に乗せ、SCLのタイミングに同期させて送受信を行います。
同じ信号線に接続されたスレーブは、デバイスごとに付与されているアドレスにより識別されるあめ、同じ種類のデバイスを接続する場合は、アドレスが重複する可能性があるので注意が必要です。
SDAとSCLはプルアップする必要があり、抵抗値は電源電圧(VDD)、バスの浮遊容量、接続されたデバイスの数と入力電流から設定します。
電源電圧(VDD)が5V、通信速度が100kbpsまたは400kbpsの場合は、2KΩ~5KΩとなります。

▶️マスターからスレーブへデータを送信
- マスターは、通信を開始するための合図(スタートコンディション)をSCLをHigh、SDAをLowにして送信します。
- マスターは、通信したいスレーブのアドレスと送信(W)コマンドを送信します。
- アドレスと送信(W)コマンドを受信したスレーブの中で、アドレスが一致したスレーブは、準備(スタンバイ)状態になったことを知らせるアクノリッジ(A)をマスターに返信します。(アドレスが一致しないスレーブは待機状態になります。)
- アクノリッジ(A)を受信したマスターは、データをスレーブに送信します。
- スレーブはデータを受信後、再び、アクノリッジ(A)をマスターに返信します。
- 必要に応じて、4.と5.を繰り返します。
- データの送信を終了した時、マスターは通信終了の合図(ストップコンディション)をSCLをHigh、SDAをHighにして送信します。
▶️スレーブからのデータをマスターが受信
- マスターは、通信を開始するための合図(スタートコンディション)をSCLをHigh、SDAをLowにして送信します。
- マスターは、通信したいスレーブのアドレスと受信(R)コマンドを送信します。
- アドレスと受信(R)コマンドを受信したスレーブの中で、アドレスが一致したスレーブは、準備(スタンバイ)状態になったことを知らせるアクノリッジ(A)をマスターに返信します。(アドレスが一致しないスレーブは待機状態になります。)
- アクノリッジ(A)を返信したスレーブは、データをマスターに送信します。
- マスターはデータを受信後、再び、アクノリッジ(A)をスレーブに返信します。
- 必要に応じて、4.と5.を繰り返します。
- データの受信を終了した時、マスターは通信終了の合図(ストップコンディション)をSCLをHigh、SDAをHighにして送信します。
同期式シリアルポート(SSP)SPI通信
SPI通信はモトローラ社が提唱したシリアル通信方式です。
数Mbpsの速度で通信ができるため、PIC16F88の外部に接続された、A/DコンバータやD/Aコンバータとの通信にも使われ、通信距離は一般的には1m程度と言われています。
SCK、SDI、SDOとSSの4本の信号線で、PIC16F88などのマイコン(マスター)から、周辺のデバイス(スレーブ)を制御することができます。
信 号 名 | 説 明 |
シリアルクロック(SCK) | データ転送を同期させるため、ラズパイPicoW(マスター)から、送信されるクロック信号です。 |
シリアルデータ・イン(SDI) | スレーブからマスターへのデータを送信する信号線です。 |
シリアルデータ・アウト(SDO) | マスターからスレーブへのデータを送信する信号線です。 |
スレーブセレクト(SS) | 制御するスレーブを選択するための信号線です。 |
▶️接続方法
SCK、SDI、SDO、SSは、マスターとスレーブに接続され、SS信号によりスレーブを選択し、データをSDI信号またはSDOOに乗せ、SCKのタイミングに同期させて送受信を行います。

▶️マスターからスレーブへデータを送信
- マスターは、データを送信するスレーブのSSを、Lowに設定して選択します。
- マスターは、その後、データを送信するためにSCKを出力します。
- マスターは、SC」に同期して、SDOからデータを出力します。
- スレーブは、SCKに同期して、SDIでデータを受信します。
- マスターは、データ送信を終了したスレーブのSSを、Highに設定して選択を解除します。
▶️スレーブからのデータをマスターが受信
- マスターは、データを受信するスレーブのSSを、Lowに設定して選択します。
- マスターは、その後、データを受信するためにSCKを出力します。
- スレーブは、SCKに同期して、SDOからデータを出力します。
- マスターは、SCKに同期して、SDIでデータを受信します。
- マスターは、データ受信を終了したスレーブSSSを、Highに設定して選択を解除します。
▶️マスターとスレーブが送受信
SPIの通信はデータの送信と受信を同時に行うことができます。
マスターからスレーブにクロックを送信し、クロックに同期して、マスターとスレーブは同時にデータを送受信することができます。
割込み
割込みは、現在実行している処理を停止させ、他の処理に実行を移し処理終了後、停止している処理の次の処理を実行します。

PIC16F88には13種類の割り込みがあります。

それぞの割込みは、SFRのINTCONレジスタ、PIR1レジスタ、PIR2レジスタ、PIE1レジスタ、PIE2レジスタで管理されており、割り込みが発生すると該当する個別の割り込みフラグを「1」に設定します。
RB0/INTピンの割り込み、RBポートの変化割り込み、及びTMRのオーバーフロー割り込みフラグは、SFRのINTCON レジスタにあります。
A/DコンバータやEEPROMなどの周辺割り込みフラグは、SFRの PIR1 およびPIR2 に、対応する割り込み有効ビットは、 PIE1 および PIE2 にあり、周辺割り込み有効ビ ッ トはSFRのINTCON にあります。
グローバル割り込み有効ビットGIE(INTCONのビット7)は、個別に無効にされていないすべての割り込みを、「1」の時に有効、「0」の時に無効にします。
周辺割り込み有効ビットPEIEE(INTCONのビット6)は、個別に無効にされていない周辺の割り込みを、「1」の時に有効、「0」の時に無効にします。
GIEが有効で、INTCONレジスタで設定される割り込みフラグビットと、INTCONで設定される個別の有効ビットが「1」に設定されている場合、割り込みは直ちに発生します。
GIEとPEIEEが有効で、PIR1、PIR2の各レジスタで設定される周辺の割り込みフラグビットと、PIE1、PIE2で設定される個別の有効ビットが「1」に設定されている場合、割り込みは直ちに発生します。
個別の割り込みは、INTCON、PIR1、PIR2の各レジスタの対応する有効ビットを「0」に設定することで、無効にすることができます。
割り込みフラグビットは、それに対応する有効ビットやGIEビットの状態とは関係なくセットされます。
リセットによりGIEは「0」に設定され、割り込みが無効になります。
BSF命令により「1」に設定し割り込みを有効にした後、割り込みが発生すると「0」に設定され、割り込みが無効になります。
割り込み処理終了後に、RETFIE命令を実行すると設定され、割り込みが再び有効になります。
割り込みの種類
No | フラグ/ 有効ビット | 割り込みの発生要因 | SFR |
1 | EEIF / EEIE | データメモリ(EEPROM) への書き込みが終了した | PIR2/ PIE2 |
2 | OSFIF/ OSFIE | システム発振器が故障し、クロック入力がINTRCに切替わった | PIR2/ PIE2 |
3 | ADIF/ ADIE | A/D変換が終了した | PIR1/ PIE1 |
4 | RCIF/ RCIE | AUSART 受信バッファが満杯になった | PIR1/ PIE1 |
5 | TXIF/ TXIE | AUSART 送信バッファが満杯になった | PIR1/ PIE1 |
6 | SSPIF/ SSPIE | 同期シリアルポート(SSP)の送信/受信が終了した (SSPにはSPIとI2Cの二つのモジュールがあります) | PIR1/ PIE1 |
7 | CCP1IF/ CCP1IE | ・キャプチャモード TMR1レジスタのキャプチャ(コピー)が終了した ・コンペアモード TMR1レジスタの比較一致が検出された | PIR1/ PIE1 |
8 | TMR2IF/ TMR2IE | TMR2とPR2の値が一致した | PIR1/ PIE1 |
9 | TMR1IF/ TMR1IE | TMR1レジスタがオーバーフローした | PIR1/ PIE1 |
10 | CMIF/ CMIE | 比較器の出力値が変化した | PIR2/ PIE2 |
11 | TMR0IE/ TMR0IE | TMR0レジスタがオーバーフローした | INTCON |
12 | INT0IF/ INT0IE | RB0/INT 外部割り込みが発生した | INTCON |
13 | RBIF/ RBIE | 少なくとも 1 つ以上の RB4~RB7 ピンの状態が変化した | INTCON |
INTCON レジスタ (アドレス 0Bh, 8Bh, 10Bh, 18Bh)
INTCON レジスタは 、RBポートの変化割り込み、外部 RB0/INT外部割り込み、及びTMR0 レジスタオーバーフロー割り込みのフラグビットと有効ビットが割り当てられているリード/ライト可能なレジスタです。
割り込みフラグビットは、割り込み条件が発生した場合、対応する有効ビットま た は グローバル割り込み有効ビット GIEに関係なくセットされます。割り込みを有効する前には、必要に応じて、ソフトウエアでフラグビットをクリアしてください。
R/W-0 | R/W-0 | R/W-0 | R/W-0 | R/W-0 | R/W-0 | R/W-0 | R/W-x |
GIE | PEIE | TMR0IE | INT0IE | RBIE | TMR0IF | INT0IF | RBIF |
凡例:
・R = 読み取り可能ビット
・W = 書き込み可能ビット
・U = 未実装ビット(読み取り時は『0』として扱う)
・-n = POR 時の値
・1 = ビットが設定されている
・0 = ビットがクリアされている
・x = ビットの状態が不明
ビット | 名 称 | 説 明 |
7 | GIE | すべての割込み有効ビット 1 = すべての個別に無効にされていない割り込み発生を許可します 0 = 全ての割り込み発生を禁止します |
6 | PEIE | 周辺機器割り込み有効ビット 1 = すべての個別に無効にされていない周辺機器割り込み発生を許可します 0 = 周辺機器割り込み発生を禁止します |
5 | TMR0IE | タイマ0 割込み有効ビット 1 = タイマ0 割込み発生を許可します 0 = タイマ0 割込み発生を禁止します |
4 | INT0IE | RB0/INT 割込み有効ビット 1 = RB0/INT 割り込み発生を許可します 0 = RB0/INT 割り込み発生を禁止します |
3 | RBIE | RB4~RB7 割込み有効ビット 1 = RB4~RB7 ポート変化割り込み発生を許可します 0 = RB4~RB7ポート変化割り込み発生を禁止します |
2 | TMR0IF | タイマ0 割込みフラグビット 1 = タイマ0 がオーバーフローした (プログラムでクリアする必要があります ) 0 = タイマ0 がオーバーフローしていない |
1 | INT0IF | RB0/INT 割込みフラグビット 1 = RB0/INT 割り込みが発生した (プログラムでクリアする必要があります ) 0 = RB0/INT 割り込みが発生していない |
0 | RBIF | ポートB 割込みフラグビット 1 = 少なくとも 1 つ以上の RB4~RB7 ピンの状態が変化した (プログラムでクリアする必要があります ) 0 = 状態が変化した RB4~RB7 ピンはない |
PIR1 レジスタ (アドレス 0Ch)
PIR1 レジスタは、周辺機能の割り込みのフラグビットが割り当てられています。
U-0 | R/W-0 | R-0 | R-0 | R-0 | R/W-0 | R/W-0 | R/W-x |
-- | ADIF | RCIF | TXIF | SSPIF | CCP1IF | TMR2IF | TMR1IF |
凡例:
・R = 読み取り可能ビット
・W = 書き込み可能ビット
・U = 未実装ビット(読み取り時は『0』として扱う)
・-n = POR 時の値
・1 = ビットが設定されている
・0 = ビットがクリアされている
・x = ビットの状態が不明
ビット | 名 称 | 説 明 |
7 | -- | 未実装:「0」 と読まれる |
6 | ADIF | AD コンバータ割り込みフラグビット 1 = AD 変換が完了した 0 = AD 変換が完了していない |
5 | RCIF | AUSART 受信割り込みフラグビット 1 = AUSART 受信バッファが満杯です 0 = AUSART 受信バッファが空です |
4 | TXIF | AUSART 送信割り込みフラグビット 1 = AUSART 送信バッファが空です (TXREG に書き込みを行うことでクリアされます) 0 = AUSART 送信バッファが満杯です |
3 | SSPIF | 同期シリアルポート(SSP) 割り込みフラグ 1 = SSP 割り込みコンディションが発生した (割り込み処理ルーチンに戻る前にソフトウェアでクリアする必要があります ) このビットをセットする条件は以下の通り。 ・SP:I送信/受信が行われた ・I2C スレーブ:送信/受信が行われた ・I2Cマスター :送信/受信が行われた :スタート・コンディションが完了した :ストップ・コンディションが完了した :リスタート・コンディションが完了した . :アクノリッジが完了した :アイドル中にスタート・コンディションが発生した (マルチマスターシステム) :アイドル中にストップコンディションが発生した (マルチマスターシステム) 0 = SSP 割り込みコンディションが発生していない |
2 | CCP1IF | CCP1 割り込みフラグビット 「キャプチャモード」 1 = TMR1 レジスタのキャプチャが発生した (プログラムでクリアする必要があります ) 0 = TMR1 レジスタのキャプチャが発生していない 「比較モード」 1 = TMR1 レジスタの比較一致が発生した (プログラムでクリアする必要があります ) 0 = TMR1 レジスタのコ比較一致が発生していない 「PWM モード」 このモードでは使用しない |
1 | TMR2IF | TMR2 ⇔ PR2 一致割り込みフラグビット 1 = TMR2 ⇔ PR2 一致割り込みが発生した (プログラムでクリアする必要があります ) 0 = TMR2 ⇔ PR2 一致割り込みが発生していない |
0 | TMR1IF | TMR1 オーバーフロー割り込みフラグビット 1 = TMR1 レジスタがオーバーフローした ( プログラムでクリアする必要があります) 0 = TMR1 レジスタがオーバーフローしていない |
PIE1 レジスタ (アドレス 8Ch)
PIE1 レジスタは、周辺機能の割り込みの有効ビットが割り当てられています。
U-0 | R/W-0 | R/W-0 | R/W-0 | R/W-0 | R/W-0 | R/W-0 | R/W-0 |
-- | ADIE | RCIE | TXIE | SSPIE | CCP1IE | TMR2IE | TMR1IE |
凡例:
・R = 読み取り可能ビット
・W = 書き込み可能ビット
・U = 未実装ビット(読み取り時は『0』として扱う)
・-n = POR 時の値
・1 = ビットが設定されている
・0 = ビットがクリアされている
・x = ビットの状態が不明
ビット | 名 称 | 説 明 |
7 | -- | 未実装:「0」 と読まれる |
6 | ADIE | AD コンバータ割り込み有効ビット 1 = AD 変換割り込みを有効にする 0 = AD 変換割り込みを無効にする |
5 | RCIE | AUSART 受信割り込み有効ビット 1 = AUSART受信割り込みを有効にする 0 = AUSART受信割り込みを無効にする |
4 | TXIE | AUSART 送信割り込み有効ビット 1 = AUSART送信割り込みを有効にする 0 = AUSART送信割り込みを無効にする |
3 | SSPIE | 同期シリアルポート(SSP) 割り込み有効ビット 1 = SSP割り込みを有効にする 0 = SSP割り込みを無効にする |
2 | CCP1IE | CCP1 割り込み有効ビット 1 = CCP1割り込みを有効にする 0 = CCP1割り込みを無効にする |
1 | TMR2IE | TMR2 ⇔ PR2 一致割り込み有効ビット 1 = TMR2 ⇔ PR2 一致割り込みを有効にする 0 =TMR2 ⇔ PR2 一致割り込みを無効にする |
0 | TMR1IE | TMR1 オーバーフロー割り込み有効ビット 1 = TMR1 オーバーフロー割り込みを有効にする 0 = TMR1 オーバーフロー割り込みを無効にする |
PIR2 レジスタ (アドレス 0Dh)
PIR2 レジスタには、EEPROM書き込み操作割り込みのフラグビットが含まれています。
R/W-0 | R/W-0 | U-0 | R/W-0 | U-0 | U-0 | U-0 | U-0 |
OSFIF | CMIF | -- | EEIF | -- | -- | -- | -- |
凡例:
・R = 読み取り可能ビット
・W = 書き込み可能ビット
・U = 未実装ビット(読み取り時は『0』として扱う)
・-n = POR 時の値
・1 = ビットが設定されている
・0 = ビットがクリアされている
・x = ビットの状態が不明
ビット | 名 称 | 説 明 |
7 | OSFIF | システム発振器故障割り込みフラグ ビット 1 = システムオシレーターが故障し、クロック入力がINTRCに切替わった (プログラムでクリアする必要があります ) 0 = システムクロックが正常に動作している |
6 | CMIF | 比較器割り込みフラグ ビット 1 = 比較器の出力が変更されました (プログラムでクリアする必要があります ) 0 = 比較器の出力は変更されていない |
5 | -- | 未実装:「0」 と読まれる |
4 | EEIF | EEPROM 書き込み操作割り込みフラグビット 1 = 書き込み操作が完了した (TXREG に書き込みを行うことでクリアされます) 0 = 書き込み操作が完了していない。または開始されていない |
3 | -- | 未実装:「0」 と読まれる |
2 | -- | 未実装:「0」 と読まれる |
1 | -- | 未実装:「0」 と読まれる |
0 | -- | 未実装:「0」 と読まれる |
PIE2 レジスタ
PIE2レジスタは、EEPROM書き込み操作割り込みの有効ビットが割り当てられています。
R/W-0 | R/W-0 | U-0 | R/W-0 | U-0 | U-0 | U-0 | U-0 |
OSFIE | CMIE | -- | EEIE | -- | -- | -- | -- |
凡例:
・R = 読み取り可能ビット
・W = 書き込み可能ビット
・U = 未実装ビット(読み取り時は『0』として扱う)
・-n = POR 時の値
・1 = ビットが設定されている
・0 = ビットがクリアされている
・x = ビットの状態が不明
ビット | 名 称 | 説 明 |
7 | OSFIE | システム発振器故障割り込み有効ビット 1 = システム発振器故障割り込みを有効にする 0 = システム発振器故障割り込みを無効にする |
6 | CMIE | 比較器割り込み有効ビット 1 = 比較器割り込みを有効にする 0 = 比較器割り込みを無効にする |
5 | -- | 未実装:「0」 と読まれる |
4 | EEIE | EEPROM 書き込み操作割り込み有効ビット 1 = EEPROM 書き込み操作割り込みを有効にする 0 = EEPROM 書き込み操作割り込みを無効にする |
3 | -- | 未実装:「0」 と読まれる |
2 | -- | 未実装:「0」 と読まれる |
1 | -- | 未実装:「0」 と読まれる |
0 | -- | 未実装:「0」 と読まれる |
割込み処理概要
割り込みの大まかな処理は手順は次のとおりです。
- INTCONレジスタのGIEビットをBSF命令で「1」に設定し、すべての割り込みを有効にします。
- 周辺機能の割り込みを有効にする場合は、BSF命令でINTCONレジスタのPEIEビットを有効にします。
- 割込みが発生すると以後の別の割込みを禁止するため、GIEビットが「0」に設定されます。
- 現在実行している命令の次の命令のアドレスがスタックに保存されます。
- 強制的にプログラムカウンタに0004hが設定され、割込み処理プログラムの開始である4番地の命令を実行します。なお、その際、割り込み処理で変更されたくない各レジスタの内容を保存します。
- 割込みの要因を調べるため、INTCON、PIR1,PIR2レジスタの割込みフラグを調べ、フラグが「1」になっているすべての割込みの処理を順次実行し、処理を終了した後、該当する割り込みのフラグをBCF命令で「0」に設定します。
- 複数の割込みフラグが「1」になっている場合は、全ての関連割込み処理を実行します。
- すべての割込み処理が終了した後、割り込み処理前に保存した各レジスタの内容を戻し、最後にRETFIE命令を実行します。
- RETFIE命令を実行すると、スタックに保存されていた割込み時のアドレスの命令が実行され、メインの処理に戻ると共に、割込みを許可するためのGIEビットが「1」に設定されます。
通常プログラムはリセット後、0番地から実行されますので、割込みを使う場合は04番地の実行を避けるようにします。
スリープ
SLEEP 命令を実行すると、スリープ ( パワーダウン ) モードに入り、消費電力が少なくなります。
レジスタやメモリに内容は保持され、クロックは停止しますが、ウオッチドッグタイマは停止しません。
外部リセット、ウォッチドッグタイマーによるウェイクアップ、または割り込みを通じてスリープモードから復帰できます。
コンフィグレーションビット
コンフィグレーションビットは、クロックの発振方法、ウォッチドッグタイマの動作等、ハードウェア条件をプログラムを実行する前に設定します。
コンフィグレーションビットはコンフィグレーションワード1(アドレス 2007h)とコンフィグレーションワード2(アドレス 2008h)に格納されています。
ユーザープログラムのメモリ領域を超えているアドレス 2007h、2008hは、プログラミング中のみでアクセスが可能です。
コンフィグレーションワード1(アドレス 2007h)
bit | 名 称 | 説 明 | 区 分 |
13 | CP | PICライターを使ったプログラムメモリの読出し保護 1 = 読み出せる(保護しない) 【OFF】 0 = すべて読み出せない(保護する) 【ON】 | R/P-1 |
12 | CCPMX | キャプチャ/コンペア/PWM(CCP1)ピンを指定 1 = RB0(6ピン)を指定 【RB0】 0 = RB3(9ピン)を指定 【RB3】 | R/P-1 |
11 | DEBUG | インサーキットデバッガモード 1 = インサーキットデバッガモードにしない RB6 と RB7 はGPIOピン 0 = インサーキットデバッガにする RB6 と RB7 はデバッガ専用ピン | R/P-1 |
10 | WRT | プログラムメモリへの書込み保護 11 = 書込める(保護しない) 【OFF】 10 = 0000hから00FFhは書き込みできない(保護) 【256】 0100hから0FFFhはEECON制御により書込める 01 = 0000hから07FFhは書き込みできない(保護) 【2048】 0800hから0FFFhはEECON制御により書込める 00 = すべて書き込みできない(保護) 【ALL】 | R/P-1 |
9 | R/P-1 | ||
8 | CPD | データメモリ(EEPROM)の読出し保護 1 = 読み出せる(保護しない) 【OFF】 0 = 読み出せない(保護する) 【ON】 | R/P-1 |
7 | LVP | 低電圧プログラミングの有効/無効 1 = 低電圧書き込みを有効 【ON】 (自作ライタ等で高い電圧が用意できない) 0 = 低電圧書き込みを無効 【OFF】 (PICKit等を使用する場合) | R/P-1 |
6 | BOREN | ブラウンアウトリセットの有効/無効 1 = ブラウンアウトリセットを有効にする 【ON】 0 = ブラウンアウトリセットを無効にする 【OFF】 | R/P-1 |
5 | MCLRE | RA5/MCLR/VPP ピンの機能選択 1 = MCLRピンとして使用 【ON】 0 = 汎用入出力ピンとして使用 【OFF】 | R/P-1 |
3 | PWRTEN | パワーアップタイマーの有効/無効 1 = パワーアップタイマーを有効にする 【OFF】 0 = パワーアップタイマーを無効にする 【ON】 | R/P-1 |
2 | WDTEN | ウォッチドッグタイマの有効/無効 1 = ウォッチドッグタイマを有効にする 【ON】 0 = ウォッチドッグタイマを無効にする 【OFF】 | R/P-1 |
4 | FOSC2 | 発振器の選択 111 = RA7に外部RC発振回路を接続 【EXTRCCLK】 (RA6ピンはCLKOとしてクロック出力) 110 = RA7に外部RC発振回路を接続 【EXTCIOO】 (RA6ピンは汎用入出力) 101 = 内部RC発振 【INTOSCCLK】 (RA6ピンはCLKOとしてクロック出力) (RA7ピンは汎用入出力) 100 = 内部RC発振回路を利用 【INTOSCIO】 (RA6、RA7ピンは汎用入出力) 011 = RA7に外部クロック(パルス)を接続 【EC】 (RA6ピンは汎用入出力) 010 = HS 【HS】 (RA7とRA6間に4MHz~20MHzの発振子を接続) (高速水晶/セラミックリゾネータを使用) 001 = XT 【XT】 (RA7とRA6間に最大4MHzの発振子を接続) (水晶/セラミックリゾネータを使用) 000 = LP 【PP】 (RA7とRA6間に32.768 kHz(時計用)を接続) (最大100KHzまで動作可能) | R/P-1 |
1 | R/P-1 | ||
0 | R/P-1 |
凡例:
・R = 読み取り可能ビット
・W = 書き込み可能ビット
・U = 未実装ビット(読み取り時は『0』として扱う)
・-n = POR 時の値
・1 = ビットが設定されている
・0 = ビットがクリアされている
・x = ビットの状態が不明
コンフィグレーションワード2(アドレス 2008h)
bit | 名 称 | 説 明 | 区 分 |
13 | -- | 未実装ビット 「1」として読み出し | U-1 |
12 | -- | 同上 | U-1 |
11 | -- | 同上 | U-1 |
10 | -- | 同上 | U-1 |
9 | -- | 同上 | U-1 |
8 | -- | 同上 | U-1 |
7 | -- | 同上 | U-1 |
6 | -- | 同上 | U-1 |
5 | -- | 同上 | U-1 |
4 | -- | 同上 | U-1 |
3 | -- | 同上 | U-1 |
2 | -- | 同上 | U-1 |
1 | IESO | 2段階起動モード (電源立ち上げ時に、外部クロックが安定するまで、内蔵クロックを使用)の有効/無効 1 = 2段階起動モードを有効にする 【ON】 0 = 2段階起動モードを無効にする 【OFF】 | R/P-1 |
0 | FCMEN | 故障防止クロックモニターの有効/無効 (外部クロックが異常停止した場合、内部クロックに切り替える) 1 = 内部クロックに切り替える 【ON】 0 = 内部クロックに切り替えない 【OFF】 | R/P-1 |
凡例:
・R = 読み取り可能ビット
・W = 書き込み可能ビット
・U = 未実装ビット(読み取り時は『0』として扱う)
・-n = POR 時の値
・1 = ビットが設定されている
・0 = ビットがクリアされている
・x = ビットの状態が不明
アセンブラ言語(MPLAB X IDE v6.20対応)
マイコンは、0と1(2進数表記)の組み合わせで表現される「機械語」の命令で制御されます。
機械語は人間にとっては大変、扱いにくい形式であるため、「ニーモニック」という人間が分かりやすいように付けられた英数字の短い符号を使って、プログラムを作成していきます。
ニーモニックで作成したプログラムを、機械語に変換してから、マイコンに与えるこで実行することができます。
ニーモニックを使ったプログラム言語のことを「アセンブラ言語」と言い、機械語に変換することを「アセンブラ」と言います。
機械語とアセンブラ言語は異なるものですが、通常はどちらもアセンブラ言語を表わす言葉として使われているようです。
アセンブラ言語の書式
アセンブラ言語は、ラベル、オペコード、オペランドで構成されます。
ラベル | オペコード(ニーモニック) | オペランド |
【例】
LOOP: BCF MEM, 5 // MEM番地の内容のビット4を0でクリア
- ラベルは行の先頭から記述し、コロン(:)で終了します。
- ラベルがない場合は、先頭に1個以上の半角スペースかタブスペースが必要です。
- それぞれの項目は1個以上の半角スペースかタブスペースで区切ります。
- 1行は255文字以下で記述します。
名 称 | 例 | 説 明 |
ラベル | LOOP: | 英文字または、_(アンダーバー)で始まる32文字以内の半角英数字です。 |
オペコード | BCF | PIC16F84Aの命令(ニーモニック)や疑似命令を記述します。 |
オペランド | MEM, 5 | 操作するレジスタやビット、定数等を記述します。 NOP命令のようにオペランドがない命令もあります。 |
コメント | MEM番地の内容のビット4を0でクリア | 「//」に続く文字、文字列は全て注釈とされ、プログラムの実行には関係ありません。 「/* */」で囲まれた文は全て注釈とされ、プログラムの実行には関係ありません。 |
命令の実行
命令は、プログラムカウンタ(PC)が指定するプログラムメモリのアドレスから命令コードを読み込み(フェッチ)、命令コードを解読し(デコード)、命令実行の3ステップで処理されます
それぞれのステップはクロック(システムクロック)を基準に処理され、フェッチで4クロック、デコード+実行で4クロックの合計8クロックを必要とします。
4クロックを1サイクルと考えるため、ノイマン型マイコンの処理では、フェッチ、デコード、実行の処理は2サイクル必要となります。
PIC16F84Aはハーバード型のマイコンであるため、パイプライン方式を利用することで、デコード+実行と同時に、次の命令のフェッチを行うため、見かけ上、1つの命令を1サイクル(4クロック)で処理することができます。
但し、ジャンプ命令の場合はジャンプ先の命令をフェッチする必要があるので、2サイクル(8クロック)が必要となります。
プログラムカウンタ(PC)は、次に実行する命令のアドレスを格納しておく13ビットのレジスタで、上位5ビットはSFRの02h番地のPCLレジスタ、下位8ビットは0Ah番地のPCLATHレジスタで構成されています。
命令の分類
PIC16F84Aは35個の命令(ニーモニック)の他に、疑似命令と呼ばれるアセンブラを制御する命令が備わっています。
疑似命令は、PICの命令では無く、アセンブラに対する命令で、アセンブラの起動時だけに実行され、機械語には変換されません。
命令はすべて14 ビット(1ワード)で、命令のタイプを表すオペコード部と、その他の命令の動作を表す1つ以上のオペランド部からできており、オペコード部は3~6ビット、ペランド部は8~11ビットとなっています。
命令は、「バイト対応命令」、「ビット対応命令」、「リテラルおよびコントロール命令」に分類できます。
- バイト対応命令では、「f」をファイル レジスタのアドレス、「d」を結果の格納場所として使用します。
「d」が 0 の場合、結果は W レジスタに格納され、「d」が 1 の場合、結果は命令で指定されたファイルレジスタに格納されます。 - ビット対応命令では、「f」 を使ってファイル レジスタのアドレスを指定し、「b」を使って、「f」で指定したファイル レジスタの内容のビットの番号を選択、操作します。
- リテラルおよびコントロール命令では、「k」を使って8 ビットまたは 11 ビットの定数やリテラルを指定します。
▶️PIC16F88の命令(35種)の分類
分 類 | 命 令 | |
バイト対応命令 | 転送 | MOVF、MOVWF、SWAPF |
算術演算 | ADDWF、SUBWF、INCF、DECF | |
論理演算 | ANDWF、IORWF、COMF、XORWF | |
ローテイト演算 | RRF、RLF | |
条件分岐 | INCFSZ、DECFSZ | |
クリア | CLRF、CLRW | |
その他 | NOP | |
ビット対応命令 | ビット操作 | BCF、BSF |
条件分岐 | BTFSC、BTFSS | |
リテラルおよびコントロール命令 | 転送 | MOVLW |
算術演算 | ADDLW、SUBLW | |
論理演算 | ANDLW、IORLW、XORLW | |
無条件分岐 | GOTO | |
サブルーチン | CALL、RETURN、RETLW、RETFIE | |
クリア | CLRWDT | |
制御 | SLEEP |
▶️疑似命令
数多くの種類がありますが、大別すると次の6種類です。
命 令 | 説 明 |
LIST命令 | 使用するPICの種類を定義します |
INCLUDE命令 | 設定ファイルを指定します |
EQU命令 | 定数をラベル名で定義します |
END命令 | ソースコードの最後である事を指定します |
▶️命令のフォーマット
▶️命令の説明に使われている記号
命令の実行で影響を受けるSTATUSレジスタのフラグ
命令によっては、SFRの03h、83h、103h、183h番地のSTATUSレジスタのフラグを表わすビット(Z、DC、C、TO、PD)に影響を与えます。

命令セット
▶️命令の説明に使われている記号(抜粋)
記 号 | 説 明 |
f | ファイルレジスタのアドレス (00h ~ 7Fh) |
W | ワーキング レジスタ ( アキュムレータ ) |
b | 8 ビットファイルレジスタ内のビット番号(0 ~ 7) |
k | 定数データまたは(0 ~ 255) |
d | 結果格納先を指定 |
d = 0 ( 結果は W に格納 ) | |
d = 1 ( 結果はファイルレジスタ 「f」に格納 ) デフォルトは d = 1 | |
label | ラベル名 |
[ ] | オプション(省略可能) |
( ) | 内容 |
→ | 割り当て先 |
イタリック | ユーザー定義 |
▶️命令一覧
No | オペコード | オペランド | 説 明 | 影響 フラグ | サイクル数 |
バイト対応命令 | |||||
1 | MOVF | f, d | ・d=0 ファイルレジスタのf番地の内容をWレジスタに転送します ・d=1 ファイルレジスタのf番地の内容をファイルレジスタf番地に転送します (f番地の内容が0どうか確認) | Z | 1 |
2 | MOVWF | f | Wレジスタの内容をァイルレジスタのf番地 | ー | 1 |
3 | SWAPF | f, d | ・d=0 ファイルレジスタのf番地の上位4ビットとWレジスタの下位4ビットを入れ替え、結果をWレジスタに格納します ・d=1 ファイルレジスタのf番地の上位4ビットと下位4ビットを入れ替え、結果をファイルレジスタのf番地に格納します | ー | 1 |
4 | ADDWF | f, d | ・d=0 Wレジスタの内容とファイルレジスタのf番地の内容を加算し、結果をWレジスタに格納します ・d=1 Wレジスタの内容とファイルレジスタのf番地の内容を加算し、結果をファイルレジスタのf番地に格納します | Z, DC, C | 1 |
5 | SUBWF | f, d | ・d=0 ファイルレジスタのf番地の内容からWレジスタの内容を減算し、結果をWレジスタに格納します ・d=1 ファイルレジスタのf番地の内容からWレジスタの内容を減算し、結果をファイルレジスタのf番地に格納します | Z, DC, C | 1 |
6 | INCF | f, d | ・d=0 ファイルレジスタのf番地の内容に1を加算(インクレメント)し、結果をWレジスタに格納します(ファイルレジスタのf番地の内容は変化しない) ・d=1 ファイルレジスタのf番地の内容に1を加算(インクレメント)します | Z | 1 |
7 | DECF | f, d | ・d=0 ファイルレジスタのf番地の内容から1を減算(デクレメント)し、結果をWレジスタに格納します(ファイルレジスタのf番地の内容は変化しない) ・d=1 ファイルレジスタのf番地の内容から1を減算(デクレメント)する | Z | 1 |
8 | ANDWF | f, d | ・d=0 Wレジスタの内容とファイルレジスタのf番地の内容をAND演算し、結果をWレジスタに格納します ・d=1 Wレジスタの内容とファイルレジスタのf番地の内容をAND演算し、結果をファイルレジスタのf番地に格納します | Z | 1 |
9 | IORWF | f, d | ・d=0 Wレジスタの内容とファイルレジスタのf番地の内容をOR演算し、結果をWレジスタに格納します ・d=1 Wレジスタの内容とファイルレジスタのf番地の内容をOR演算し、結果をファイルレジスタのf番地に格納します | Z | 1 |
10 | COMF | f, d | ・d=0 ファイルレジスタのf番地の内容をNOT演算し、結果をWレジスタに格納します ・d=1 ファイルレジスタのf番地の内容をNOT演算します | Z | 1 |
11 | XORWF | f, d | ・d=0 Wレジスタの内容とファイルレジスタのf番地の内容をEX-OR演算し、結果をWレジスタに格納します ・d=1 Wレジスタの内容とファイルレジスタのf番地の内容をEX-OR演算し、結果をファイルレジスタのf番地に格納します | Z | 1 |
12 | RRF | f, d | ・d=0 ファイルレジスタのf番地の内容をキャリーフラグを含めて1ビット右に回転させ、結果をWレジスタに格納します ・d=1 ファイルレジスタのf番地の内容をキャリーフラグを含めて1ビット右に回転させ、結果をファイルレジスタのf番地に格納します | C | 1 |
13 | RLF | f, d | ・d=0 ファイルレジスタのf番地の内容をキャリーフラグを含めて1ビット左に回転させ、結果をWレジスタに格納します ・d=1 ファイルレジスタのf番地の内容をキャリーフラグを含めて1ビット左に回転させ、結果をファイルレジスタのf番地に格納します | C | 1 |
14 | INCFSZ | f, d | ・d=0 ファイルレジスタのf番地の内容に1を加算(インクレメント)し、結果をWレジスタに格納します 結果が0の場合は次の命令をスキップし、0以外の場合は次の命令を実行します(ファイルレジスタのf番地の内容は変化しない) ・d=1 ファイルレジスタのf番地の内容に1を加算(インクレメント)します 結果が0の場合は次の命令をスキップし、0以外の場合は次の命令を実行します 【スキップする場合は2サイクルになります】 | ー | 1(2) |
15 | DECFSZ | f, d | ・d=0 ファイルレジスタのf番地の内容から1を減算(デクレメント)し、結果をWレジスタに格納します 結果が0の場合は次の命令をスキップし、0以外の場合は次の命令を実行します(ファイルレジスタのf番地の内容は変化しない) ・d=1 ファイルレジスタのf番地の内容から1を減算(デクレメント)します 結果が0の場合は次の命令をスキップし、0以外の場合は次の命令を実行します 【スキップする場合は2サイクルになります】 | ー | 1(2) |
16 | CLRF | f | ファイルレジスタのf番地の内容をクリア(00h)にします | Z | 1 |
17 | CLRW | ー | Wレジスタのf番地の内容をクリア(00h)にします | Z | 1 |
18 | NOP | ー | 何もおこないません | ー | 1 |
ビット対応命令 | |||||
19 | BCF | f, b | ファイルレジスタのf番地のビットbをクリア(0)にします(他のビットは影響されません) | ー | 1 |
20 | BSF | f, b | ファイルレジスタのf番地のビットbをセット(1)にします(他のビットは影響されません) | ー | 1 |
21 | BTFSC | f, b | ファイルレジスタのf番地のビットbが0の場合は次の命令をスキップし、0以外の場合は次の命令を実行します 【スキップする場合は2サイクルになります】 | ー | 1(2) |
22 | BTFSS | f, b | ファイルレジスタのf番地のビットbが1の場合は次の命令をスキップし、0以外の場合は次の命令を実行します 【スキップする場合は2サイクルになります】 | ー | 1(2) |
リテラルおよびコントロール命令 | |||||
23 | MOVLW | k | 8ビットの定数kをWレジスタに転送します | ー | 1 |
24 | ADDLW | k | Wレジスタの内容と8ビットの定数kを加算し、結果をWレジスタに格納します | Z, DC, C | 1 |
25 | SUBLW | k | 8ビットの定数kからWレジスタの内容を減算し、結果をWレジスタに格納します | Z, DC, C | 1 |
26 | ANDLW | k | Wレジスタの内容と8ビットの定数kとをAND演算し、結果をWレジスタに格納します | Z | 1 |
27 | IORLW | k | Wレジスタの内容と8ビットの定数kとをOR演算し、結果をWレジスタに格納します | Z | 1 |
28 | XORLW | k | Wレジスタの内容と8ビットの定数kとをEX-OR演算し、結果をWレジスタに格納します | Z | 1 |
29 | CALL | label | 命令が実行されると復帰するアドレスをスタックに格納します label(または11ビット幅にアドレス)で指定されるプログラムメモリのアドレスにあるサブルーチンをじっこうします 実行後、RETURN、RETLW命令で元のルーチンに復帰します | ー | 2 |
30 | GOTO | label | label(または11ビット幅にアドレス)で指定されるプログラムメモリのアドレスに無条件に分岐します | ー | 2 |
31 | RETURN | ー | サブルーチンより復帰します | ー | 2 |
32 | RETLW | k | 8ビットの定数kをWレジスタに転送し、サブルーチンより復帰します | ー | 2 |
33 | RETFIE | ー | 割込み処理から復帰しまう | ー | 2 |
34 | CLRWDT | ー | ウオッチドッグタイマ(WDT)の初期化を行います | TO, PD | 1 |
35 | SLEEP | ー | 低電力でのスリープ(待機)モードになります。外部からのリセット、割込み、ウオッチドッグタイマ(WDT)のタイムアウトにより復帰します | TO, PD | 1 |