【プリプロセッサ擬似命令】(Preprocessor Directives)
プリプロセッサ擬似命令は、コンパイラに対してコンパイルの仕方などの条件
設定をするための擬似命令で、#で始まる命令群で直接実行される機械語への
翻訳はされません。
プリプロセッサの種類には下記のようなものがあります。
【データ定義】
(1) #define
文字列に対して定数を定義します。
《例》
#define MAX_COUNT 100
#define VERSION "v1.0"
#define PERIMETER( x, y ) 2*x + 2*y
(これは式 2*x+2*y をPERIMETER(x,y)という文字列で定義するという意味)
(2) #undef
定義された文字定数を削除する。以後その文字列は未定義となる。
《例》
#undef MAX_COUNT
【条件コンパイル指定】
#if #ifdef #ifndef
#else #elif
#endif
#defined()
コンパイラに対して環境条件によりコンパイルする内容を変更させることが
出来ます。
#if、#ifdef #ifndef で始まり必ず最期に#endifが必要です。
#ifdef、#ifndefは指定された文字列が定義されていれば、あるいはいなければ
という条件を指定したことになります。
defined()という擬似関数が#ifと一緒に使われると、#ifdef と同じ意味になり
ます。
《例》
#define MAC_COUNT 100
#define ELEMNT_SIZE 3
#if defined(MAX_COUNT) && defined(ELEMNT_SIZE)
#if (MAX_COUNT * ELEMENT_SIZE) > 256
#error "Data size too large."
#else
#define DATA_SIZE MAX_COUNT * ELEMENT_SIZE
#endif
#endif
《例》
#ifndef DEBUG
#define Debug(x)
#else
#define Debug(x) x
#endif
【結合指定】
#include
他のソースファイルを一括取り込み連結する機能を持つ
下記3種類のファイル指定方法があり、探索ディレクトリの順番が異なる。
《例》
#include "header.h"
まず現在ディレクトリ内をサーチし次にinclude directoryを探す。
#include <pic18cxx.h>
include directoryとして指定された中を探す。
#include d:\mcc18\h\pic18c458.h
指定したdirectoryから結合する。
ここでinclude directoryとは、MPLAB-C18の環境として指定された
ディレクトリである。
【エラー制御】
#error
この定義分を実行するところまできたら、ここで定義されているエラー文を
出力します。
《例》
#define MAC_COUNT 100
#define ELEMNT_SIZE 3
#if (MAX_COUNT * ELEMENT_SIZE) > 256
#error "Data size too large."
#endif
【行番号制御】
#line
この行を指定した行番号として以下連続番号とする。
《例》
#line 34 //この行を34行目とする。
#line 55 "main.c" //この行をmain関数の55行目とする
【割込み関数の定義】
#pragma interrupt fname
#pragma interruptlow fname
割込み関数の定義をする擬似命令で、interruptは高位割込み処理関数
であることを定義し、interruptlowは低位割込み処理関数であることを示し
ます。
高位割込み処理では、レジスタの退避/復旧にshadow registerを自動的
に選択し、WREG、BSR、STATUSの各レジスタは自動的に行われます。
また、さらに追加レジスタを退避したいときには、save= で指定すれば追加
されます。
自動的にshadow registerを使うので、この割込み処理関数の最後は、Fast
RETFIEとする必要があります。正確な書式は下記となります。
ここでsectionnameはリロケータブルな配置とする場合に、code部とするか
data部とするかをsectionnameとして指定します。
このsectionnameの中で絶対アドレスを指定することも出来ます。
#pragma interrupt functionname [sectionname]
save = symmbollist
これに対し、interruptlowの方は、レジスタの退避は自動的には実行されないので、
必ずsave=で退避する必要があります。また最後は通常のRETFIEで戻るように
すれば大丈夫です。正確な書式は下記となります。
#pragma interruptlow functionname [sectionname]
save = symbollist
いずれの場合にも、MPLAB-C18では割り込みベクタへの自動配置はしてくれ
ませんので、割り込みベクタの番地には、このそれぞれの割込み処理への
ジャンプ命令を追加する必要があります。実際の例は下記のようになります。
《例》
void myInterrupt(void)
#pragma code lowVector=0x18
void atLowVector(void)
{ _asm
GOTO myInterrupt
_endasm
}
#pragma code //return to default code section
#pragma interruptlow myInterrupt save=FSR0,PROD
void myInterrupt(void)
{
*globalCharPointer += PORTB;
}
【リスト出力の許可/禁止】
#pragma list
#pragma nolist
コンパイル結果のリストを表示するしないを設定します。
【メモリ配置設定】
#pragma sectiontype
リロケータブルなコンパイルにする場合の配置指定をする。
sectiontypeとしては下記のようなものがあります。
#pragma udata [qualifier] [sectionname] [location]
#pragma idata [qualifier] [sectionname] [location]
#pragma romdata {overlay} [sectionname]
#pragma code {overlay} [sectionname]
ここでqualifierは下記の3通り
access (アクセスバンクに配置)
overlay (???)
またlocationは下記のみ
= address (絶対アドレスに配置)
【変数のメモリ配置指定】
#pragma varlocate n name
nameという変数をバンクnに配置するよう指定する。
《例》
#pragma varlocate bankNo name