目次

PIC18

 PIC18と、PIC12/16とは、構成が違っているようで、コンパイラも別であった。HITECH-Cなら、for C18を新たにダウンロードする。また、PICkit3もファームウェアダウンロードが必要(これはIDEが自動でやる)。PIC18を使ったりPIC16を使ったりすると、毎回ダウンロードが発生する。そんなに時間がかからないから別に良いんだけど。

コンフィグbit

Configuration bitsの設定は、IDEの中で可能だが、プログラムの中に記述する事も出来る。PIC12F675などは __CONFIG( の一文ですんでいたのだが、PIC18Fでは、一つ一つ設定が必要らしい。

#pragma config OSC = INTIO2		//内蔵オシレータ RA6,RA7=I/Oポートとして使用
#pragma config FSCM = OFF		//Fail-Safe Clock Monitor
#pragma config IESO = OFF		//内部、外部の切り替え無し
#pragma config PWRT = ON		//パワーアップタイマーON
#pragma config BOR = ON			//ブラウンアウトON
#pragma config BORV = 42		//ブラウンアウト電圧4.5V
#pragma config WDT = OFF		//ウォッチドッグOFF
#pragma config WDTPS = 32768	//ウォッチドッグポストスケーラ(:32768)
#pragma config MCLRE = ON		//マスタークリアON
#pragma config STVR = OFF		//Stack Full&Overflow Reset=OFF
#pragma config LVP = OFF		//低電圧書込OFF
#pragma config DEBUG = ON		//BackgroundデバッガON
#pragma config CP0 = OFF		//Code Protection bit Block 0
#pragma config CP1 = OFF		//Code Protection bit Block 1
#pragma config CPB = OFF		//Boot Block Code Protection Bit
#pragma config CPD = OFF		//Data EEPROM Code Protectio Bit
#pragma config WRT0 = OFF		//Write Protection bit Block 0
#pragma config WRT1 = OFF		//Write Protection bit Block 1
#pragma config WRTB = OFF		//Boot Block Write Protection
#pragma config WRTC = OFF		//Configuration Register Write Protection
#pragma config WRTD = OFF		//Data EEPROM Write Protection
#pragma config EBTR0 = OFF		//Table Read Protection Block 0
#pragma config EBTR1 = OFF		//Table Read Protection Block 1
#pragma config EBTRB = OFF		//Boot Block Table Read Protection

INTIO2のような定数は、どこにも定義が無いのだが、IDEの中のヘルプに書かれており認識するようである。それぞれの持つ意味は、PICのデータシートから紐解くしか無い。いまいちよくわかっとらん。

Delay

サンプルで用意されていたDelay関数が無くなっちゃった。あるのか知れんけど。よくわからんから重宝してたのですが、で、includeフォルダをみたら、delays.hと言うのがあった。わたしも、あんまりよくわかってないので、行き当たりばったりでよくないんですが。

/* C18 cycle-count delay routines. */
/* Passing 0 (zero) results in a delay of 2560 cycles. */
void Delay10TCYx(unsigned char);
 
/*  Passing 0 (zero) results in a delay of 25,600 cycles.*/
void Delay100TCYx(unsigned char);
 
/* Delay1KTCYx
 * Passing 0 (zero) results in a delay of 256,000 cycles. */
void Delay1KTCYx(unsigned char);
 
/*  Passing 0 (zero) results in a delay of 2,560,000 cycles. */
void Delay10KTCYx(unsigned char);

で、なんがしか時間待ちするようであるので、オシロの波形で確認したところ、PIC18F1320で8MHz内蔵タイマで下表の結果だった。

Function Results 期待値
Delay1KTCYx(1) 510us 500us
Delay10KTCYx(1) 5.1ms 5ms
Delay100TCYx(1) 66us 50us
Delay100TCYx(10) 550us 500us
Delay100TCYx(100) 5.2ms 5ms
Delay10TCYx(1) 19.2us 5us
Delay10TCYx(10) 79us 50us
Delay10TCYx(20) 146us 100us
Delay10TCYx(100) 670us 500us

 計測にPort出力のH/Lと、反転するのにif文を使っているので、その処理分追加されているので、よくわからない(条件分岐せずにポートの出力をすると670nsぐらい)けど、小さい時間は誤差が大きいようだ。内蔵タイマを4MHz設定にすると、時間は半分だった。
 以上から、1TCYx=510ns(@8MHz)と思われる。8MHzは周期125nsから、TCY=4/Fosc というのがデータシートに書かれていたので、本来1TCYx=500nsとなるのかな。
 なので、引数がcharなので

/* 1ms - 1275ms */
void DelayMs(int t){
    if(t<128){
      Delay1KTCYx(t*2);
    } else if(t<1275){
      Delay10KTCYx(t/5);
    } else {
      Delay10KTCYx(255);
    }
}

これで、いいでしょうか。

定義済定数

参考書とかでは、ポートの出力、例えばポートAのビット0は、RA0=1 などの記述で1出力できたのだが、PIC18Fでは大量のWarningが出る。そのままでも動作に問題は無いのだが、気持ち悪い。RA0の記述が非推奨のようである。

ヘッダファイルを見ると、PORTAbits.RA0と記載するのかな。でも長いなぁ

extern volatile union {
    struct {
        unsigned RB0                    :1;
        unsigned RB1                    :1;
        unsigned RB2                    :1;
        unsigned RB3                    :1;
        unsigned RB4                    :1;
        unsigned RB5                    :1;
        unsigned RB6                    :1;
        unsigned RB7                    :1;
    };
    struct {
        unsigned RB                     :8;
} PORTBbits @ 0xF81;

 よくわからないんだけど、共用体の中に、構造体があるから、PORTBbits.RB0とPORTBbits.RBは同じメモリになるけど、PORTBbits.RB0とPORTBbits.RB1は異なるメモリにあり独立しているという意味だと思うんだけど、bitが他のbitに影響を与えるようだ。

ADCONの設定をしていないせいでした。とほほ。一部のポートはADCONがデフォルトになっていると言う事もある。