プロセッサ ヘッダファイル (Processor header file)

各プロセッサには、そのプロセッサのSFR名やマクロを定義したヘッダファイルが用意されています。このファイルは、

#include <p30fxx.h>   // xxは、プロセッサのデバイス番号

のように読み込め、既定では/Microchip/MPLAB C30/support/dsPIC30F/h/にあります。

SFR (Special Function Register) の定義

プロセッサ ヘッダファイル内では次のような定義がなされており、SFR名を変数名のようにしてレジスタにアクセスできるようになっています。

/* CORCON: CPU Mode control Register */
extern volatile unsigned int CORCON __attribute__((__sfr__));

typedef struct tagCORCONBITS {
        unsigned IF     :1;     /* Integer/Fractional mode              */
        unsigned RND    :1;     /* Rounding mode                        */
        unsigned PSV    :1;     /* Program Space Visibility enable      */
        unsigned IPL3   :1;     /* CPU Interrupt Priority Level bit 3   */
        unsigned ACCSAT :1;     /* Acc saturation mode                  */
        unsigned SATDW  :1;     /* Data space write saturation enable   */
        unsigned SATB   :1;     /* Acc B saturation enable              */
        unsigned SATA   :1;     /* Acc A saturation enable              */
        unsigned DL     :3;     /* DO loop nesting level status         */
        unsigned EDT    :1;     /* Early DO loop termination control    */
        unsigned US     :1;     /* Signed/Unsigned mode                 */
        unsigned        :3;
} CORCONBITS;

extern volatile CORCONBITS CORCONbits __attribute__((__sfr__));
__attribute__((__sfr__))は、変数がSFRであることを宣言するMPLAB Cコンパイラのキーワード

レジスタの各ビットにアクセスするには、

CORCONbits.IF

のように記述します。または、

/* CORCON */
#define _IF     CORCONbits.IF
#define _RND    CORCONbits.RND
#define _PSV    CORCONbits.PSV
#define _IPL3   CORCONbits.IPL3
#define _ACCSAT CORCONbits.ACCSAT
#define _SATDW  CORCONbits.SATDW
#define _SATB   CORCONbits.SATB
#define _SATA   CORCONbits.SATA
#define _DL     CORCONbits.DL
#define _EDT    CORCONbits.EDT
#define _US     CORCONbits.US

のようなマクロが定義されているので、「_IF」とも記述できます。

SFRアドレスの定義

プロセッサ ヘッダファイルではSFRの名前が定義されているだけであり、SFRのアドレスは/Microchip/MPLAB C30/support/dsPIC30F/gld/にあるレジスタ定義ファイルで定義されています。

マクロ (Macro)

プロセッサ ヘッダファイルには、上記のSFRに加え次のマクロが定義されています。

コンフィギュレーションビット設定マクロ

コンフィギュレーションの設定を行います。このマクロは、

extern __attribute__((space(prog))) int _FOSC;
#define _FOSC(x) __attribute__((section("__FOSC.sec"),space(prog))) int _FOSC = (x);

のようなもので、

_FOSC( OPT1_ON & OPT2_OFF & OPT3_PLL );

のように使用します。

インラインアセンブリ使用マクロ

C言語内でアセンブリコードを定義するマクロで、次の4つがあります。

#define Nop()    __builtin_nop()
#define ClrWdt() {__asm__ volatile ("clrwdt");}
#define Sleep()  {__asm__ volatile ("pwrsav #0");}
#define Idle()   {__asm__ volatile ("pwrsav #1");}

この内、下の3つは関数の呼び出しではなく、直接アセンブリコードに展開されます。

データメモリ割り当てマクロ

データメモリ内に空間を割り当てるマクロです。

#define _XBSS(N)    __attribute__((space(xmemory),aligned(N)))
#define _XDATA(N)   __attribute__((space(xmemory),aligned(N)))
#define _YBSS(N)    __attribute__((space(ymemory),aligned(N)))
#define _YDATA(N)   __attribute__((space(ymemory),aligned(N)))
#define _EEDATA(N)  __attribute__((space(eedata),aligned(N)))

32バイトアドレスに整列されるXメモリ内の初期化されていない配列を宣言するには、

int _XBSS(32) xbuf[16];

とします。presistentデータメモリ、またはnearメータメモリ内に変数を配置するには、

#define _PERSISTENT __attribute__((persistent))
#define _NEAR       __attribute__((near))

の2つのマクロがあります。

ISR宣言マクロ

ISR (割り込みサービスルーチン) を宣言するマクロです。

#define _ISR __attribute__((interrupt))
#define _ISRFAST __attribute__((interrupt, shadow))

CPU割り込み優先順位設定マクロ

CPU割り込み優先順位を設定するマクロです。

#define SET_CPU_IPL(ipl) {       \
  int DISI_save;                 \
                                 \
  DISI_save = DISICNT;           \
  asm volatile ("disi #0x3FFF"); \
  SRbits.IPL = ipl;              \
  DISICNT = DISI_save; } (void) 0;

#define SET_AND_SAVE_CPU_IPL(save_to, ipl) { \
  save_to = SRbits.IPL; \
  SET_CPU_IPL(ipl); } (void) 0;

#define RESTORE_CPU_IPL(saved_to) SET_CPU_IPL(saved_to)

参考

  • MPLAB C Compiler for PIC24 MCUs and dsPIC DSCs User's Guide (DS51284K)
    Chapter 7. Device Support Files
  • MPLAB C30 C コンパイラ ユーザーズガイド (DS51284E_JP)
    6章「デバイスサポートファイル」