TOPMPLAB C18編>プログラムの基本形

プログラムの基本形(MPLAB C18)

更新日2009.3.7

C18を使うプログラムの基本形を以下の3パターンについて説明します。

1. 割込みを使わない場合
2. PIC16互換の割込みを使う場合(優先割込みを使わない)
3. 優先割込みを使う場合(PIC18の新機能)

プログラムの入り口について(プログラムメモリの構成)

はじめにプログラムメモリの構成についてです。
割込みの使い方によって以下の3パターンがあります。

割込みを使わない場合PIC16互換割込みを使う場合優先割込みを使う場合






リセットベクタは、C言語を使う場合意識する事はありません。
通常は、「main」と言う名前(の関数)がC言語での入り口になり、C18でも同じです。

割込みを使う場合は、割込みの種類とアドレスの意識が必要になります。

PIC18の割込みについては、優先/非優先割込みを使うも参考にして下さい。

割込みを使わないプログラム

最初は、割込みを使わないプログラムの基本形です。
以下のように非常に簡単です。

#include <p18f1320.h>

#pragma config OSC = HS
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config WDT = OFF
#pragma config LVP = OFF

void main (void) {
  /* ここにメイン処理を記述する */
}

1行目のヘッダファイルは、使用する機種に合わせて指定します。

configレジスタの設定は例であり、必要に応じて変更します。

void main (void)はこの通りに記述します。
割込みの有無とは関係なく必ず「main」は必要で、リセット時の入り口になります。

上の雛形は、メインルーチンのみ記述していますが、サブルーチン(関数)を自由に作成できます。

割込みに関するレジスタは、リセット時に割込みを使わない設定になっていますので、プログラムでは特に設定する必要がありません。

PIC16互換の割込みを使うプログラム

続いて、PIC16互換の割込みを使う場合です。

PIC18ファミリでは、2レベル(優先・非優先)の割込みがサポートされましたが、この機能を使わずにPIC16ファミリと同じ1レベルの割込みとする場合です。

上の割込みを使わない場合との違いは、0x8番地を割込みベクタとして定義し、割込み処理を記述する点です。

#include <p18f1320.h>

#pragma config OSC = HS
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config WDT = OFF
#pragma config LVP = OFF

void isr (void);

#pragma code compatible_vector=0x8
void compatible_interrupt (void) {
	_asm
		GOTO isr
	_endasm
}
#pragma code

#pragma interruptlow isr
void isr (void) {
  /* ここに割込み処理を記述する */
}

void main (void) {
  /* ここにメイン処理を記述する */
}

イタリック体の記述部分は任意の名前に変えられます。
「isr」が4箇所にありますが、割り込みルーチンに付ける名前であり、任意に指定できます。

割込みに関するレジスタは必要に応じて設定します。考え方はPIC16と同様です。
例えば、TIMER0割込みを使う場合は、「INTCON」「T0CON」などを設定します。


優先割込みを使うプログラム

次は、優先割込み機能を使う場合です。

下のように、高優先割込みに関する記述と低優先割込みに関する記述が必要です。
この2つを良く見ると、同じ形式になっている事が分かると思います。
どちらも、割込みベクタの定義と割込み処理の定義から成っています。

#include <p18f1320.h>

#pragma config OSC = HS
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config WDT = OFF
#pragma config LVP = OFF

void high_isr (void);
void low_isr (void);

// ==(1)== ここから高優先割込み関連の記述 ====
#pragma code high_vector=0x8
void high_interrupt (void) {
	_asm
		GOTO high_isr
	_endasm
}
#pragma code

#pragma interrupt high_isr
void high_isr (void) {
  /* ここに高優先割込み処理を記述する */
}

// ==(2)== ここから低優先割込み関連の記述 ====
#pragma code low_vector=0x18
void low_interrupt (void) {
	_asm
		GOTO low_isr
	_endasm
}

#pragma code

#pragma interruptlow low_isr
void low_isr (void) {
  /* ここに低優先割込み処理を記述する */
}

// ==(3)== ここからメイン処理の記述 ====
void main (void) {
	RCONbits.IPEN = 1;	// 優先割込み機能を使う
  /* ここにメイン処理を記述する */
}

イタリック体の記述部分は任意の名前に変えられます。
ただし、同じ記述のものはそろえて変えて下さい。

赤字は、高優先・低優先割込みの設定に関するものです。

優先割込み機能を有効にするためには、RCONレジスタのIPENビットに1をセットします。上の例では、メイン処理の最初にセットしています。
それ以外のレジスタは、使う割り込みの種類によって設定します。