__delay_ms();系のコマンドを書くと以下のように赤線が引かれて
Unable to resolve identifier __delay_ms
と怒られる。
怒られるがコンパイルは問題なく終了する。
だから別に構わねえじゃんってことで放置してきたが、ちょっと調べてみた。
環境は以下の通り。
MPLAB X IDE v2.15
XC8 v1.32
例として扱っているPICはPIC16F1827(instruction cycle の関係があるので一応)
ずっと以前からそのままなので、Microchip的には問題なしと思ってるか無視してるかってことだと思うが、そもそも__delay_ms();はコンパイラではどんな扱いなのかということで、まずは検索してみた。
pic.hとpic18.hの中に記述がある。
そうか、これをインクルードしないからエラーなんだなと思ってインクルードしてみたがエラーは出っ放しだった。
そこで、pic.hを眺めてみると、該当する部分はこんな感じだ。
初心者の私に意味が分かるはずも無いが、
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
というのは
__delay_ms(x) を _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0))) に置き換えるんだということは今までの経験からわかる。
つうことは、結局_delay()っていうコマンドに書き換えられてんのね。
これについてXC8のHelpから必要そうな部分だけをかいつまむと
void _delay(unsigned long cycles);
delays for the number of instruction cycles
an instruction cycle takes 4 clock cycles
と書いてあって、指定した回数のインストラクション・サイクル分Delayするってことのようだ。
PIC16F1827ではクロックの4サイクル分が1インストラクション・サイクルとなる。
clockが8MHzでinstruction cycleが4 clock cyclesの場合、1 clockは1/8000000 secなので1 instruction cycleは(1/8000000)x4 sec、つまり(1/_XTAL_FREQ)x4 secとなる。
よって(1/_XTAL_FREQ)x4x1000 msecということだ。
それで、これを逆数にした _XTAL_FREQ/4000.0 という計算式が#defineに登場するわけだ。
ところでpic.hに書いてある#ifdefを調べると、
__PICCPRO__というマクロが定義されていたら、#ifdefと#endifの間の行が有効になる。
ということのようだ。
__PICCPRO__についてはよく分からないが、何らかの条件があってこの#defineが有効にならないためにエラーが表示されると考えられる。
え、じゃあ自分で定義しちゃえばいいんでないの?
と思ってこの1行をプログラムに直接追加したら、
エラーの赤線はきれいさっぱり出なくなった。
__PICCPRO__を__PICC__に書き換えればいいという記述も見つけたが、うちの環境では書き換えてもエラーは無くならなかった。
そもそも#ifdef __PICCPRO__をちゃんと理解してない、というか__PICCPRO__の意味するところが不明だからすっきりした解決には至らない。
そのうち気が向いたら調べるかも。